summaryrefslogtreecommitdiffstats
path: root/src/uscxml/server
diff options
context:
space:
mode:
authorStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2013-06-20 19:53:21 (GMT)
committerStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2013-06-20 19:53:21 (GMT)
commit794575f01ce5a6bf7e377eb815f3def5aded74f5 (patch)
tree9c59df64ee290f68b7b6c8698bfac4169684485e /src/uscxml/server
parentd304f85417e3175c5f2ca159dd303309c24e7b81 (diff)
downloaduscxml-794575f01ce5a6bf7e377eb815f3def5aded74f5.zip
uscxml-794575f01ce5a6bf7e377eb815f3def5aded74f5.tar.gz
uscxml-794575f01ce5a6bf7e377eb815f3def5aded74f5.tar.bz2
New version with XHTML invoker
Diffstat (limited to 'src/uscxml/server')
-rw-r--r--src/uscxml/server/HTTPServer.cpp56
-rw-r--r--src/uscxml/server/HTTPServer.h15
-rw-r--r--src/uscxml/server/InterpreterServlet.cpp3
-rw-r--r--src/uscxml/server/InterpreterServlet.h2
4 files changed, 45 insertions, 31 deletions
diff --git a/src/uscxml/server/HTTPServer.cpp b/src/uscxml/server/HTTPServer.cpp
index bd24326..f4b1a57 100644
--- a/src/uscxml/server/HTTPServer.cpp
+++ b/src/uscxml/server/HTTPServer.cpp
@@ -72,7 +72,10 @@ std::map<std::string, std::string> HTTPServer::mimeTypes;
HTTPServer* HTTPServer::getInstance(int port) {
// tthread::lock_guard<tthread::recursive_mutex> lock(_instanceMutex);
if (_instance == NULL) {
-
+#ifdef _WIN32
+ WSADATA wsaData;
+ WSAStartup(MAKEWORD(2, 2), &wsaData);
+#endif
// this is but a tiny list, supply a content-type <header> yourself
mimeTypes["txt"] = "text/plain";
mimeTypes["c"] = "text/plain";
@@ -109,19 +112,16 @@ std::string HTTPServer::mimeTypeForExtension(const std::string& ext) {
return "";
}
+/**
+ * This callback is registered for all HTTP requests
+ */
void HTTPServer::httpRecvReqCallback(struct evhttp_request *req, void *callbackData) {
-// std::cout << (uintptr_t)req << ": Replying" << std::endl;
-// evhttp_send_error(req, 404, NULL);
-// return;
-
std::stringstream raw;
evhttp_request_own(req);
Request request;
request.curlReq = req;
-
-
switch (evhttp_request_get_command(req)) {
case EVHTTP_REQ_GET:
request.data.compound["type"] = Data("get", Data::VERBATIM);
@@ -167,7 +167,7 @@ void HTTPServer::httpRecvReqCallback(struct evhttp_request *req, void *callbackD
const char* query = evhttp_uri_get_query(evhttp_request_get_evhttp_uri(req));
if (query)
raw << "?" << std::string(query);
-
+
raw << " HTTP/" << request.data.compound["httpMajor"].atom << "." << request.data.compound["httpMinor"].atom;
raw << std::endl;
@@ -237,40 +237,45 @@ void HTTPServer::httpRecvReqCallback(struct evhttp_request *req, void *callbackD
request.raw = raw.str();
- if (callbackData == NULL) {
+ // try with the handler registered for path first
+ bool answered = false;
+ if (callbackData != NULL)
+ answered = ((HTTPServlet*)callbackData)->httpRecvRequest(request);
+
+ if (!answered)
HTTPServer::getInstance()->processByMatchingServlet(request);
- } else {
- ((HTTPServlet*)callbackData)->httpRecvRequest(request);
- }
}
+
void HTTPServer::processByMatchingServlet(const Request& request) {
+ tthread::lock_guard<tthread::recursive_mutex> lock(_mutex);
+
servlet_iter_t servletIter = _servlets.begin();
std::string actualPath = request.data.compound.at("path").atom;
- HTTPServlet* bestMatch = NULL;
- std::string bestPath;
+ std::map<std::string, HTTPServlet*, comp_strsize_less> matches;
while(servletIter != _servlets.end()) {
// is the servlet path a prefix of the actual path?
std::string servletPath = "/" + servletIter->first;
if (boost::iequals(actualPath.substr(0, servletPath.length()), servletPath) && // actual path is a prefix
- boost::iequals(actualPath.substr(servletPath.length(), 1), "/")) { // and next character is a '/'
- if (bestPath.length() < servletPath.length()) {
- // this servlet is a better match
- bestPath = servletPath;
- bestMatch = servletIter->second;
- }
+ boost::iequals(actualPath.substr(servletPath.length(), 1), "/")) { // and next character is a '/'
+ matches.insert(std::make_pair(servletPath, servletIter->second));
}
servletIter++;
}
- if (bestMatch != NULL) {
- bestMatch->httpRecvRequest(request);
- } else {
- LOG(INFO) << "Got an HTTP request at " << actualPath << " but no servlet is registered there or at a prefix";
- evhttp_send_error(request.curlReq, 404, NULL);
+ // process by best matching servlet until someone feels responsible
+ std::map<std::string, HTTPServlet*, comp_strsize_less>::iterator matchesIter = matches.begin();
+ while(matchesIter != matches.end()) {
+ if (matchesIter->second->httpRecvRequest(request)) {
+ return;
+ }
+ matchesIter++;
}
+
+ LOG(INFO) << "Got an HTTP request at " << actualPath << " but no servlet is registered there or at a prefix";
+ evhttp_send_error(request.curlReq, 404, NULL);
}
void HTTPServer::reply(const Reply& reply) {
@@ -281,7 +286,6 @@ void HTTPServer::reply(const Reply& reply) {
}
void HTTPServer::replyCallback(evutil_socket_t fd, short what, void *arg) {
-
Reply* reply = (Reply*)arg;
if (reply->content.size() > 0 && reply->headers.find("Content-Type") == reply->headers.end()) {
diff --git a/src/uscxml/server/HTTPServer.h b/src/uscxml/server/HTTPServer.h
index bd54166..d216d5e 100644
--- a/src/uscxml/server/HTTPServer.h
+++ b/src/uscxml/server/HTTPServer.h
@@ -20,7 +20,7 @@ public:
Request() : curlReq(NULL) {}
std::string content;
struct evhttp_request* curlReq;
-
+
operator bool() {
return curlReq != NULL;
}
@@ -50,6 +50,15 @@ public:
static void unregisterServlet(HTTPServlet* servlet);
private:
+ struct comp_strsize_less {
+ bool operator()(std::string const& l, std::string const& r) const {
+ if (l.size() < r.size())
+ return false;
+
+ return l < r;
+ };
+ };
+
HTTPServer(unsigned short port);
~HTTPServer();
@@ -86,11 +95,11 @@ private:
class HTTPServlet {
public:
- virtual void httpRecvRequest(const HTTPServer::Request& request) = 0;
+ virtual bool httpRecvRequest(const HTTPServer::Request& request) = 0;
+ virtual void setURL(const std::string& url) = 0; /// Called by the server with the actual URL
virtual bool canAdaptPath() {
return true;
}
- virtual void setURL(const std::string& url) = 0; /// Called by the server with the actual URL
};
}
diff --git a/src/uscxml/server/InterpreterServlet.cpp b/src/uscxml/server/InterpreterServlet.cpp
index 28b7c1b..b59cc05 100644
--- a/src/uscxml/server/InterpreterServlet.cpp
+++ b/src/uscxml/server/InterpreterServlet.cpp
@@ -24,7 +24,7 @@ boost::shared_ptr<IOProcessorImpl> InterpreterServlet::create(InterpreterImpl* i
return io;
}
-void InterpreterServlet::httpRecvRequest(const HTTPServer::Request& req) {
+bool InterpreterServlet::httpRecvRequest(const HTTPServer::Request& req) {
tthread::lock_guard<tthread::recursive_mutex> lock(_mutex);
// evhttp_request_own(req.curlReq);
@@ -37,6 +37,7 @@ void InterpreterServlet::httpRecvRequest(const HTTPServer::Request& req) {
event.origin = toStr((uintptr_t)req.curlReq);
event.initContent(event.data.compound["content"].atom);
_interpreter->receive(event);
+ return true;
}
Data InterpreterServlet::getDataModelVariables() {
diff --git a/src/uscxml/server/InterpreterServlet.h b/src/uscxml/server/InterpreterServlet.h
index 6c61e47..c00bd11 100644
--- a/src/uscxml/server/InterpreterServlet.h
+++ b/src/uscxml/server/InterpreterServlet.h
@@ -26,7 +26,7 @@ public:
Data getDataModelVariables();
virtual void send(const SendRequest& req);
- virtual void httpRecvRequest(const HTTPServer::Request& req);
+ virtual bool httpRecvRequest(const HTTPServer::Request& req);
std::string getPath() {
return _path;