#include "rotord.h" using namespace Rotor; RenderContextHandler::RenderContextHandler(const std::string _content,const HTTPServerResponse::HTTPStatus _status){ content=_content; status=_status; } void RenderContextHandler::handleRequest(HTTPServerRequest& request,HTTPServerResponse& response) { response.setChunkedTransferEncoding(true); response.setContentType("text/html"); response.setStatus(status); std::ostream& ostr = response.send(); ostr << "\n"; //this is the mysterious extra header ostr << content; } HTTPRequestHandler* RotorRequestHandlerFactory::createRequestHandler(const HTTPServerRequest& request){ Poco::URI theuri=Poco::URI(request.getURI()); std::vector command; theuri.getPathSegments(command); Logger& logger = Logger::get("Rotor"); logger.information(request.clientAddress().toString()+" "+request.getMethod()); HTTPResponse::HTTPStatus status=HTTPResponse::HTTP_BAD_REQUEST; //by default std::string body; std::ostringstream os; os<name()==sID) { logger.error("ERROR: tried to create thread with existing name "+sID); XML.addValue("error","Render context /"+sID+"/ exists already"); found=true; } } if (!found){ logger.information("starting thread "+sID); manager.start(new Rotor::Render_context(sID)); XML.addValue("sID",sID); status=HTTPResponse::HTTP_OK; } } } } else if (command[0]=="list") { XML.pushTag("rotor"); if (request.getMethod()=="GET") { logger.information("sending tasklist"); //std::list < Poco::AutoPtr < Poco::Task > >::iterator it; //it=manager.taskList().begin(); //for (it=manager.taskList().begin();it !=manager.taskList().end();++it) { //content+=""+(*it)->name()+"\n"; //} //massive problems making an iterator for the tasklist, the above crashes //solution: auto type range-based for-loop //this is c++11 specific but works for (auto& task: manager.taskList()) { //c++11 XML.addValue("sID",task->name()); } status=HTTPResponse::HTTP_OK; } } else if (command[0]=="listnodes") { XML.pushTag("rotor"); if (request.getMethod()=="GET") { Node_factory factory; factory.list_nodes(XML); status=HTTPResponse::HTTP_OK; } } else if (command[0]=="listnode") { XML.pushTag("rotor"); if (request.getMethod()=="GET") { Node_factory factory; if (factory.list_node(body,XML)) status=HTTPResponse::HTTP_OK; } } else if (command[0]=="listrenders") { XML.pushTag("rotor"); if (request.getMethod()=="GET") { int i=0; for (auto r: renders){ XML.addTag("render"); XML.addAttribute("render","ID",r.first,i); bool context_found=false; for (auto& task: manager.taskList()) { if(task->name()==r.second) { Render_status status=((Poco::AutoPtr)task)->get_render_status(r.first); //cerr<<"render "<name()==command[0]) { //valid session command found=true; XML.addAttribute("rotor","context",task->name(),0); XML.pushTag("rotor"); if (command.size()==1) { //just invoking sID if (request.getMethod()=="DELETE") { task->cancel(); status=HTTPResponse::HTTP_OK; logger.information("deleted context "+command[0]); XML.addValue("status","context deleted successfully"); } else { logger.error("ERROR: Render context invoked with no command: "+command[0]); XML.addValue("error","Render context invoked with no command"); } } else { //session modifier command- to be passed to render context //some commands need to return error codes //ie where the audio file isn't found //on the other hand, some commands need to know state of the renderer? Session_command SC; vector sc; //uid,method,id,command1,{command2,}{body} SC.uid=idGen.createOne().toString(); sc.push_back(request.getMethod()); SC.method=request.getMethod(); for (auto& i: command){ sc.push_back(i); SC.commands.push_back(i); } sc.push_back(body); SC.body=body; ((Poco::AutoPtr)task)->session_command(SC,XML,status); if (XML.tagExists("render_id")){ //cerr<<"render started: "<(this, &RotorServer::handleHelp) ) ); } void RotorServer::handleHelp(const std::string& name, const std::string& value){ HelpFormatter helpFormatter(options()); helpFormatter.setCommand(commandName()); helpFormatter.setUsage("OPTIONS"); helpFormatter.setHeader( "Rotor"); helpFormatter.format(std::cout); stopOptionsProcessing(); _helpRequested = true; } int RotorServer::main(const std::vector& args){ if (!_helpRequested) { unsigned short port; Logger& logger = Logger::get("Rotor"); xmlIO xml; if(xml.loadFile("settings.xml") ){ port=xml.getAttribute("Rotor","port",9000,0); } else logger.information("settings.xml not found, using defaults"); logger.information("rotord running on port "+ofToString(port)); port = (unsigned short) config().getInt("port", port); //override from command line std::string format(config().getString("format", DateTimeFormat::SORTABLE_FORMAT)); ServerSocket svs(port); HTTPServer srv(new RotorRequestHandlerFactory(),svs, new HTTPServerParams); srv.start(); waitForTerminationRequest(); srv.stop(); } return Application::EXIT_OK; }