/*
- Copyright (C) 2014-2015 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2014-2021 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
*/
-#include <boost/asio.hpp>
-#include <boost/bind.hpp>
-#include <boost/thread.hpp>
-#include "json_server.h"
-#include "job_manager.h"
-#include "job.h"
-#include "util.h"
+
#include "film.h"
+#include "job.h"
+#include "job_manager.h"
+#include "json_server.h"
#include "transcode_job.h"
+#include <dcp/raw_convert.h>
+#include <boost/asio.hpp>
+#include <boost/bind/bind.hpp>
+#include <boost/thread.hpp>
#include <iostream>
-using std::string;
+
using std::cout;
-using std::map;
+using std::dynamic_pointer_cast;
using std::list;
-using boost::thread;
-using boost::shared_ptr;
-using boost::dynamic_pointer_cast;
+using std::make_shared;
+using std::map;
+using std::shared_ptr;
+using std::string;
using boost::asio::ip::tcp;
+using boost::thread;
+using dcp::raw_convert;
+
#define MAX_LENGTH 512
+
enum State {
AWAITING_G,
AWAITING_E,
READING_URL,
};
+
JSONServer::JSONServer (int port)
{
+#ifdef DCPOMATIC_LINUX
+ auto t = new thread (boost::bind (&JSONServer::run, this, port));
+ pthread_setname_np (t->native_handle(), "json-server");
+#else
new thread (boost::bind (&JSONServer::run, this, port));
+#endif
}
+
void
JSONServer::run (int port)
try
tcp::acceptor a (io_service, tcp::endpoint (tcp::v4 (), port));
while (true) {
try {
- shared_ptr<tcp::socket> s (new tcp::socket (io_service));
+ auto s = make_shared<tcp::socket>(io_service);
a.accept (*s);
handle (s);
}
}
+
void
JSONServer::handle (shared_ptr<tcp::socket> socket)
{
break;
}
- char* p = data;
- char* e = data + len;
+ auto p = data;
+ auto e = data + len;
while (p != e) {
- State old_state = state;
+ auto old_state = state;
switch (state) {
case AWAITING_G:
if (*p == 'G') {
}
}
+
+map<string, string>
+split_get_request(string url)
+{
+ enum {
+ AWAITING_QUESTION_MARK,
+ KEY,
+ VALUE
+ } state = AWAITING_QUESTION_MARK;
+
+ map<string, string> r;
+ string k;
+ string v;
+ for (size_t i = 0; i < url.length(); ++i) {
+ switch (state) {
+ case AWAITING_QUESTION_MARK:
+ if (url[i] == '?') {
+ state = KEY;
+ }
+ break;
+ case KEY:
+ if (url[i] == '=') {
+ v.clear();
+ state = VALUE;
+ } else {
+ k += url[i];
+ }
+ break;
+ case VALUE:
+ if (url[i] == '&') {
+ r.insert(make_pair(k, v));
+ k.clear ();
+ state = KEY;
+ } else {
+ v += url[i];
+ }
+ break;
+ }
+ }
+
+ if (state == VALUE) {
+ r.insert (make_pair (k, v));
+ }
+
+ return r;
+}
+
+
void
JSONServer::request (string url, shared_ptr<tcp::socket> socket)
{
cout << "request: " << url << "\n";
- map<string, string> r = split_get_request (url);
- for (map<string, string>::iterator i = r.begin(); i != r.end(); ++i) {
- cout << i->first << " => " << i->second << "\n";
+ auto r = split_get_request (url);
+ for (auto const& i: r) {
+ cout << i.first << " => " << i.second << "\n";
}
string action;
action = r["action"];
}
- SafeStringStream json;
+ string json;
if (action == "status") {
- list<shared_ptr<Job> > jobs = JobManager::instance()->get ();
-
- json << "{ \"jobs\": [";
- for (list<shared_ptr<Job> >::iterator i = jobs.begin(); i != jobs.end(); ++i) {
+ auto jobs = JobManager::instance()->get();
- json << "{ ";
+ json += "{ \"jobs\": [";
+ for (auto i = jobs.cbegin(); i != jobs.cend(); ++i) {
+ json += "{ ";
if ((*i)->film()) {
- json << "\"dcp\": \"" << (*i)->film()->dcp_name() << "\", ";
+ json += "\"dcp\": \"" + (*i)->film()->dcp_name() + "\", ";
}
- json << "\"name\": \"" << (*i)->json_name() << "\", ";
- if ((*i)->progress ()) {
- json << "\"progress\": " << (*i)->progress().get() << ", ";
+ json += "\"name\": \"" + (*i)->json_name() + "\", ";
+ if ((*i)->progress()) {
+ json += "\"progress\": " + raw_convert<string>((*i)->progress().get()) + ", ";
} else {
- json << "\"progress\": unknown, ";
+ json += "\"progress\": unknown, ";
}
- json << "\"status\": \"" << (*i)->json_status() << "\"";
- json << " }";
+ json += "\"status\": \"" + (*i)->json_status() + "\"";
+ json += " }";
- list<shared_ptr<Job> >::iterator j = i;
+ auto j = i;
++j;
if (j != jobs.end ()) {
- json << ", ";
+ json += ", ";
}
}
- json << "] }";
-
- if (json.str().empty ()) {
- json << "{ }";
- }
+ json += "] }";
}
- SafeStringStream reply;
- reply << "HTTP/1.1 200 OK\r\n"
- << "Content-Length: " << json.str().length() << "\r\n"
- << "Content-Type: application/json\r\n"
- << "\r\n"
- << json.str () << "\r\n";
- cout << "reply: " << json.str() << "\n";
- boost::asio::write (*socket, boost::asio::buffer (reply.str().c_str(), reply.str().length()));
+ string reply = "HTTP/1.1 200 OK\r\n"
+ "Content-Length: " + raw_convert<string>(json.length()) + "\r\n"
+ "Content-Type: application/json\r\n"
+ "\r\n"
+ + json + "\r\n";
+ cout << "reply: " << json << "\n";
+ boost::asio::write (*socket, boost::asio::buffer(reply.c_str(), reply.length()));
}