diff options
| author | Carl Hetherington <cth@carlh.net> | 2015-03-25 00:15:23 +0000 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2015-03-25 00:15:23 +0000 |
| commit | 5f6d9c16df8e0b49160353354dccbcbdd1e57e9d (patch) | |
| tree | bbaee2cd516651d8e0bbf590780be6df64aae7d5 /src/lib/json_server.cc | |
| parent | eba0d9ca54fcfd269e61ab7b47d2e741735f6f3e (diff) | |
Missing files.
Diffstat (limited to 'src/lib/json_server.cc')
| -rw-r--r-- | src/lib/json_server.cc | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/src/lib/json_server.cc b/src/lib/json_server.cc new file mode 100644 index 000000000..1035c248f --- /dev/null +++ b/src/lib/json_server.cc @@ -0,0 +1,197 @@ +/* + Copyright (C) 2014-2015 Carl Hetherington <cth@carlh.net> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#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 "transcode_job.h" + +using std::string; +using std::stringstream; +using std::cout; +using std::map; +using std::list; +using boost::thread; +using boost::shared_ptr; +using boost::dynamic_pointer_cast; +using boost::asio::ip::tcp; + +#define MAX_LENGTH 512 + +enum State { + AWAITING_G, + AWAITING_E, + AWAITING_T, + AWAITING_SPACE, + READING_URL, +}; + +JSONServer::JSONServer (int port) +{ + new thread (boost::bind (&JSONServer::run, this, port)); +} + +void +JSONServer::run (int port) +try +{ + boost::asio::io_service io_service; + tcp::acceptor a (io_service, tcp::endpoint (tcp::v4 (), port)); + while (true) { + try { + shared_ptr<tcp::socket> s (new tcp::socket (io_service)); + a.accept (*s); + handle (s); + } + catch (...) { + + } + } +} +catch (...) +{ + +} + +void +JSONServer::handle (shared_ptr<tcp::socket> socket) +{ + string url; + State state = AWAITING_G; + + while (true) { + char data[MAX_LENGTH]; + boost::system::error_code error; + size_t len = socket->read_some (boost::asio::buffer (data), error); + if (error) { + cout << "error.\n"; + break; + } + + char* p = data; + char* e = data + len; + while (p != e) { + + State old_state = state; + switch (state) { + case AWAITING_G: + if (*p == 'G') { + state = AWAITING_E; + } + break; + case AWAITING_E: + if (*p == 'E') { + state = AWAITING_T; + } + break; + case AWAITING_T: + if (*p == 'T') { + state = AWAITING_SPACE; + } + break; + case AWAITING_SPACE: + if (*p == ' ') { + state = READING_URL; + } + break; + case READING_URL: + if (*p == ' ') { + request (url, socket); + state = AWAITING_G; + url = ""; + } else { + url += *p; + } + break; + } + + if (state == old_state && state != READING_URL) { + state = AWAITING_G; + } + + ++p; + } + } +} + +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"; + } + + string action; + if (r.find ("action") != r.end ()) { + action = r["action"]; + } + + stringstream 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) { + + json << "{ "; + + if ((*i)->film()) { + json << "\"dcp\": \"" << (*i)->film()->dcp_name() << "\", "; + } + + json << "\"name\": \"" << (*i)->json_name() << "\", "; + if ((*i)->progress ()) { + json << "\"progress\": " << (*i)->progress().get() << ", "; + } else { + json << "\"progress\": unknown, "; + } + json << "\"status\": \"" << (*i)->json_status() << "\""; + json << " }"; + + list<shared_ptr<Job> >::iterator j = i; + ++j; + if (j != jobs.end ()) { + json << ", "; + } + } + json << "] }"; + + if (json.str().empty ()) { + json << "{ }"; + } + } + + stringstream 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())); +} |
