summaryrefslogtreecommitdiff
path: root/orkbasecxx/MultiThreadedServer.cpp
diff options
context:
space:
mode:
authorHenri Herscher <henri@oreka.org>2006-06-16 19:00:20 +0000
committerHenri Herscher <henri@oreka.org>2006-06-16 19:00:20 +0000
commit5ea30f3627dc91e138d23a055c37c022c956f4c7 (patch)
treee8f4bfac7e34e4267a8aa89621f1ea43b82c964a /orkbasecxx/MultiThreadedServer.cpp
parent3316ec6d8896fbbfab7ab6e1f2ee5bc30665dfb6 (diff)
Moving stuff from orkaudio to orkbasecxx
git-svn-id: https://oreka.svn.sourceforge.net/svnroot/oreka/trunk@260 09dcff7a-b715-0410-9601-b79a96267cd0
Diffstat (limited to 'orkbasecxx/MultiThreadedServer.cpp')
-rw-r--r--orkbasecxx/MultiThreadedServer.cpp223
1 files changed, 223 insertions, 0 deletions
diff --git a/orkbasecxx/MultiThreadedServer.cpp b/orkbasecxx/MultiThreadedServer.cpp
new file mode 100644
index 0000000..3dcc417
--- /dev/null
+++ b/orkbasecxx/MultiThreadedServer.cpp
@@ -0,0 +1,223 @@
+/*
+ * Oreka -- A media capture and retrieval platform
+ *
+ * Copyright (C) 2005, orecx LLC
+ *
+ * http://www.orecx.com
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License.
+ * Please refer to http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "MultiThreadedServer.h"
+
+#include "ace/INET_Addr.h"
+#include "ace/OS_NS_string.h"
+#include "ObjectFactory.h"
+#include "serializers/SingleLineSerializer.h"
+#include "serializers/DomSerializer.h"
+#include "serializers/UrlSerializer.h"
+#include "LogManager.h"
+#include "Utils.h"
+#include <xercesc/parsers/XercesDOMParser.hpp>
+#include <xercesc/dom/DOMWriter.hpp>
+#include <xercesc/dom/DOMImplementation.hpp>
+#include <xercesc/dom/DOMImplementationRegistry.hpp>
+
+
+int CommandLineServer::open (void *void_acceptor)
+{
+ return this->activate (THR_DETACHED);
+}
+
+
+void CommandLineServer::run(void* args)
+{
+ unsigned short tcpPort = (unsigned short)(unsigned int)args;
+ CommandLineAcceptor peer_acceptor;
+ ACE_INET_Addr addr (tcpPort);
+ ACE_Reactor reactor;
+
+ if (peer_acceptor.open (addr, &reactor) == -1)
+ {
+ CStdString tcpPortString = IntToString(tcpPort);
+ LOG4CXX_ERROR(LOG.rootLog, CStdString("Failed to start command line server on port:") + tcpPortString);
+ }
+ else
+ {
+ for(;;)
+ {
+ reactor.handle_events();
+ }
+ }
+}
+
+int CommandLineServer::svc(void)
+{
+ for (bool active = true;active == true;)
+ {
+ char buf[2048];
+ ACE_Time_Value timeout;
+ timeout.sec(3600);
+ int i = 0;
+
+ // Display prompt
+ char prompt[] = "\r\n>";
+ peer().send(prompt, 3);
+
+ // Get one command line
+ bool foundCRLF = false;
+ while(active && !foundCRLF && i<2040)
+ {
+ ssize_t size = peer().recv(buf+i, 2040-i, &timeout);
+
+ if (size == 0 || size == -1)
+ {
+ active = false;
+ }
+ else
+ {
+ for(int j=0; j<size && !foundCRLF;j++)
+ {
+ if(buf[i+j] == '\r' || buf[i+j] == '\n')
+ {
+ foundCRLF = true;
+ buf[i+j] = '\0';
+ CStdString command(buf);
+ try
+ {
+ CStdString className = SingleLineSerializer::FindClass(command);
+ ObjectRef objRef = ObjectFactorySingleton::instance()->NewInstance(className);
+ if (objRef.get())
+ {
+ objRef->DeSerializeSingleLine(command);
+ ObjectRef response = objRef->Process();
+ CStdString responseString = response->SerializeSingleLine();
+ peer().send((PCSTR)responseString, responseString.GetLength());
+ }
+ else
+ {
+ CStdString error = "Unrecognized command";
+ peer().send(error, error.GetLength()); ;
+ }
+ }
+ catch (CStdString& e)
+ {
+ peer().send(e, e.GetLength()); ;
+ }
+ }
+ }
+ i += size;
+ }
+ }
+ }
+ return 0;
+}
+
+
+//==============================================================
+
+int HttpServer::open (void *void_acceptor)
+{
+ return this->activate (THR_DETACHED);
+}
+
+
+void HttpServer::run(void* args)
+{
+ unsigned short tcpPort = (unsigned short)(unsigned int)args;
+ HttpAcceptor peer_acceptor;
+ ACE_INET_Addr addr (tcpPort);
+ ACE_Reactor reactor;
+
+ if (peer_acceptor.open (addr, &reactor) == -1)
+ {
+ CStdString tcpPortString = IntToString(tcpPort);
+ LOG4CXX_ERROR(LOG.rootLog, CStdString("Failed to start http server on port:") + tcpPortString);
+ }
+ else
+ {
+ for(;;)
+ {
+ reactor.handle_events();
+ }
+ }
+}
+
+int HttpServer::svc(void)
+{
+ char buf[2048];
+ buf[2047] = '\0'; // security
+ ACE_Time_Value timeout;
+
+ ssize_t size = peer().recv(buf, 2040);
+
+ if (size > 5)
+ {
+ try
+ {
+ int startUrlOffset = 5; // get rid of "GET /" from Http request, so skip 5 chars
+ char* stopUrl = ACE_OS::strstr(buf+startUrlOffset, " HTTP"); // detect location of post-URL trailing stuff
+ if(!stopUrl)
+ {
+ throw (CStdString("Malformed http request")); ;
+ }
+ *stopUrl = '\0'; // Remove post-URL trailing stuff
+ CStdString url(buf+startUrlOffset);
+ int queryOffset = url.Find("?");
+ if (queryOffset > 0)
+ {
+ // Strip beginning of URL in case the command is received as an URL "query" of the form:
+ // http://hostname/service/command?type=ping
+ url = url.Right(url.size() - queryOffset - 1);
+ }
+
+
+ CStdString className = UrlSerializer::FindClass(url);
+ ObjectRef objRef = ObjectFactorySingleton::instance()->NewInstance(className);
+ if (objRef.get())
+ {
+ objRef->DeSerializeUrl(url);
+ ObjectRef response = objRef->Process();
+
+ DOMImplementation* impl = DOMImplementationRegistry::getDOMImplementation(XStr("Core").unicodeForm());
+ XERCES_CPP_NAMESPACE::DOMDocument* myDoc;
+ myDoc = impl->createDocument(
+ 0, // root element namespace URI.
+ XStr("response").unicodeForm(), // root element name
+ 0); // document type object (DTD).
+ response->SerializeDom(myDoc);
+ CStdString pingResponse = DomSerializer::DomNodeToString(myDoc);
+
+ CStdString httpOk("HTTP/1.0 200 OK\r\nContent-type: text/xml\r\n\r\n");
+ peer().send(httpOk, httpOk.GetLength());
+ peer().send(pingResponse, pingResponse.GetLength());
+ }
+ else
+ {
+ throw (CStdString("Command not found:") + className); ;
+ }
+
+ }
+ catch (CStdString &e)
+ {
+ CStdString error("HTTP/1.0 404 not found\r\nContent-type: text/html\r\n\r\nError\r\n");
+ error = error + e + "\r\n";
+ peer().send(error, error.GetLength());
+ }
+ catch(const XMLException& e)
+ {
+ CStdString error("HTTP/1.0 404 not found\r\nContent-type: text/html\r\n\r\nXML Error\r\n");
+ peer().send(error, error.GetLength());
+ }
+ }
+ else
+ {
+ CStdString notFound("HTTP/1.0 404 not found\r\nContent-type: text/html\r\n\r\nNot found\r\n");
+ peer().send(notFound, notFound.GetLength());
+ }
+ return 0;
+}
+