From a68b6c1d31cb94675dd4dda0a2da11d8e83063c3 Mon Sep 17 00:00:00 2001 From: Stefan Radomski Date: Mon, 28 Oct 2013 18:26:38 +0100 Subject: Bug fixes (see details) - No more 100-continue HTTP header - Correctly delegate HTTP requests - More elaborate expressions when communicating via HTTP - Fixed off-by-one in JSCNodeSet --- CMakeLists.txt | 5 ++- apps/samples/put-that-there/put-that-there.scxml | 44 +++++++++++++++++++++- src/uscxml/Interpreter.cpp | 10 +++-- src/uscxml/Interpreter.h | 4 +- src/uscxml/Message.h | 2 +- src/uscxml/URL.cpp | 12 +++++- .../JavaScriptCore/dom/JSCNodeSetCustom.cpp | 2 +- .../invoker/graphics/openscenegraph/OSGInvoker.cpp | 2 +- .../ioprocessor/basichttp/BasicHTTPIOProcessor.cpp | 30 +++++++++++---- src/uscxml/server/HTTPServer.cpp | 2 +- src/uscxml/server/HTTPServer.h | 4 +- 11 files changed, 94 insertions(+), 23 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ef32b01..768b8f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,7 +65,7 @@ if (APPLE) OUTPUT_STRIP_TRAILING_WHITESPACE) if (MACOSX_VERSION) THREE_PART_VERSION_TO_VARS( - "10.8" + ${MACOSX_VERSION} MACOSX_VERSION_MAJOR MACOSX_VERSION_MINOR MACOSX_VERSION_PATCH) @@ -381,7 +381,8 @@ endif() set(CMAKE_COMPILER_STRING "${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}") # see http://www.mail-archive.com/cmake@cmake.org/msg23240.html -if (APPLE) +if (APPLE AND MACOSX_VERSION VERSION_LESS "10.9") + # figure out what to do with Mavericks (10.9) later # add_definitions("-D_DARWIN_UNLIMITED_SELECT") # set(CMAKE_OSX_ARCHITECTURES "x86_64;i386") # support leopard and above diff --git a/apps/samples/put-that-there/put-that-there.scxml b/apps/samples/put-that-there/put-that-there.scxml index b608972..43a6b37 100644 --- a/apps/samples/put-that-there/put-that-there.scxml +++ b/apps/samples/put-that-there/put-that-there.scxml @@ -1,6 +1,7 @@ - + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp index b7a9d33..bb54c6f 100644 --- a/src/uscxml/Interpreter.cpp +++ b/src/uscxml/Interpreter.cpp @@ -917,7 +917,7 @@ void InterpreterImpl::send(const Arabica::DOM::Node& element) { processContentElement(contents[0], sendReq.dom, sendReq.content, expr); if (expr.length() > 0 && _dataModel) { try { - sendReq.content =_dataModel.evalAsString(expr); + sendReq.data = _dataModel.getStringAsData(expr); } catch (Event e) { e.name = "error.execution"; receiveInternal(e); @@ -1055,7 +1055,7 @@ void InterpreterImpl::invoke(const Arabica::DOM::Node& element) { processContentElement(contents[0], invokeReq.dom, invokeReq.content, expr); if (expr.length() > 0 && _dataModel) { try { - invokeReq.content =_dataModel.evalAsString(expr); + invokeReq.data =_dataModel.getStringAsData(expr); } catch (Event e) { e.name = "error.execution"; receiveInternal(e); @@ -1749,8 +1749,10 @@ NodeSet InterpreterImpl::filterChildElements(const std::string& tag NodeSet filteredChildElems; NodeList childs = node.getChildNodes(); for (unsigned int i = 0; i < childs.getLength(); i++) { - if (childs.item(i).getNodeType() != Node_base::ELEMENT_NODE || - !iequals(TAGNAME(childs.item(i)), tagName)) + if (childs.item(i).getNodeType() != Node_base::ELEMENT_NODE) + continue; +// std::cout << tagName << " vs " << TAGNAME(childs.item(i)) << std::endl; + if (!iequals(TAGNAME(childs.item(i)), tagName)) continue; filteredChildElems.push_back(childs.item(i)); } diff --git a/src/uscxml/Interpreter.h b/src/uscxml/Interpreter.h index eaedeb1..ac26457 100644 --- a/src/uscxml/Interpreter.h +++ b/src/uscxml/Interpreter.h @@ -190,8 +190,8 @@ public: return _nsContext; } std::string getXMLPrefixForNS(const std::string& ns) { - if (_nsToPrefix.find(ns) != _nsToPrefix.end()) - return _nsToPrefix[ns] + ":"; + if (_nameSpaceInfo.find(ns) != _nameSpaceInfo.end() && _nameSpaceInfo[ns].size()) + return _nameSpaceInfo[ns] + ":"; return ""; } void setNameSpaceInfo(const std::map nameSpaceInfo); diff --git a/src/uscxml/Message.h b/src/uscxml/Message.h index 719db63..4aba5ed 100644 --- a/src/uscxml/Message.h +++ b/src/uscxml/Message.h @@ -94,7 +94,7 @@ public: virtual ~Data() {} operator bool() const { - return (atom.length() > 0 || !compound.empty() || !array.empty() || binary); + return (atom.length() > 0 || !compound.empty() || !array.empty() || binary || node); } bool hasKey(const std::string& key) const { diff --git a/src/uscxml/URL.cpp b/src/uscxml/URL.cpp index 9721562..6ebd9a6 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); @@ -582,6 +582,12 @@ void URLFetcher::fetchURL(URL& url) { (curlError = curl_easy_setopt(handle, CURLOPT_COPYPOSTFIELDS, url._impl->_outContent.c_str())) == CURLE_OK || LOG(ERROR) << "Cannot set post data " << url.asString() << ": " << curl_easy_strerror(curlError); + // Disable "Expect: 100-continue" +// curl_slist* disallowed_headers = 0; +// disallowed_headers = curl_slist_append(disallowed_headers, "Expect:"); +// (curlError = curl_easy_setopt(handle, CURLOPT_HTTPHEADER, disallowed_headers)) == CURLE_OK || +// LOG(ERROR) << "Cannot disable Expect 100 header: " << curl_easy_strerror(curlError); + struct curl_slist* headers = NULL; std::map::iterator paramIter = url._impl->_outHeader.begin(); while(paramIter != url._impl->_outHeader.end()) { @@ -596,6 +602,10 @@ void URLFetcher::fetchURL(URL& url) { curl_free(value); paramIter++; } + + // 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/ecmascript/JavaScriptCore/dom/JSCNodeSetCustom.cpp b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/dom/JSCNodeSetCustom.cpp index 821f463..6de5793 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/dom/JSCNodeSetCustom.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/dom/JSCNodeSetCustom.cpp @@ -61,7 +61,7 @@ JSValueRef JSCNodeSet::getPropertyCustomCallback(JSContextRef ctx, JSObjectRef o int index = boost::lexical_cast(propName); struct JSCNodeSetPrivate* privData = (struct JSCNodeSetPrivate*)JSObjectGetPrivate(object); - if (privData->nativeObj->size() < index) { + if (privData->nativeObj->size() <= index) { return JSValueMakeUndefined(ctx); } diff --git a/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.cpp b/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.cpp index d615238..cd690ff 100644 --- a/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.cpp +++ b/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.cpp @@ -101,7 +101,7 @@ void OSGInvoker::invoke(const InvokeRequest& req) { setupColors(); - std::cout << req.dom; +// std::cout << req.dom; // register default event handlers Arabica::DOM::Events::EventTarget evTarget = Arabica::DOM::Events::EventTarget(req.dom); diff --git a/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp b/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp index dc0e27a..2edb8ba 100644 --- a/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp +++ b/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp @@ -170,28 +170,44 @@ void BasicHTTPIOProcessor::send(const SendRequest& req) { } } - // content - + // try hard to find actual content + char* keyCStr = evhttp_encode_uri("content"); if (req.content.size() > 0) { - char* keyCStr = evhttp_encode_uri("content"); char* valueCStr = evhttp_encode_uri(req.content.c_str()); kvps << kvpSeperator << keyCStr << "=" << valueCStr; free(keyCStr); free(valueCStr); kvpSeperator = "&"; - } - if (req.dom) { + } else if (req.dom) { std::stringstream xmlStream; xmlStream << req.dom; - char* keyCStr = evhttp_encode_uri("content"); char* valueCStr = evhttp_encode_uri(xmlStream.str().c_str()); kvps << kvpSeperator << keyCStr << "=" << valueCStr; - free(keyCStr); free(valueCStr); kvpSeperator = "&"; + } else if (req.data) { + char* valueCStr = NULL; + if (req.data.atom.length() || req.data.array.size() || req.data.compound.size()) { + valueCStr = evhttp_encode_uri(Data::toJSON(req.data).c_str()); + } else if(req.data.node) { + std::stringstream xmlStream; + xmlStream << req.data.node; + valueCStr = evhttp_encode_uri(xmlStream.str().c_str()); + } else if(req.data.binary) { + valueCStr = evhttp_encode_uri(req.data.binary->base64().c_str()); + } + if (valueCStr != NULL) { + kvps << kvpSeperator << keyCStr << "=" << valueCStr; + free(valueCStr); + kvpSeperator = "&"; + } } + free(keyCStr); + 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 4598615..09dc0b6 100644 --- a/src/uscxml/server/HTTPServer.cpp +++ b/src/uscxml/server/HTTPServer.cpp @@ -415,7 +415,7 @@ void HTTPServer::processByMatchingServlet(const Request& request) { while(servletIter != _servlets.end()) { // is the servlet path a prefix of the actual path? std::string servletPath = "/" + servletIter->first; - if (iequals(actualPath.substr(0, servletPath.length()), servletPath) && // actual path is a prefix + if (iequals(actualPath.substr(0, servletPath.length()), servletPath) && // servlet path is a prefix iequals(actualPath.substr(servletPath.length(), 1), "/")) { // and next character is a '/' matches.insert(std::make_pair(servletPath, servletIter->second)); } diff --git a/src/uscxml/server/HTTPServer.h b/src/uscxml/server/HTTPServer.h index d5191da..049abc4 100644 --- a/src/uscxml/server/HTTPServer.h +++ b/src/uscxml/server/HTTPServer.h @@ -87,8 +87,8 @@ private: bool operator()(std::string const& l, std::string const& r) const { if (l.size() < r.size()) return false; - - return l < r; + return true; +// return l < r; }; }; -- cgit v0.12