From a5b2c2081329958710a59107854349f5b6a14bcb Mon Sep 17 00:00:00 2001 From: Stefan Radomski Date: Sat, 16 Nov 2013 17:45:34 +0100 Subject: Builds on windows again --- README.md | 2 + contrib/local/compress_and_upload_deps.sh | 6 +- contrib/src/evws/evws.c | 115 +++++++--- contrib/src/evws/evws.h | 57 +++-- src/uscxml/Common.h | 1 + src/uscxml/Convenience.h | 178 +++++++-------- src/uscxml/DOMUtils.h | 1 + src/uscxml/Interpreter.h | 6 +- src/uscxml/URL.cpp | 4 +- .../plugins/datamodel/xpath/XPathDataModel.cpp | 11 +- .../openscenegraph/converter/OSGConverter.cpp | 62 ++--- .../plugins/invoker/miles/MilesSessionInvoker.cpp | 24 +- .../ioprocessor/basichttp/BasicHTTPIOProcessor.cpp | 2 +- src/uscxml/server/HTTPServer.cpp | 252 +++++++++++---------- src/uscxml/server/HTTPServer.h | 16 +- src/uscxml/server/InterpreterServlet.cpp | 54 ++--- src/uscxml/server/InterpreterServlet.h | 16 +- src/uscxml/util/Base64.h | 60 ++--- src/uscxml/util/MD5.h | 50 ++-- src/uscxml/util/SHA1.h | 67 +++--- 20 files changed, 554 insertions(+), 430 deletions(-) mode change 100755 => 100644 src/uscxml/util/SHA1.h diff --git a/README.md b/README.md index 02d324d..e9cd5bb 100644 --- a/README.md +++ b/README.md @@ -25,9 +25,11 @@ There are still a few rough edges though, especially with the plugins and custom * Features the standard basichttp io-processor * Features the required SCXML io-processor * No DOM io-processor + * Early support for [WebSockets](http://datatracker.ietf.org/doc/rfc6455/) * Can actually respond to HTTP requests with data via <response> * Language Bindings * PHP module for apache and cli interpreter + * Java bindings ## Test Reports diff --git a/contrib/local/compress_and_upload_deps.sh b/contrib/local/compress_and_upload_deps.sh index e47d7b5..90a398d 100755 --- a/contrib/local/compress_and_upload_deps.sh +++ b/contrib/local/compress_and_upload_deps.sh @@ -36,7 +36,11 @@ for FILE in ${PLATFORMS}; do PLATFORM=`basename $FILE` echo $FILE if [ "$PLATFORM" != "include" ]; then - tar cvzf uscxml-prebuilt-${PLATFORM}.tgz --exclude='*/.DS_Store' --exclude='VERSION.txt' --exclude='lib/*_d.a' ${FILE} + if [ "$PLATFORM" == windows* ]; then + tar cvzf uscxml-prebuilt-${PLATFORM}.tgz --exclude='*/.DS_Store' --exclude='VERSION.txt' ${FILE} + else + tar cvzf uscxml-prebuilt-${PLATFORM}.tgz --exclude='*/.DS_Store' --exclude='VERSION.txt' --exclude='lib/*_d.a' ${FILE} + fi scp uscxml-prebuilt-${PLATFORM}.tgz ${USCXML_PREBUILT_HOST}:${USCXML_PREBUILT_PATH}/${VERSION} rm uscxml-prebuilt-${PLATFORM}.tgz else diff --git a/contrib/src/evws/evws.c b/contrib/src/evws/evws.c index 35adaa1..b39bc03 100644 --- a/contrib/src/evws/evws.c +++ b/contrib/src/evws/evws.c @@ -26,6 +26,31 @@ #include "uscxml/util/SHA1.h" #include "uscxml/util/Base64.h" +#ifdef _WIN32 + +char* strsep(char** stringp, const char* delim) { + char* start = *stringp; + char* p; + + p = (start != NULL) ? strpbrk(start, delim) : NULL; + + if (p == NULL) + { + *stringp = NULL; + } + else + { + *p = '\0'; + *stringp = p + 1; + } + + return start; +} + +#define strdup _strdup + +#endif + static int evws_parse_first_line(struct evws_connection *conn, char *line); static int evws_parse_header_line(char *line, char **skey, char **svalue); @@ -41,8 +66,11 @@ struct evws *evws_new(struct event_base *base) { ret_obj->base = base; ret_obj->listener = NULL; - TAILQ_INIT(&ret_obj->connections); - TAILQ_INIT(&ret_obj->callbacks); + ret_obj->connections.tqh_first = NULL; + ret_obj->connections.tqh_last = &(ret_obj->connections.tqh_first); + + ret_obj->callbacks.tqh_first = NULL; + ret_obj->callbacks.tqh_last = &(ret_obj->callbacks.tqh_first); return ret_obj; } @@ -70,7 +98,7 @@ evutil_socket_t evws_bind_socket(struct evws * ws, unsigned short port) { int evws_set_cb(struct evws * ws, const char * uri, cb_frame_type message_cb, cb_type connect_cb, void * arg) { struct evws_cb *ws_cb; - TAILQ_FOREACH(ws_cb, &ws->callbacks, next) { + for (ws_cb = ws->callbacks.tqh_first; ws_cb; ws_cb = ws_cb->next.tqe_next) { if (strcmp(ws_cb->uri, uri) == 0) return (-1); } @@ -84,7 +112,11 @@ int evws_set_cb(struct evws * ws, const char * uri, cb_frame_type message_cb, cb ws_cb->conn_cb = connect_cb; ws_cb->cb_arg = arg; - TAILQ_INSERT_TAIL(&ws->callbacks, ws_cb, next); + // TAILQ_INSERT_TAIL + ws_cb->next.tqe_next = NULL; + ws_cb->next.tqe_prev = ws->callbacks.tqh_last; + ws->callbacks.tqh_last = &ws_cb; + ws->callbacks.tqh_last = &ws_cb->next.tqe_next; return (0); } @@ -99,7 +131,7 @@ cb_frame_type evws_set_gencb(struct evws *ws, cb_frame_type cb, void * arg) { // Broadcast data to all buffers associated with pattern void evws_broadcast(struct evws *ws, const char *uri, enum evws_opcode opcode, const char *data, uint64_t length) { struct evws_connection *ws_connection; - TAILQ_FOREACH(ws_connection, &ws->connections, next) { + for (ws_connection = ws->connections.tqh_first; ws_connection; ws_connection = ws_connection->next.tqe_next) { if (strcmp(ws_connection->uri, uri) == 0) evws_send_data(ws_connection, opcode, data, length); } @@ -108,7 +140,16 @@ void evws_broadcast(struct evws *ws, const char *uri, enum evws_opcode opcode, c // Error callback static void cb_error(struct bufferevent *bev, short what, void *ctx) { struct evws_connection *conn = ctx; - TAILQ_REMOVE(&(conn->ws->connections), conn, next); + + //TAILQ_REMOVE + if (conn->next.tqe_next != NULL) + conn->next.tqe_next->next.tqe_prev = conn->next.tqe_prev; + else { + conn->ws->connections.tqh_last = conn->next.tqe_prev; + } + conn->next.tqe_prev = &conn->next.tqe_next; + + evws_connection_free(conn); } @@ -149,11 +190,18 @@ void cb_read_handshake(struct bufferevent *bev, void *arg) { struct evws_connection *ws_conn = arg; char *line, *skey, *svalue; struct evbuffer *buffer = bufferevent_get_input(bev); + struct evws_header *header = NULL; size_t line_length; char *key = NULL; char *host = NULL; char *origin = NULL; - + SHA1Context sha1; + char chksumSha1[21]; + int i; + int md5End = 0; + char chksumBase64[200]; + base64_encodestate* base64Ctx = NULL; + switch(ws_conn->state) { case 0: line = evbuffer_readln(buffer, &line_length, EVBUFFER_EOL_CRLF); @@ -175,8 +223,13 @@ void cb_read_handshake(struct bufferevent *bev, void *arg) { } else if(strcmp(skey, "Origin") == 0) { origin = strdup(svalue); } - struct evws_header *header = evws_header_new(skey, svalue); - TAILQ_INSERT_TAIL(&ws_conn->headers, header, next); + header = evws_header_new(skey, svalue); + //TAILQ_INSERT_TAIL + header->next.tqe_next = NULL; + header->next.tqe_prev = ws_conn->headers.tqh_last; + ws_conn->headers.tqh_last = &header; + ws_conn->headers.tqh_last = &header->next.tqe_next; + free(line); } default: @@ -185,14 +238,11 @@ void cb_read_handshake(struct bufferevent *bev, void *arg) { // -- SHA1 - SHA1Context sha1; SHA1Reset(&sha1); SHA1Input(&sha1, (const unsigned char*)key, 24); SHA1Input(&sha1, (const unsigned char*)WS_GUID, 36); SHA1Result(&sha1); - char chksumSha1[21]; - int i; for (i = 0; i < 5; i++) { chksumSha1[i * 4 + 0] = (sha1.Message_Digest[i] >> 24) & 0xff; chksumSha1[i * 4 + 1] = (sha1.Message_Digest[i] >> 16) & 0xff; @@ -203,9 +253,7 @@ void cb_read_handshake(struct bufferevent *bev, void *arg) { // -- BASE64 - int md5End = 0; - char chksumBase64[200]; - base64_encodestate* base64Ctx = malloc(sizeof(base64_encodestate)); + base64Ctx = malloc(sizeof(base64_encodestate)); base64_init_encodestate(base64Ctx); md5End += base64_encode_block(chksumSha1, 20, chksumBase64, base64Ctx); md5End += base64_encode_blockend(&chksumBase64[md5End], base64Ctx); @@ -234,10 +282,15 @@ void cb_read_handshake(struct bufferevent *bev, void *arg) { ); bufferevent_setcb(ws_conn->bufev, cb_read_frame, NULL, cb_error, ws_conn); - TAILQ_INSERT_TAIL(&(ws_conn->ws->connections), ws_conn, next); + //TAILQ_INSERT_TAIL(&(ws_conn->ws->connections), ws_conn, next); + ws_conn->next.tqe_next = NULL; + ws_conn->next.tqe_prev = ws_conn->ws->connections.tqh_last; + ws_conn->ws->connections.tqh_last = &ws_conn; + ws_conn->ws->connections.tqh_last = &ws_conn->next.tqe_next; + { struct evws_cb *ws_cb; - TAILQ_FOREACH(ws_cb, &ws_conn->ws->callbacks, next) { + for (ws_cb = ws_conn->ws->callbacks.tqh_first; ws_cb; ws_cb = ws_cb->next.tqe_next) { if (strcmp(ws_cb->uri, ws_conn->uri) == 0) { if(ws_cb->conn_cb != NULL) ws_cb->conn_cb(ws_conn, NULL, 0, ws_cb->cb_arg); @@ -361,7 +414,7 @@ NEXT_FRAME: if (conn->frame->payload_read == conn->frame->size) { // done reading this frame - invoke callbacks struct evws_cb *ws_cb; - TAILQ_FOREACH(ws_cb, &ws->callbacks, next) { + for (ws_cb = ws->callbacks.tqh_first; ws_cb; ws_cb = ws_cb->next.tqe_next) { if (strcmp(ws_cb->uri, conn->uri) == 0) { if(ws_cb->msg_cb != NULL) ws_cb->msg_cb(conn, conn->frame, ws_cb->cb_arg); @@ -379,11 +432,15 @@ NEXT_FRAME: } void evws_send_data(struct evws_connection *conn, enum evws_opcode opcode, const char *data, uint64_t length) { - char *sendbuf = malloc(length + 10); // payload + header without masking key + char* writePtr = NULL; + char *sendbuf = NULL; + struct evbuffer *buffer = NULL; + + sendbuf = malloc(length + 10); // payload + header without masking key if(sendbuf == NULL) return; - char* writePtr = sendbuf; + writePtr = sendbuf; writePtr[0] = (1 << 7); // set fin header and zero out RSV writePtr[0] += opcode; // set opcode @@ -415,7 +472,7 @@ void evws_send_data(struct evws_connection *conn, enum evws_opcode opcode, const memcpy(writePtr, data, length); writePtr += length; - struct evbuffer *buffer = bufferevent_get_output(conn->bufev); + buffer = bufferevent_get_output(conn->bufev); evbuffer_add(buffer, sendbuf, writePtr - sendbuf); free(sendbuf); } @@ -432,7 +489,10 @@ struct evws_connection* evws_connection_new(struct evws *ws, evutil_socket_t fd) conn->bufev = bufferevent_socket_new(ws->base, fd, BEV_OPT_CLOSE_ON_FREE); conn->state = 0; conn->frame = NULL; - TAILQ_INIT(&conn->headers); + + conn->headers.tqh_first = NULL; + conn->headers.tqh_last = &(conn->headers.tqh_first); + return conn; } @@ -442,7 +502,7 @@ void evws_connection_free(struct evws_connection *conn) { if(conn->uri != NULL) free(conn->uri); - TAILQ_FOREACH(header, &conn->headers, next) { + for (header = conn->headers.tqh_first; header; header = header->next.tqe_next) { evws_header_free(header); } free(conn); @@ -477,11 +537,12 @@ void evws_header_free(struct evws_header *header) { } char *evws_find_header(const struct wsheadersq *q, const char *key) { - struct evws_header *hdr; + struct evws_header *header; char * ret = NULL; - TAILQ_FOREACH(hdr, q, next) { - if(strcmp(hdr->key, key) == 0) { - ret = hdr->value; + for (header = q->tqh_first; header; header = header->next.tqe_next) { + + if(strcmp(header->key, key) == 0) { + ret = header->value; break; } } diff --git a/contrib/src/evws/evws.h b/contrib/src/evws/evws.h index 7967a64..f9ea567 100644 --- a/contrib/src/evws/evws.h +++ b/contrib/src/evws/evws.h @@ -24,13 +24,21 @@ #include #include #include -#include +#ifndef _WIN32 +# include +#endif #include #ifdef __cplusplus extern "C" { #endif +struct evws; +struct evws_header; +struct evws_frame; +struct evws_connection; +struct evwsconq; + enum evws_opcode { EVWS_CONTINUATION_FRAME = 0x0, EVWS_TEXT_FRAME = 0x1, @@ -58,7 +66,10 @@ enum evws_frame_state { }; struct evws_header { - TAILQ_ENTRY(evws_header) next; + struct { + struct evws_header *tqe_next; + struct evws_header **tqe_prev; + } next; char *key; char *value; }; @@ -125,9 +136,11 @@ struct evws_frame { uint8_t state; }; -struct evws_connection -{ - TAILQ_ENTRY(evws_connection) next; +struct evws_connection { + struct { + struct evws_connection *tqe_next; + struct evws_connection **tqe_prev; + } next; struct evws *ws; struct evws_frame *frame; char *uri; @@ -136,33 +149,41 @@ struct evws_connection int fd; // headers - TAILQ_HEAD(wsheadersq, evws_header) headers; + struct wsheadersq { + struct evws_header *tqh_first; + struct evws_header **tqh_last; + } headers; + }; typedef void (*cb_type)(struct evws_connection *, const char *, size_t, void *); typedef void (*cb_frame_type)(struct evws_connection *, struct evws_frame *, void *); -struct evws_cb -{ - TAILQ_ENTRY(evws_cb) next; +struct evws_cb { + struct { + struct evws_cb *tqe_next; + struct evws_cb **tqe_prev; + } next; + char * uri; cb_frame_type msg_cb; cb_type conn_cb; void * cb_arg; }; -struct evws_read_buf -{ - TAILQ_ENTRY(evws_read_buf) next; - char* data; -}; -TAILQ_HEAD(evwsconq, evws_connection); +struct evwsconq { + struct evws_connection *tqh_first; + struct evws_connection **tqh_last; +}; -struct evws -{ +struct evws { struct evconnlistener *listener; - TAILQ_HEAD(wscbq, evws_cb) callbacks; + struct wscbq { + struct evws_cb *tqh_first; + struct evws_cb **tqh_last; + } callbacks; + struct evwsconq connections; // generic callback diff --git a/src/uscxml/Common.h b/src/uscxml/Common.h index eaa1a2b..c261301 100644 --- a/src/uscxml/Common.h +++ b/src/uscxml/Common.h @@ -56,6 +56,7 @@ // is thrown alot in arabica headers #pragma warning (disable : 4240) #pragma warning (disable : 4250) +#pragma warning (disable : 4661) // dll interface #pragma warning (disable : 4251) diff --git a/src/uscxml/Convenience.h b/src/uscxml/Convenience.h index f764d06..9f4c1a1 100644 --- a/src/uscxml/Convenience.h +++ b/src/uscxml/Convenience.h @@ -88,108 +88,108 @@ x.ull = 0x0123456789abcdef; // may need special suffix for ULL. */ enum endianness { - little_endian, - big_endian, - network_endian = big_endian, - + little_endian, + big_endian, + network_endian = big_endian, + #if defined(BOOST_LITTLE_ENDIAN) - host_endian = little_endian + host_endian = little_endian #elif defined(BOOST_BIG_ENDIAN) - host_endian = big_endian + host_endian = big_endian #else #error "unable to determine system endianness" #endif }; namespace detail { - - template - struct swap_bytes { - inline T operator()(T val) { - throw std::out_of_range("data size"); - } - }; - - template - struct swap_bytes { - inline T operator()(T val) { - return val; - } - }; - - template - struct swap_bytes { // for 16 bit - inline T operator()(T val) { - return ((((val) >> 8) & 0xff) | (((val) & 0xff) << 8)); - } - }; - - template - struct swap_bytes { // for 32 bit - inline T operator()(T val) { + +template +struct swap_bytes { + inline T operator()(T val) { + throw std::out_of_range("data size"); + } +}; + +template +struct swap_bytes { + inline T operator()(T val) { + return val; + } +}; + +template +struct swap_bytes { // for 16 bit + inline T operator()(T val) { + return ((((val) >> 8) & 0xff) | (((val) & 0xff) << 8)); + } +}; + +template +struct swap_bytes { // for 32 bit + inline T operator()(T val) { #if defined(_USE_BUILTIN_BSWAPS) && defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4) - return __builtin_bswap32(val); + return __builtin_bswap32(val); #else - return ((((val) & 0xff000000) >> 24) | - (((val) & 0x00ff0000) >> 8) | - (((val) & 0x0000ff00) << 8) | - (((val) & 0x000000ff) << 24)); + return ((((val) & 0xff000000) >> 24) | + (((val) & 0x00ff0000) >> 8) | + (((val) & 0x0000ff00) << 8) | + (((val) & 0x000000ff) << 24)); #endif - } - }; - - template<> - struct swap_bytes { - inline float operator()(float val) { - uint32_t mem = swap_bytes()(*(uint32_t*)&val); - return *(float*)&mem; - } - }; - - template - struct swap_bytes { // for 64 bit - inline T operator()(T val) { + } +}; + +template<> +struct swap_bytes { + inline float operator()(float val) { + uint32_t mem = swap_bytes()(*(uint32_t*)&val); + return *(float*)&mem; + } +}; + +template +struct swap_bytes { // for 64 bit + inline T operator()(T val) { #if defined(_USE_BUILTIN_BSWAPS) && defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4) - return __builtin_bswap64(val); + return __builtin_bswap64(val); #else - return ((((val) & 0xff00000000000000ull) >> 56) | - (((val) & 0x00ff000000000000ull) >> 40) | - (((val) & 0x0000ff0000000000ull) >> 24) | - (((val) & 0x000000ff00000000ull) >> 8 ) | - (((val) & 0x00000000ff000000ull) << 8 ) | - (((val) & 0x0000000000ff0000ull) << 24) | - (((val) & 0x000000000000ff00ull) << 40) | - (((val) & 0x00000000000000ffull) << 56)); + return ((((val) & 0xff00000000000000ull) >> 56) | + (((val) & 0x00ff000000000000ull) >> 40) | + (((val) & 0x0000ff0000000000ull) >> 24) | + (((val) & 0x000000ff00000000ull) >> 8 ) | + (((val) & 0x00000000ff000000ull) << 8 ) | + (((val) & 0x0000000000ff0000ull) << 24) | + (((val) & 0x000000000000ff00ull) << 40) | + (((val) & 0x00000000000000ffull) << 56)); #endif - } - }; - - template<> - struct swap_bytes { - inline double operator()(double val) { - uint64_t mem = swap_bytes()(*(uint64_t*)&val); - return *(double*)&mem; - } - }; - - template - struct do_byte_swap { - inline T operator()(T value) { - return swap_bytes()(value); - } - }; - // specialisations when attempting to swap to the same endianess - template struct do_byte_swap { - inline T operator()(T value) { - return value; - } - }; - template struct do_byte_swap { - inline T operator()(T value) { - return value; - } - }; - + } +}; + +template<> +struct swap_bytes { + inline double operator()(double val) { + uint64_t mem = swap_bytes()(*(uint64_t*)&val); + return *(double*)&mem; + } +}; + +template +struct do_byte_swap { + inline T operator()(T value) { + return swap_bytes()(value); + } +}; +// specialisations when attempting to swap to the same endianess +template struct do_byte_swap { + inline T operator()(T value) { + return value; + } +}; +template struct do_byte_swap { + inline T operator()(T value) { + return value; + } +}; + } // namespace detail template @@ -198,7 +198,7 @@ inline T byte_swap(T value) { BOOST_STATIC_ASSERT(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8); // ensure we're only swapping arithmetic types BOOST_STATIC_ASSERT(boost::is_arithmetic::value); - + return detail::do_byte_swap()(value); } diff --git a/src/uscxml/DOMUtils.h b/src/uscxml/DOMUtils.h index 31e7df0..103296b 100644 --- a/src/uscxml/DOMUtils.h +++ b/src/uscxml/DOMUtils.h @@ -22,6 +22,7 @@ #include "uscxml/Common.h" #include +#include #include #define TAGNAME(elem) ((Arabica::DOM::Element)elem).getTagName() diff --git a/src/uscxml/Interpreter.h b/src/uscxml/Interpreter.h index f192152..5cc9053 100644 --- a/src/uscxml/Interpreter.h +++ b/src/uscxml/Interpreter.h @@ -135,7 +135,7 @@ public: EARLY = 0, LATE = 1 }; - + virtual ~InterpreterImpl(); void start(); @@ -310,7 +310,7 @@ protected: void handleEvent(Arabica::DOM::Events::Event& event); InterpreterImpl* _interpreter; }; - + InterpreterImpl(); void init(); @@ -353,7 +353,7 @@ protected: DelayedEventQueue* _sendQueue; DOMEventListener _domEventListener; - + Event _currEvent; Factory* _factory; InterpreterHTTPServlet* _httpServlet; diff --git a/src/uscxml/URL.cpp b/src/uscxml/URL.cpp index 6ebd9a6..2aaa46b 100644 --- a/src/uscxml/URL.cpp +++ b/src/uscxml/URL.cpp @@ -552,7 +552,7 @@ void URLFetcher::fetchURL(URL& url) { // (curlError = curl_easy_setopt(handle, CURLOPT_NOSIGNAL, 1)) == CURLE_OK || // LOG(ERROR) << "Cannot set curl to ignore signals: " << curl_easy_strerror(curlError); - + (curlError = curl_easy_setopt(handle, CURLOPT_WRITEDATA, url._impl.get())) == CURLE_OK || LOG(ERROR) << "Cannot register this as write userdata: " << curl_easy_strerror(curlError); @@ -605,7 +605,7 @@ void URLFetcher::fetchURL(URL& url) { // Disable "Expect: 100-continue" headers = curl_slist_append(headers, "Expect:"); - + (curlError = curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers)) == CURLE_OK || LOG(ERROR) << "Cannot headers for " << url.asString() << ": " << curl_easy_strerror(curlError); diff --git a/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp b/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp index 25f7d45..cdbec28 100644 --- a/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp +++ b/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp @@ -210,9 +210,8 @@ void XPathDataModel::setEvent(const Event& event) { unsigned int i; for( i = 0 , ptr = event.data.array.begin() ; - ((i < event.data.array.size()) && (ptr != event.data.array.end())); - i++ , ptr++ ) - { + ((i < event.data.array.size()) && (ptr != event.data.array.end())); + i++ , ptr++ ) { Element eventMESElem = _doc.createElement("data"); Text textNode = _doc.createTextNode(ptr->atom.c_str()); std::stringstream ss; @@ -495,7 +494,7 @@ void XPathDataModel::assign(const Element& assignElem, if (trimmed.length() == 0) { data = data.getNextSibling(); continue; - } + } } nodeSet.push_back(data); data = data.getNextSibling(); @@ -706,8 +705,8 @@ void XPathDataModel::assign(const NodeSet& key, for (int i = 0; i < key.size(); i++) { switch (key[i].getNodeType()) case Node_base::ELEMENT_NODE: { - assign(Element(key[i]), value, assignElem); - break; + assign(Element(key[i]), value, assignElem); + break; default: // std::cout << key[i].getNodeType() << std::endl; throw Event("error.execution", Event::PLATFORM); diff --git a/src/uscxml/plugins/invoker/graphics/openscenegraph/converter/OSGConverter.cpp b/src/uscxml/plugins/invoker/graphics/openscenegraph/converter/OSGConverter.cpp index c742ec7..536d276 100644 --- a/src/uscxml/plugins/invoker/graphics/openscenegraph/converter/OSGConverter.cpp +++ b/src/uscxml/plugins/invoker/graphics/openscenegraph/converter/OSGConverter.cpp @@ -133,14 +133,14 @@ void OSGConverter::send(const SendRequest& req) { for (std::list::const_iterator formatIter = formats.begin(); formatIter != formats.end(); formatIter++) { actualReq.params.insert(std::make_pair("format", *formatIter)); } - + // format given as expression std::list formatExprs; Event::getParam(req.params, "formatexpr", formatExprs); for (std::list::const_iterator formatIter = formatExprs.begin(); formatIter != formatExprs.end(); formatIter++) { actualReq.params.insert(std::make_pair("format", _interpreter->getDataModel().getStringAsData(*formatIter))); } - + if (actualReq.params.find("format") == actualReq.params.end()) { // no explicit format, try to get from destination std::string dest; @@ -154,7 +154,7 @@ void OSGConverter::send(const SendRequest& req) { } } } - + if (actualReq.params.find("format") == actualReq.params.end()) { LOG(ERROR) << "missing format"; reportFailure(req); @@ -244,8 +244,8 @@ void OSGConverter::process(const SendRequest& req) { bool optimizeGeometry = false; if (req.params.find("optimizegeometry") != req.params.end()) { if (iequals(req.params.find("optimizegeometry")->second.atom, "on") || - iequals(req.params.find("optimizegeometry")->second.atom, "1") || - iequals(req.params.find("optimizegeometry")->second.atom, "true")) { + iequals(req.params.find("optimizegeometry")->second.atom, "1") || + iequals(req.params.find("optimizegeometry")->second.atom, "true")) { optimizeGeometry = true; } } @@ -253,8 +253,8 @@ void OSGConverter::process(const SendRequest& req) { bool antiAliased = true; if (req.params.find("antialiased") != req.params.end()) { if (iequals(req.params.find("antialiased")->second.atom, "off") || - iequals(req.params.find("antialiased")->second.atom, "0") || - iequals(req.params.find("antialiased")->second.atom, "false")) { + iequals(req.params.find("antialiased")->second.atom, "0") || + iequals(req.params.find("antialiased")->second.atom, "false")) { antiAliased = false; } } @@ -271,9 +271,9 @@ void OSGConverter::process(const SendRequest& req) { osgUtil::Optimizer optimizer; optimizer.optimize(model, osgUtil::Optimizer::ALL_OPTIMIZATIONS); } - + Data retContent; - + // setup scenegraph osg::ref_ptr sceneGraph = new osg::Group(); sceneGraph->addChild(model); @@ -282,7 +282,7 @@ void OSGConverter::process(const SendRequest& req) { for (std::list::iterator formatIter = formats.begin(); formatIter != formats.end(); formatIter++) { std::string format = *formatIter; - + osg::ref_ptr writer = osgDB::Registry::instance()->getReaderWriterForExtension(format); if (writer.valid()) { @@ -294,7 +294,7 @@ void OSGConverter::process(const SendRequest& req) { // pass option to disable tristrips when writing osgjs files if (strcmp(format.c_str(), "osgjs") == 0) rwOptions->setOptionString("disableTriStrip"); - + result = writer->writeNode(*sceneGraph, ss, rwOptions); if (result.success()) { if (dest.length() > 0) { @@ -305,12 +305,12 @@ void OSGConverter::process(const SendRequest& req) { continue; } } - + // conversion from 3d model to image tthread::lock_guard lock(_viewerMutex); osgViewer::Viewer viewer; osg::Camera *camera = viewer.getCamera(); - + osg::ref_ptr traits = new osg::GraphicsContext::Traits; traits->width = width; @@ -325,55 +325,55 @@ void OSGConverter::process(const SendRequest& req) { viewer.setDisplaySettings(ds); } osg::GraphicsContext *gc = - osg::GraphicsContext::createGraphicsContext(traits.get()); - + osg::GraphicsContext::createGraphicsContext(traits.get()); + camera->setGraphicsContext(gc); camera->setDrawBuffer(GL_FRONT); camera->setViewport(new osg::Viewport(0, 0, width, height)); - + viewer.setSceneData(sceneGraph); - + viewer.setCameraManipulator(new osgGA::TrackballManipulator()); viewer.getCamera()->setClearColor(osg::Vec4f(1.0f,1.0f,1.0f,1.0f)); viewer.getCamera()->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - + double zoom = 1; CAST_PARAM(req.params, zoom, "zoom", double); - + viewer.getCameraManipulator()->setByMatrix(osg::Matrix::lookAt(osg::Vec3d(0,0,bs.radius() * (-3.4 * zoom)), // eye - (osg::Vec3d)bs.center(), // center - osg::Vec3d(0,1,0))); // up - + (osg::Vec3d)bs.center(), // center + osg::Vec3d(0,1,0))); // up + osg::Image *image = new osg::Image(); camera->attach(osg::Camera::COLOR_BUFFER0, image); - + viewer.setThreadingModel(osgViewer::Viewer::SingleThreaded); viewer.realize(); viewer.frame(); - + std::string tempFile = URL::getTmpFilename(format); - + if (!osgDB::writeImageFile(*image, tempFile)) { LOG(ERROR) << "Could write image file at " << tempFile; return; } - + // read file into buffer char* buffer = NULL; size_t length = 0; { std::ifstream file(tempFile.c_str()); - + file.seekg(0, std::ios::end); length = file.tellg(); file.seekg(0, std::ios::beg); buffer = (char*)malloc(length); file.read(buffer, length); } - + retContent.compound[format] = Data(buffer, length, URL::getMimeType(format), false); } - + if (retContent.compound.size()) { reportSuccess(req, retContent); } else { @@ -389,11 +389,11 @@ void OSGConverter::reportSuccess(const SendRequest& req, const Data& content) { // Data foo = paramIter->second; // std::cout << paramIter->first << " = " << foo << std::endl; // } - + if (event.name.length() == 0) event.name = "convert"; event.name += ".success"; - + if (content) event.data.compound["content"] = content; returnEvent(event); diff --git a/src/uscxml/plugins/invoker/miles/MilesSessionInvoker.cpp b/src/uscxml/plugins/invoker/miles/MilesSessionInvoker.cpp index 6667017..a004a66 100644 --- a/src/uscxml/plugins/invoker/miles/MilesSessionInvoker.cpp +++ b/src/uscxml/plugins/invoker/miles/MilesSessionInvoker.cpp @@ -30,6 +30,10 @@ #include #include /* srand, rand */ +#ifdef _WIN32 +#define strdup _strdup +#endif + namespace uscxml { #ifdef BUILD_AS_PLUGINS @@ -304,15 +308,15 @@ void MilesSessionInvoker::processEventStart(const std::string& origin, const std /* Set up audio and video RTP sockets */ video_rtp_in_socket = miles_net_setup_udp_socket((char*)reflector.c_str(), video_port, video_port, 10, 16000); audio_rtp_in_socket = miles_net_setup_udp_socket((char*)reflector.c_str(), audio_port, audio_port, 10, 16000); - video_rtp_out_socket = video_rtp_in_socket; - audio_rtp_out_socket = audio_rtp_in_socket; + video_rtp_out_socket = video_rtp_in_socket; + audio_rtp_out_socket = audio_rtp_in_socket; /* Set up audio and video RTCP sockets */ video_rtcp_in_socket = miles_net_setup_udp_socket((char*)reflector.c_str(), video_port+1, video_port+1, 10, 16000); audio_rtcp_in_socket = miles_net_setup_udp_socket((char*)reflector.c_str(), audio_port+1, audio_port+1, 10, 16000); video_rtcp_out_socket = video_rtcp_in_socket; - audio_rtcp_out_socket = audio_rtcp_in_socket; + audio_rtcp_out_socket = audio_rtcp_in_socket; /* Set up RTP audio and video sessions */ video_session = miles_rtp_setup_session(video_rtp_in_socket, MILES_RTP_MEDIA_TYPE_VIDEO); @@ -357,7 +361,7 @@ void MilesSessionInvoker::processEventStart(const std::string& origin, const std } /* Register RTCP APP handler for text messages */ - rv = miles_rtp_register_rtcp_app_handler("text", NULL, receive_text_message_callback, 0); + rv = miles_rtp_register_rtcp_app_handler("text", NULL, receive_text_message_callback, 0); if(rv==0) { LOG(ERROR) << "Error registering text message callback"; } @@ -400,7 +404,7 @@ void MilesSessionInvoker::processEventStop(const std::string& origin) { return; } /* Unregister RTCP APP handler for text messages */ - rv = miles_rtp_unregister_rtcp_app_handler("text"); + rv = miles_rtp_unregister_rtcp_app_handler("text"); if(rv==0) { LOG(ERROR) << "Error registering text message callback"; } @@ -466,7 +470,7 @@ void MilesSessionInvoker::processEventThumbnail(const std::string& origin, const use_thumb = te; } p = p->next; - } + } if(!p && use_thumb) use_thumb->userid = strdup(userid.c_str()); if(use_thumb) { @@ -568,7 +572,7 @@ void MilesSessionInvoker::processEventGetText(const std::string& origin) { returnEvent(ev); return; } - + ev.name = "gettext.reply"; if(confero_text_msg_available) { strcpy(text_msg_buf, confero_text_msg_buf); @@ -578,7 +582,7 @@ void MilesSessionInvoker::processEventGetText(const std::string& origin) { memset(confero_text_msg_buf, 0, 1000); confero_text_msg_available = 0; } - + returnEvent(ev); } @@ -640,7 +644,7 @@ void MilesSessionInvoker::processAudio() { int MilesSessionInvoker::setup_audio() { /* Check that we have OpeanAL audio */ if(!miles_audio_io_is_supported(MILES_AUDIO_IO_OPENAL)) { - fprintf(stderr, "OpenAL audio i/o not supported on this platform.\n"); + fprintf(stderr, "OpenAL audio i/o not supported on this platform.\n"); return 0; } @@ -730,7 +734,7 @@ int MilesSessionInvoker::setup_video_grabber() { video_grabber->height = 240; video_grabber->frame_rate = 25*100; /* Select first supported image format */ - struct miles_video_grabber_device *dev; + struct miles_video_grabber_device *dev; dev = (struct miles_video_grabber_device *)grabber_description->devices->item; struct miles_int_struct *img_format; img_format = (struct miles_int_struct *)dev->capabilities->formats->item; diff --git a/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp b/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp index 6632dc1..865db13 100644 --- a/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp +++ b/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp @@ -207,7 +207,7 @@ void BasicHTTPIOProcessor::send(const SendRequest& req) { targetURL.setOutContent(kvps.str()); // targetURL.addOutHeader("Content-Type", "application/x-www-form-urlencoded"); - + targetURL.setRequestType("post"); targetURL.addMonitor(this); diff --git a/src/uscxml/server/HTTPServer.cpp b/src/uscxml/server/HTTPServer.cpp index 04a831e..2258ab0 100644 --- a/src/uscxml/server/HTTPServer.cpp +++ b/src/uscxml/server/HTTPServer.cpp @@ -76,7 +76,7 @@ HTTPServer::HTTPServer(unsigned short port, unsigned short wsPort, SSLConfig* ss _thread = NULL; _httpHandle = NULL; _wsHandle = NULL; - + determineAddress(); unsigned int allowedMethods = @@ -91,12 +91,12 @@ HTTPServer::HTTPServer(unsigned short port, unsigned short wsPort, SSLConfig* ss EVHTTP_REQ_PATCH; evhttp_set_allowed_methods(_http, allowedMethods); // allow all methods - + if (_port > 0) _httpHandle = evhttp_bind_socket_with_handle(_http, INADDR_ANY, _port); if (_httpHandle) LOG(INFO) << "HTTP server listening on tcp/" << _port; - + _wsPort = wsPort; if (_wsPort > 0) _wsHandle = evws_bind_socket(_evws, _wsPort); @@ -186,42 +186,42 @@ void HTTPServer::wsRecvReqCallback(struct evws_connection *conn, struct evws_fra wsFrame.evwsConn = conn; struct evws_header *header; - TAILQ_FOREACH(header, &conn->headers, next) { + for (header = conn->headers.tqh_first; header; header = header->next.tqe_next) { wsFrame.data.compound["header"].compound[header->key] = Data(header->value, Data::VERBATIM); } switch (frame->opcode) { - case EVWS_CONTINUATION_FRAME: - wsFrame.data.compound["type"] = Data("continuation", Data::VERBATIM); - wsFrame.data.compound["content"] = Data(std::string(frame->data, frame->size), Data::VERBATIM); - break; - case EVWS_TEXT_FRAME: - wsFrame.data.compound["type"] = Data("text", Data::VERBATIM); - wsFrame.data.compound["content"] = Data(std::string(frame->data, frame->size), Data::VERBATIM); - break; - case EVWS_BINARY_FRAME: - wsFrame.data.compound["type"] = Data("binary", Data::VERBATIM); - wsFrame.data.compound["content"] = Data(frame->data, frame->size, "application/octet-stream"); - break; - case EVWS_CONNECTION_CLOSE: - wsFrame.data.compound["type"] = Data("close", Data::VERBATIM); - break; - case EVWS_PING: - wsFrame.data.compound["type"] = Data("ping", Data::VERBATIM); - break; - case EVWS_PONG: - wsFrame.data.compound["type"] = Data("ping", Data::VERBATIM); - break; + case EVWS_CONTINUATION_FRAME: + wsFrame.data.compound["type"] = Data("continuation", Data::VERBATIM); + wsFrame.data.compound["content"] = Data(std::string(frame->data, frame->size), Data::VERBATIM); + break; + case EVWS_TEXT_FRAME: + wsFrame.data.compound["type"] = Data("text", Data::VERBATIM); + wsFrame.data.compound["content"] = Data(std::string(frame->data, frame->size), Data::VERBATIM); + break; + case EVWS_BINARY_FRAME: + wsFrame.data.compound["type"] = Data("binary", Data::VERBATIM); + wsFrame.data.compound["content"] = Data(frame->data, frame->size, "application/octet-stream"); + break; + case EVWS_CONNECTION_CLOSE: + wsFrame.data.compound["type"] = Data("close", Data::VERBATIM); + break; + case EVWS_PING: + wsFrame.data.compound["type"] = Data("ping", Data::VERBATIM); + break; + case EVWS_PONG: + wsFrame.data.compound["type"] = Data("ping", Data::VERBATIM); + break; } wsFrame.data.compound["uri"] = Data(HTTPServer::getBaseURL(WebSockets) + conn->uri, Data::VERBATIM); wsFrame.data.compound["path"] = Data(conn->uri, Data::VERBATIM); - + // try with the handler registered for path first bool answered = false; if (callbackData != NULL) answered = ((WebSocketServlet*)callbackData)->wsRecvRequest(conn, wsFrame); - + if (!answered) HTTPServer::getInstance()->processByMatchingServlet(conn, wsFrame); @@ -246,7 +246,7 @@ void HTTPServer::httpRecvReqCallback(struct evhttp_request *req, void *callbackD } } #endif - + evhttp_request_own(req); Request request; request.evhttpReq = req; @@ -393,7 +393,7 @@ void HTTPServer::httpRecvReqCallback(struct evhttp_request *req, void *callbackD } } } - + request.raw = raw.str(); // try with the handler registered for path first @@ -439,22 +439,22 @@ void HTTPServer::processByMatchingServlet(const Request& request) { void HTTPServer::processByMatchingServlet(evws_connection* conn, const WSFrame& frame) { tthread::lock_guard lock(_mutex); - + ws_servlet_iter_t servletIter = _wsServlets.begin(); - + std::string actualPath = frame.data.compound.at("path").atom; std::map matches; - + while(servletIter != _wsServlets.end()) { // is the servlet path a prefix of the actual path? std::string servletPath = "/" + servletIter->first; if (iequals(actualPath.substr(0, servletPath.length()), servletPath) && // servlet path is a prefix - iequals(actualPath.substr(servletPath.length(), 1), "/")) { // and next character is a '/' + iequals(actualPath.substr(servletPath.length(), 1), "/")) { // and next character is a '/' matches.insert(std::make_pair(servletPath, servletIter->second)); } servletIter++; } - + // process by best matching servlet until someone feels responsible std::map::iterator matchesIter = matches.begin(); while(matchesIter != matches.end()) { @@ -544,7 +544,7 @@ bool HTTPServer::registerServlet(const std::string& path, HTTPServlet* servlet) bool HTTPServer::registerServlet(const std::string& path, WebSocketServlet* servlet) { HTTPServer* INSTANCE = getInstance(); tthread::lock_guard lock(INSTANCE->_mutex); - + // remove trailing and leading slash std::string actualPath = path; if (boost::ends_with(actualPath, "/")) @@ -552,7 +552,7 @@ bool HTTPServer::registerServlet(const std::string& path, WebSocketServlet* serv if (boost::starts_with(actualPath, "/")) actualPath = actualPath.substr(1); std::string suffixedPath = actualPath; - + // if this servlet allows to adapt the path, do so int i = 2; while(INSTANCE->_wsServlets.find(suffixedPath) != INSTANCE->_wsServlets.end()) { @@ -562,15 +562,15 @@ bool HTTPServer::registerServlet(const std::string& path, WebSocketServlet* serv ss << actualPath << i++; suffixedPath = ss.str(); } - + std::stringstream servletURL; servletURL << "ws://" << INSTANCE->_address << ":" << INSTANCE->_wsPort << "/" << suffixedPath; servlet->setURL(servletURL.str()); - + INSTANCE->_wsServlets[suffixedPath] = servlet; - + // LOG(INFO) << "HTTP Servlet listening at: " << servletURL.str() << std::endl; - + // register callback evws_set_cb(INSTANCE->_evws, ("/" + suffixedPath).c_str(), HTTPServer::wsRecvReqCallback, NULL, servlet); @@ -582,15 +582,19 @@ std::string HTTPServer::getBaseURL(ServerType type) { std::stringstream servletURL; switch (type) { - case HTTP: - servletURL << "http://" << INSTANCE->_address << ":" << INSTANCE->_port; - break; - case HTTPS: - servletURL << "https://" << INSTANCE->_address << ":" << INSTANCE->_sslPort; - break; - case WebSockets: - servletURL << "ws://" << INSTANCE->_address << ":" << INSTANCE->_wsPort; - break; + case HTTP: + servletURL << "http://" << INSTANCE->_address << ":" << INSTANCE->_port; + break; +#if (defined EVENT_SSL_FOUND && defined OPENSSL_FOUND && defined OPENSSL_HAS_ELIPTIC_CURVES) + case HTTPS: + servletURL << "https://" << INSTANCE->_address << ":" << INSTANCE->_sslPort; + break; +#endif + case WebSockets: + servletURL << "ws://" << INSTANCE->_address << ":" << INSTANCE->_wsPort; + break; + default: + break; } return servletURL.str(); } @@ -628,84 +632,84 @@ void HTTPServer::determineAddress() { _address = std::string(hostname); } - + #if (defined EVENT_SSL_FOUND && defined OPENSSL_FOUND && defined OPENSSL_HAS_ELIPTIC_CURVES) - // see https://github.com/ppelleti/https-example/blob/master/https-server.c - struct bufferevent* HTTPServer::sslBufferEventCallback(struct event_base *base, void *arg) { - struct bufferevent* r; - SSL_CTX *ctx = (SSL_CTX *) arg; - r = bufferevent_openssl_socket_new (base, - -1, - SSL_new (ctx), - BUFFEREVENT_SSL_ACCEPTING, - BEV_OPT_CLOSE_ON_FREE); - return r; +// see https://github.com/ppelleti/https-example/blob/master/https-server.c +struct bufferevent* HTTPServer::sslBufferEventCallback(struct event_base *base, void *arg) { + struct bufferevent* r; + SSL_CTX *ctx = (SSL_CTX *) arg; + r = bufferevent_openssl_socket_new (base, + -1, + SSL_new (ctx), + BUFFEREVENT_SSL_ACCEPTING, + BEV_OPT_CLOSE_ON_FREE); + return r; +} + + +void HTTPServer::sslGeneralBufferEventCallback (struct evhttp_request *req, void *arg) { + struct evbuffer *evb = NULL; + const char *uri = evhttp_request_get_uri (req); + struct evhttp_uri *decoded = NULL; + + /* We only handle POST requests. */ + if (evhttp_request_get_command (req) != EVHTTP_REQ_POST) { + evhttp_send_reply (req, 200, "OK", NULL); + return; } - - - void HTTPServer::sslGeneralBufferEventCallback (struct evhttp_request *req, void *arg) { - struct evbuffer *evb = NULL; - const char *uri = evhttp_request_get_uri (req); - struct evhttp_uri *decoded = NULL; - - /* We only handle POST requests. */ - if (evhttp_request_get_command (req) != EVHTTP_REQ_POST) { - evhttp_send_reply (req, 200, "OK", NULL); - return; - } - - printf ("Got a POST request for <%s>\n", uri); - - /* Decode the URI */ - decoded = evhttp_uri_parse (uri); - if (! decoded) { - printf ("It's not a good URI. Sending BADREQUEST\n"); - evhttp_send_error (req, HTTP_BADREQUEST, 0); - return; - } - - /* Decode the payload */ - struct evkeyvalq kv; - memset (&kv, 0, sizeof (kv)); - struct evbuffer *buf = evhttp_request_get_input_buffer (req); - evbuffer_add (buf, "", 1); /* NUL-terminate the buffer */ - char *payload = (char *) evbuffer_pullup (buf, -1); - if (0 != evhttp_parse_query_str (payload, &kv)) { - printf ("Malformed payload. Sending BADREQUEST\n"); - evhttp_send_error (req, HTTP_BADREQUEST, 0); - return; - } - - /* Determine peer */ - char *peer_addr; - ev_uint16_t peer_port; - struct evhttp_connection *con = evhttp_request_get_connection (req); - evhttp_connection_get_peer (con, &peer_addr, &peer_port); - - /* Extract passcode */ - const char *passcode = evhttp_find_header (&kv, "passcode"); - char response[256]; - evutil_snprintf (response, sizeof (response), - "Hi %s! I %s your passcode.\n", peer_addr, - (0 == strcmp (passcode, "R23") - ? "liked" - : "didn't like")); - evhttp_clear_headers (&kv); /* to free memory held by kv */ - - /* This holds the content we're sending. */ - evb = evbuffer_new (); - - evhttp_add_header (evhttp_request_get_output_headers (req), - "Content-Type", "application/x-yaml"); - evbuffer_add (evb, response, strlen (response)); - - evhttp_send_reply (req, 200, "OK", evb); - - if (decoded) - evhttp_uri_free (decoded); - if (evb) - evbuffer_free (evb); + + printf ("Got a POST request for <%s>\n", uri); + + /* Decode the URI */ + decoded = evhttp_uri_parse (uri); + if (! decoded) { + printf ("It's not a good URI. Sending BADREQUEST\n"); + evhttp_send_error (req, HTTP_BADREQUEST, 0); + return; } + + /* Decode the payload */ + struct evkeyvalq kv; + memset (&kv, 0, sizeof (kv)); + struct evbuffer *buf = evhttp_request_get_input_buffer (req); + evbuffer_add (buf, "", 1); /* NUL-terminate the buffer */ + char *payload = (char *) evbuffer_pullup (buf, -1); + if (0 != evhttp_parse_query_str (payload, &kv)) { + printf ("Malformed payload. Sending BADREQUEST\n"); + evhttp_send_error (req, HTTP_BADREQUEST, 0); + return; + } + + /* Determine peer */ + char *peer_addr; + ev_uint16_t peer_port; + struct evhttp_connection *con = evhttp_request_get_connection (req); + evhttp_connection_get_peer (con, &peer_addr, &peer_port); + + /* Extract passcode */ + const char *passcode = evhttp_find_header (&kv, "passcode"); + char response[256]; + evutil_snprintf (response, sizeof (response), + "Hi %s! I %s your passcode.\n", peer_addr, + (0 == strcmp (passcode, "R23") + ? "liked" + : "didn't like")); + evhttp_clear_headers (&kv); /* to free memory held by kv */ + + /* This holds the content we're sending. */ + evb = evbuffer_new (); + + evhttp_add_header (evhttp_request_get_output_headers (req), + "Content-Type", "application/x-yaml"); + evbuffer_add (evb, response, strlen (response)); + + evhttp_send_reply (req, 200, "OK", evb); + + if (decoded) + evhttp_uri_free (decoded); + if (evb) + evbuffer_free (evb); +} #endif } \ No newline at end of file diff --git a/src/uscxml/server/HTTPServer.h b/src/uscxml/server/HTTPServer.h index 6f3c792..7083a3c 100644 --- a/src/uscxml/server/HTTPServer.h +++ b/src/uscxml/server/HTTPServer.h @@ -40,7 +40,7 @@ namespace uscxml { class HTTPServlet; class WebSocketServlet; - + class USCXML_API HTTPServer { public: class Request : public Event { @@ -60,7 +60,7 @@ public: std::string content; struct evws_connection* evwsConn; }; - + class SSLConfig { public: SSLConfig() : port(8443) {} @@ -85,11 +85,11 @@ public: }; enum ServerType { - HTTPS, - HTTP, - WebSockets + HTTPS, + HTTP, + WebSockets }; - + static HTTPServer* getInstance(unsigned short port, unsigned short wsPort, SSLConfig* sslConf = NULL); static HTTPServer* getInstance() { return getInstance(0, 0, NULL); @@ -140,10 +140,10 @@ private: struct event_base* _base; struct evhttp* _http; struct evws* _evws; - + struct evhttp_bound_socket* _httpHandle; evutil_socket_t _wsHandle; - + unsigned short _port; unsigned short _wsPort; std::string _address; diff --git a/src/uscxml/server/InterpreterServlet.cpp b/src/uscxml/server/InterpreterServlet.cpp index 8218669..01c8f07 100644 --- a/src/uscxml/server/InterpreterServlet.cpp +++ b/src/uscxml/server/InterpreterServlet.cpp @@ -85,11 +85,11 @@ void InterpreterHTTPServlet::send(const SendRequest& req) { LOG(ERROR) << "send not supported by http iorprocessor, use the fetch element"; } - - + + InterpreterWebSocketServlet::InterpreterWebSocketServlet(InterpreterImpl* interpreter) { _interpreter = interpreter; - + std::stringstream path; path << _interpreter->getName(); int i = 2; @@ -109,16 +109,16 @@ boost::shared_ptr InterpreterWebSocketServlet::create(Interpret bool InterpreterWebSocketServlet::wsRecvRequest(struct evws_connection *conn, const HTTPServer::WSFrame& frame) { tthread::lock_guard lock(_mutex); - + // evhttp_request_own(req.curlReq); - + _requests[toStr((uintptr_t)conn)] = conn; - + Event event = frame; - + event.name = "ws." + event.data.compound["type"].atom; event.origin = toStr((uintptr_t)conn); - + if (event.data.compound["type"].atom.compare("text") == 0 && event.data.compound["content"]) { if (event.data.compound["content"].compound.size() > 0) { std::map::iterator compoundIter = event.data.compound["content"].compound.begin(); @@ -131,7 +131,7 @@ bool InterpreterWebSocketServlet::wsRecvRequest(struct evws_connection *conn, co } } } - + _interpreter->receive(event); return true; } @@ -155,23 +155,23 @@ void InterpreterWebSocketServlet::send(const SendRequest& req) { if (false) { } else if (req.data.binary) { evws_send_data(_requests[req.target], - EVWS_BINARY_FRAME, - req.data.binary->data, - req.data.binary->size); + EVWS_BINARY_FRAME, + req.data.binary->data, + req.data.binary->size); } else if (req.data.node) { std::stringstream ssXML; ssXML << req.data.node; std::string data = ssXML.str(); evws_send_data(_requests[req.target], - EVWS_TEXT_FRAME, - data.c_str(), - data.length()); + EVWS_TEXT_FRAME, + data.c_str(), + data.length()); } else if (req.data) { std::string data = Data::toJSON(req.data); evws_send_data(_requests[req.target], - EVWS_TEXT_FRAME, - data.c_str(), - data.length()); + EVWS_TEXT_FRAME, + data.c_str(), + data.length()); } else { LOG(WARNING) << "Not sure what to make off content given to send on websocket!"; } @@ -180,23 +180,23 @@ void InterpreterWebSocketServlet::send(const SendRequest& req) { if (false) { } else if (req.data.binary) { evws_broadcast(getWSBase(), req.target.c_str(), - EVWS_BINARY_FRAME, - req.data.binary->data, - req.data.binary->size); + EVWS_BINARY_FRAME, + req.data.binary->data, + req.data.binary->size); } else if (req.data.node) { std::stringstream ssXML; ssXML << req.data.node; std::string data = ssXML.str(); evws_broadcast(getWSBase(), req.target.c_str(), - EVWS_TEXT_FRAME, - data.c_str(), - data.length()); + EVWS_TEXT_FRAME, + data.c_str(), + data.length()); } else if (req.data) { std::string data = Data::toJSON(req.data); evws_broadcast(getWSBase(), req.target.c_str(), - EVWS_TEXT_FRAME, - data.c_str(), - data.length()); + EVWS_TEXT_FRAME, + data.c_str(), + data.length()); } else { LOG(WARNING) << "Not sure what to make off content given to broadcast on websocket!"; } diff --git a/src/uscxml/server/InterpreterServlet.h b/src/uscxml/server/InterpreterServlet.h index 46cc737..0315598 100644 --- a/src/uscxml/server/InterpreterServlet.h +++ b/src/uscxml/server/InterpreterServlet.h @@ -83,21 +83,21 @@ public: InterpreterWebSocketServlet() {}; InterpreterWebSocketServlet(InterpreterImpl* interpreter); virtual ~InterpreterWebSocketServlet() {} - + virtual boost::shared_ptr create(InterpreterImpl* interpreter); - + virtual std::set getNames() { std::set names; names.insert("websocket"); names.insert("http://www.w3.org/TR/scxml/#WebSocketEventProcessor"); return names; } - + Data getDataModelVariables(); virtual void send(const SendRequest& req); - + virtual bool wsRecvRequest(struct evws_connection *conn, const HTTPServer::WSFrame& frame); - + std::string getPath() { return _path; } @@ -117,15 +117,15 @@ public: tthread::recursive_mutex& getMutex() { return _mutex; } - + protected: InterpreterImpl* _interpreter; - + tthread::recursive_mutex _mutex; std::map _requests; std::string _path; std::string _url; - + }; } diff --git a/src/uscxml/util/Base64.h b/src/uscxml/util/Base64.h index 3bd4c6c..7dfc83c 100644 --- a/src/uscxml/util/Base64.h +++ b/src/uscxml/util/Base64.h @@ -8,50 +8,58 @@ For details, see http://sourceforge.net/projects/libb64 #ifndef BASE64_H_MMR5NHB7 #define BASE64_H_MMR5NHB7 +#if defined(_WIN32) && !defined(USCXML_STATIC) +# ifdef USCXML_EXPORT +# define USCXML_API __declspec(dllexport) +# else +# define USCXML_API __declspec(dllimport) +# endif +#else +# define USCXML_API +#endif + #ifdef __cplusplus extern "C" { #endif /// DECODE -typedef enum -{ - step_a, step_b, step_c, step_d -} base64_decodestep; + typedef enum + { + step_a, step_b, step_c, step_d + } + base64_decodestep; -typedef struct -{ - base64_decodestep step; - char plainchar; -} base64_decodestate; + typedef struct { + base64_decodestep step; + char plainchar; + } base64_decodestate; -void base64_init_decodestate(base64_decodestate* state_in); + USCXML_API void base64_init_decodestate(base64_decodestate* state_in); -int base64_decode_value(char value_in); + USCXML_API int base64_decode_value(char value_in); -int base64_decode_block(const char* code_in, const int length_in, char* plaintext_out, base64_decodestate* state_in); + USCXML_API int base64_decode_block(const char* code_in, const int length_in, char* plaintext_out, base64_decodestate* state_in); /// ENDCODE -typedef enum -{ - step_A, step_B, step_C -} base64_encodestep; + typedef enum { + step_A, step_B, step_C + } base64_encodestep; -typedef struct -{ - base64_encodestep step; - char result; - int stepcount; -} base64_encodestate; + typedef struct { + base64_encodestep step; + char result; + int stepcount; + } base64_encodestate; -void base64_init_encodestate(base64_encodestate* state_in); + USCXML_API void base64_init_encodestate(base64_encodestate* state_in); -char base64_encode_value(char value_in); + USCXML_API char base64_encode_value(char value_in); -int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in); + USCXML_API int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in); -int base64_encode_blockend(char* code_out, base64_encodestate* state_in); + USCXML_API int base64_encode_blockend(char* code_out, base64_encodestate* state_in); #ifdef __cplusplus } diff --git a/src/uscxml/util/MD5.h b/src/uscxml/util/MD5.h index a3468d9..840c704 100644 --- a/src/uscxml/util/MD5.h +++ b/src/uscxml/util/MD5.h @@ -50,39 +50,49 @@ #ifndef md5_INCLUDED # define md5_INCLUDED +#if defined(_WIN32) && !defined(USCXML_STATIC) +# ifdef USCXML_EXPORT +# define USCXML_API __declspec(dllexport) +# else +# define USCXML_API __declspec(dllimport) +# endif +#else +# define USCXML_API +#endif + #ifdef __cplusplus extern "C" { #endif -/* - * This package supports both compile-time and run-time determination of CPU - * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be - * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is - * defined as non-zero, the code will be compiled to run only on big-endian - * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to - * run on either big- or little-endian CPUs, but will run slightly less - * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined. - */ + /* + * This package supports both compile-time and run-time determination of CPU + * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be + * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is + * defined as non-zero, the code will be compiled to run only on big-endian + * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to + * run on either big- or little-endian CPUs, but will run slightly less + * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined. + */ -typedef unsigned char md5_byte_t; /* 8-bit byte */ -typedef unsigned int md5_word_t; /* 32-bit word */ + typedef unsigned char md5_byte_t; /* 8-bit byte */ + typedef unsigned int md5_word_t; /* 32-bit word */ -/* Define the state of the MD5 Algorithm. */ -typedef struct md5_state_s { - md5_word_t count[2]; /* message length in bits, lsw first */ - md5_word_t abcd[4]; /* digest buffer */ - md5_byte_t buf[64]; /* accumulate block */ -} md5_state_t; + /* Define the state of the MD5 Algorithm. */ + typedef struct md5_state_s { + md5_word_t count[2]; /* message length in bits, lsw first */ + md5_word_t abcd[4]; /* digest buffer */ + md5_byte_t buf[64]; /* accumulate block */ + } md5_state_t; /* Initialize the algorithm. */ - void md5_init(md5_state_t *pms); + USCXML_API void md5_init(md5_state_t *pms); /* Append a string to the message. */ - void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes); + USCXML_API void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes); /* Finish the message and return the digest. */ - void md5_finish(md5_state_t *pms, md5_byte_t digest[16]); + USCXML_API void md5_finish(md5_state_t *pms, md5_byte_t digest[16]); #ifdef __cplusplus } /* end extern "C" */ diff --git a/src/uscxml/util/SHA1.h b/src/uscxml/util/SHA1.h old mode 100755 new mode 100644 index 2b1f466..f9baa5b --- a/src/uscxml/util/SHA1.h +++ b/src/uscxml/util/SHA1.h @@ -5,13 +5,13 @@ Freeware Public License (FPL) This software is licensed as "freeware." Permission to distribute - this software in source and binary forms, including incorporation - into other products, is hereby granted without a fee. THIS SOFTWARE - IS PROVIDED 'AS IS' AND WITHOUT ANY EXPRESSED OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHOR SHALL NOT BE HELD - LIABLE FOR ANY DAMAGES RESULTING FROM THE USE OF THIS SOFTWARE, EITHER - DIRECTLY OR INDIRECTLY, INCLUDING, BUT NOT LIMITED TO, LOSS OF DATA + this software in source and binary forms, including incorporation + into other products, is hereby granted without a fee. THIS SOFTWARE + IS PROVIDED 'AS IS' AND WITHOUT ANY EXPRESSED OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHOR SHALL NOT BE HELD + LIABLE FOR ANY DAMAGES RESULTING FROM THE USE OF THIS SOFTWARE, EITHER + DIRECTLY OR INDIRECTLY, INCLUDING, BUT NOT LIMITED TO, LOSS OF DATA OR DATA BEING RENDERED INACCURATE. */ @@ -41,36 +41,45 @@ #ifndef _SHA1_H_ #define _SHA1_H_ +#if defined(_WIN32) && !defined(USCXML_STATIC) +# ifdef USCXML_EXPORT +# define USCXML_API __declspec(dllexport) +# else +# define USCXML_API __declspec(dllimport) +# endif +#else +# define USCXML_API +#endif + #ifdef __cplusplus extern "C" { #endif -/* - * This structure will hold context information for the hashing - * operation - */ -typedef struct SHA1Context -{ - unsigned Message_Digest[5]; /* Message Digest (output) */ + /* + * This structure will hold context information for the hashing + * operation + */ + typedef struct SHA1Context { + unsigned Message_Digest[5]; /* Message Digest (output) */ - unsigned Length_Low; /* Message length in bits */ - unsigned Length_High; /* Message length in bits */ + unsigned Length_Low; /* Message length in bits */ + unsigned Length_High; /* Message length in bits */ - unsigned char Message_Block[64]; /* 512-bit message blocks */ - int Message_Block_Index; /* Index into message block array */ + unsigned char Message_Block[64]; /* 512-bit message blocks */ + int Message_Block_Index; /* Index into message block array */ - int Computed; /* Is the digest computed? */ - int Corrupted; /* Is the message digest corruped? */ -} SHA1Context; + int Computed; /* Is the digest computed? */ + int Corrupted; /* Is the message digest corruped? */ + } SHA1Context; -/* - * Function Prototypes - */ -void SHA1Reset(SHA1Context *); -int SHA1Result(SHA1Context *); -void SHA1Input(SHA1Context *, - const unsigned char *, - unsigned); + /* + * Function Prototypes + */ + USCXML_API void SHA1Reset(SHA1Context *); + USCXML_API int SHA1Result(SHA1Context *); + USCXML_API void SHA1Input(SHA1Context *, + const unsigned char *, + unsigned); #ifdef __cplusplus } -- cgit v0.12