diff options
author | Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de> | 2013-02-20 21:13:02 (GMT) |
---|---|---|
committer | Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de> | 2013-02-20 21:13:02 (GMT) |
commit | a56f28b0db56ff3e39f0b50e4c55c52b7aeec696 (patch) | |
tree | 41cf67ea5cee9593e86272ab55367653fbd1c2f3 /src/uscxml/plugins/element | |
parent | 7c779099b3acd1fa969dde718299484ebe0d2775 (diff) | |
download | uscxml-a56f28b0db56ff3e39f0b50e4c55c52b7aeec696.zip uscxml-a56f28b0db56ff3e39f0b50e4c55c52b7aeec696.tar.gz uscxml-a56f28b0db56ff3e39f0b50e4c55c52b7aeec696.tar.bz2 |
See detailled log
- Builds on windows again
- All HTTP requests are no passed into interpreter
- New response element to reply with data
- Moved basichttp URL
- New HTTP servlet invoker to register additional URLs
- More bugfixes than I care to mention
Diffstat (limited to 'src/uscxml/plugins/element')
-rw-r--r-- | src/uscxml/plugins/element/fetch/FetchElement.cpp | 108 | ||||
-rw-r--r-- | src/uscxml/plugins/element/fetch/FetchElement.h | 48 | ||||
-rw-r--r-- | src/uscxml/plugins/element/response/ResponseElement.cpp | 68 | ||||
-rw-r--r-- | src/uscxml/plugins/element/response/ResponseElement.h | 42 |
4 files changed, 266 insertions, 0 deletions
diff --git a/src/uscxml/plugins/element/fetch/FetchElement.cpp b/src/uscxml/plugins/element/fetch/FetchElement.cpp new file mode 100644 index 0000000..33cb76e --- /dev/null +++ b/src/uscxml/plugins/element/fetch/FetchElement.cpp @@ -0,0 +1,108 @@ +#include "FetchElement.h" +#include <glog/logging.h> + +#include <event2/http.h> +#include <event2/http_struct.h> + +#ifdef BUILD_AS_PLUGINS +#include <Pluma/Connector.hpp> +#endif + +namespace uscxml { + +#ifdef BUILD_AS_PLUGINS +PLUMA_CONNECTOR +bool connect(pluma::Host& host) { + host.add( new FetchElementProvider() ); + return true; +} +#endif + +boost::shared_ptr<ExecutableContentImpl> FetchElement::create(Interpreter* interpreter) { + boost::shared_ptr<FetchElement> invoker = boost::shared_ptr<FetchElement>(new FetchElement()); + invoker->_interpreter = interpreter; + return invoker; +} + +FetchElement::~FetchElement() { + URLFetcher::breakURL(_targetUrl); +} + +void FetchElement::downloadCompleted(const URL& url) { + Event event; + event.name = _callback; + + std::string content = url.getInContent(); + std::map<std::string, std::string> headerFields = url.getInHeaderFields(); + + if (false) { + } else if (boost::iequals(_type, "text")) { + event.data.atom = content; + event.data.type = Data::VERBATIM; + } else if (boost::iequals(_type, "url")) { + } else if (boost::iequals(_type, "json")) { + event.data = Data::fromJSON(content); + } else if (boost::iequals(_type, "xml")) { + event = Event::fromXML(content); + } + + _interpreter->receive(event); + +} + +void FetchElement::downloadFailed(const URL& url, int errorCode) { + Event event; + event.name = _callback + ".failed"; + + _interpreter->receive(event); + +} + +void FetchElement::enterElement(const Arabica::DOM::Node<std::string>& node) { + if (!HAS_ATTR(node, "target") && !HAS_ATTR(node, "targetexpr")) { + LOG(ERROR) << "Fetch element requires target or targetexpr"; + return; + } + if (HAS_ATTR(node, "targetexpr") && !_interpreter->getDataModel()) { + LOG(ERROR) << "Fetch element with targetexpr requires datamodel"; + return; + } + _target = (HAS_ATTR(node, "target") ? ATTR(node, "target") : _interpreter->getDataModel().evalAsString(ATTR(node, "targetexpr"))); + + if (!HAS_ATTR(node, "callback") && !HAS_ATTR(node, "callbackexpr")) { + LOG(ERROR) << "Fetch element requires callback or callbackexpr"; + return; + } + if (HAS_ATTR(node, "callbackexpr") && !_interpreter->getDataModel()) { + LOG(ERROR) << "Fetch element with callbackexpr requires datamodel"; + return; + } + _callback = (HAS_ATTR(node, "callback") ? ATTR(node, "callback") : _interpreter->getDataModel().evalAsString(ATTR(node, "callbackexpr"))); + + _type = (HAS_ATTR(node, "type") ? ATTR(node, "type") : "text"); + if (!boost::iequals(_type, "text") && + !boost::iequals(_type, "url") && + !boost::iequals(_type, "json") && + !boost::iequals(_type, "xml")) { + LOG(ERROR) << "Fetch element type attribute not one of text, url, json, xml."; + return; + } + + _targetUrl = URL(_target); + if (!_targetUrl.isAbsolute()) { + if (!_interpreter->toAbsoluteURI(_targetUrl)) { + LOG(ERROR) << "Cannot transform " << _target << " into absolute URL"; + return; + } + } + + _targetUrl.addMonitor(this); + URLFetcher::fetchURL(_targetUrl); + +} + +void FetchElement::exitElement(const Arabica::DOM::Node<std::string>& node) { + +} + +}
\ No newline at end of file diff --git a/src/uscxml/plugins/element/fetch/FetchElement.h b/src/uscxml/plugins/element/fetch/FetchElement.h new file mode 100644 index 0000000..0229048 --- /dev/null +++ b/src/uscxml/plugins/element/fetch/FetchElement.h @@ -0,0 +1,48 @@ +#ifndef FETCHELEMENT_H_R6GH94FV +#define FETCHELEMENT_H_R6GH94FV + +#include <uscxml/Interpreter.h> + +#ifdef BUILD_AS_PLUGINS +#include "uscxml/plugins/Plugins.h" +#endif + +namespace uscxml { + +class FetchElement : public ExecutableContentImpl, public URLMonitor { +public: + FetchElement() {} + virtual ~FetchElement(); + boost::shared_ptr<ExecutableContentImpl> create(Interpreter* interpreter); + + std::string getLocalName() { + return "fetch"; + } + + std::string getNamespace() { + return "http://www.w3.org/2005/07/scxml"; + } + + bool processChildren() { + return false; + } + + void enterElement(const Arabica::DOM::Node<std::string>& node); + void exitElement(const Arabica::DOM::Node<std::string>& node); + void downloadCompleted(const URL& url); + void downloadFailed(const URL& url, int errorCode); + +protected: + URL _targetUrl; + std::string _target; + std::string _callback; + std::string _type; +}; + +#ifdef BUILD_AS_PLUGINS +PLUMA_INHERIT_PROVIDER(FetchElement, Element); +#endif + +} + +#endif /* end of include guard: FETCHELEMENT_H_R6GH94FV */ diff --git a/src/uscxml/plugins/element/response/ResponseElement.cpp b/src/uscxml/plugins/element/response/ResponseElement.cpp new file mode 100644 index 0000000..ce25036 --- /dev/null +++ b/src/uscxml/plugins/element/response/ResponseElement.cpp @@ -0,0 +1,68 @@ +#include "ResponseElement.h" +#include "uscxml/plugins/invoker/http/HTTPServletInvoker.h" +#include <glog/logging.h> + +#ifdef BUILD_AS_PLUGINS +#include <Pluma/Connector.hpp> +#endif + +namespace uscxml { + +#ifdef BUILD_AS_PLUGINS +PLUMA_CONNECTOR +bool connect(pluma::Host& host) { + host.add( new ResponseElementProvider() ); + return true; +} +#endif + +boost::shared_ptr<ExecutableContentImpl> ResponseElement::create(Interpreter* interpreter) { + boost::shared_ptr<ResponseElement> invoker = boost::shared_ptr<ResponseElement>(new ResponseElement()); + invoker->_interpreter = interpreter; + return invoker; +} + +void ResponseElement::enterElement(const Arabica::DOM::Node<std::string>& node) { + if (!HAS_ATTR(node, "request") && !HAS_ATTR(node, "requestexpr")) { + LOG(ERROR) << "Response element requires request or requestexpr"; + return; + } + if (HAS_ATTR(node, "requestexpr") && !_interpreter->getDataModel()) { + LOG(ERROR) << "Response element with requestexpr requires datamodel"; + return; + } + if (HAS_ATTR(node, "close")) { + + } + + std::string requestId = (HAS_ATTR(node, "request") ? ATTR(node, "request") : _interpreter->getDataModel().evalAsString(ATTR(node, "requestexpr"))); + + HTTPServletInvoker* servlet = _interpreter->getHTTPServlet(); + tthread::lock_guard<tthread::recursive_mutex> lock(servlet->getMutex()); + + if (servlet->getRequests().find(requestId) == servlet->getRequests().end()) { + LOG(ERROR) << "No matching HTTP request for response element"; + return; + } + + std::string statusStr = (HAS_ATTR(node, "status") ? ATTR(node, "status") : "200"); + if (!isNumeric(statusStr.c_str(), 10)) { + LOG(ERROR) << "Response element with non-numeric status " << statusStr; + return; + } + int status = strTo<int>(statusStr); + + HTTPServer::Request httpReq = servlet->getRequests()[requestId]; + + HTTPServer::Reply httpReply(httpReq); + httpReply.status = status; + + HTTPServer::reply(httpReply); + servlet->getRequests().erase(requestId); +} + +void ResponseElement::exitElement(const Arabica::DOM::Node<std::string>& node) { + +} + +}
\ No newline at end of file diff --git a/src/uscxml/plugins/element/response/ResponseElement.h b/src/uscxml/plugins/element/response/ResponseElement.h new file mode 100644 index 0000000..97ff9db --- /dev/null +++ b/src/uscxml/plugins/element/response/ResponseElement.h @@ -0,0 +1,42 @@ +#ifndef RESPONSEELEMENT_H_I11KQ39Q +#define RESPONSEELEMENT_H_I11KQ39Q + +#include <uscxml/Interpreter.h> + +#ifdef BUILD_AS_PLUGINS +#include "uscxml/plugins/Plugins.h" +#endif + +namespace uscxml { + +class ResponseElement : public ExecutableContentImpl { +public: + ResponseElement() {} + virtual ~ResponseElement() {} + boost::shared_ptr<ExecutableContentImpl> create(Interpreter* interpreter); + + std::string getLocalName() { + return "response"; + } + + std::string getNamespace() { + return "http://www.w3.org/2005/07/scxml"; + } + + bool processChildren() { + return false; + } + + void enterElement(const Arabica::DOM::Node<std::string>& node); + void exitElement(const Arabica::DOM::Node<std::string>& node); + +}; + +#ifdef BUILD_AS_PLUGINS +PLUMA_INHERIT_PROVIDER(ResponseElement, Element); +#endif + +} + + +#endif /* end of include guard: RESPONSEELEMENT_H_I11KQ39Q */ |