From 1c10bc4bf19c5ce73e3e10380e613da8bf93a1b0 Mon Sep 17 00:00:00 2001 From: Stefan Radomski Date: Sun, 14 Apr 2013 23:22:24 +0200 Subject: Refactored URLs and fixed Windows URL handling --- docs/CentOS.md | 2 +- src/bindings/swig/php/uscxmlNativePHP.php | 6 +-- src/uscxml/Interpreter.cpp | 47 +++++----------------- src/uscxml/Interpreter.h | 6 --- src/uscxml/URL.cpp | 36 ++++++++++++++++- src/uscxml/URL.h | 3 ++ src/uscxml/plugins/element/fetch/FetchElement.cpp | 2 +- .../invoker/filesystem/dirmon/DirMonInvoker.cpp | 2 +- test/src/test-url.cpp | 28 +++++++++++++ 9 files changed, 79 insertions(+), 53 deletions(-) diff --git a/docs/CentOS.md b/docs/CentOS.md index e70f45f..cb2045f 100644 --- a/docs/CentOS.md +++ b/docs/CentOS.md @@ -23,7 +23,7 @@ sudo yum remove swig $ wget http://sourceforge.net/projects/openvrml/files/latest/download $ tar xvjf openvrml* $ cd openvrml* -$ ./configure --disable-render-text-node --disable-script-node-javascript --disable-script-node-java --disable-gl-renderer --disable-xembed --disable-player --disable-examples +$ ./configure --disable-render-text-node --disable-script-node-javascript --disable-script-node-java --disable-gl-renderer --disable-xembed --disable-player --disable-examples --disable-mozilla-plugin $ make install $ wget http://www.cmake.org/files/v2.8/cmake-2.8.10.2.tar.gz diff --git a/src/bindings/swig/php/uscxmlNativePHP.php b/src/bindings/swig/php/uscxmlNativePHP.php index 25ce9fa..86eba7b 100644 --- a/src/bindings/swig/php/uscxmlNativePHP.php +++ b/src/bindings/swig/php/uscxmlNativePHP.php @@ -2,7 +2,7 @@ /* ---------------------------------------------------------------------------- * This file was automatically generated by SWIG (http://www.swig.org). - * Version 2.0.7 + * Version 2.0.9 * * This file is not intended to be easily readable and contains a number of * coding conventions designed to improve portability and efficiency. Do not make @@ -585,10 +585,6 @@ class Interpreter { return Interpreter_getBaseURI($this->_cPtr); } - function toAbsoluteURI($uri) { - return Interpreter_toAbsoluteURI($this->_cPtr,$uri); - } - function setCmdLineOptions($argc,$argv) { Interpreter_setCmdLineOptions($this->_cPtr,$argc,$argv); } diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp index 0f98dc9..c951999 100644 --- a/src/uscxml/Interpreter.cpp +++ b/src/uscxml/Interpreter.cpp @@ -100,7 +100,7 @@ Interpreter Interpreter::fromURI(const std::string& uri) { if (boost::iequals(absUrl.scheme(), "file")) { Arabica::SAX::InputSource inputSource; - inputSource.setSystemId(absUrl.path()); + inputSource.setSystemId(absUrl.asString()); interpreter = fromInputSource(inputSource); } else if (boost::iequals(absUrl.scheme(), "http")) { // handle http per arabica @@ -119,8 +119,11 @@ Interpreter Interpreter::fromURI(const std::string& uri) { } // try to establish URI root for relative src attributes in document - if (interpreter) - interpreter._impl->_baseURI = InterpreterImpl::toBaseURI(absUrl); + if (interpreter) { + interpreter._impl->_baseURI = URL::asBaseURL(absUrl); + } else { + LOG(ERROR) << "Cannot create interpreter from URI '" << absUrl.asString() << "'"; + } return interpreter; } @@ -186,38 +189,6 @@ void InterpreterImpl::setName(const std::string& name) { } } -URL InterpreterImpl::toBaseURI(const URL& uri) { - std::stringstream ssBaseURI; - if (uri.scheme().size() > 0) { - ssBaseURI << uri.scheme() << "://"; - } else { - ssBaseURI << "file://"; - } - if (uri.host().size() > 0) { - ssBaseURI << uri.host(); - if (!boost::iequals(uri.port(), "0")) - ssBaseURI << ":" << uri.port(); - } - if (uri.path().size() > 0) { - std::string uriPath = uri.path(); - uriPath = uriPath.substr(0, uriPath.find_last_of("/\\") + 1); - ssBaseURI << uriPath; - } - return URL(ssBaseURI.str()); -} - -bool InterpreterImpl::toAbsoluteURI(URL& uri) { - if (uri.isAbsolute()) - return true; - - if (_baseURI.asString().size() > 0) { - if (uri.toAbsolute(_baseURI)) - return true; - return false; - } - return false; -} - InterpreterImpl::~InterpreterImpl() { tthread::lock_guard lock(_mutex); if (_thread) { @@ -481,7 +452,7 @@ void InterpreterImpl::processDOMorText(const Arabica::DOM::Node& no (HAS_ATTR(node, "srcexpr") && _dataModel)) { std::stringstream srcContent; URL sourceURL(HAS_ATTR(node, "srcexpr") ? _dataModel.evalAsString(ATTR(node, "srcexpr")) : ATTR(node, "src")); - if (!toAbsoluteURI(sourceURL)) { + if (!sourceURL.toAbsolute(_baseURI)) { LOG(ERROR) << LOCALNAME(node) << " element has relative src or srcexpr URI with no baseURI set."; return; } @@ -785,7 +756,7 @@ void InterpreterImpl::invoke(const Arabica::DOM::Node& element) { } if (source.length() > 0) { URL srcURI(source); - if (!toAbsoluteURI(srcURI)) { + if (!srcURI.toAbsolute(_baseURI)) { LOG(ERROR) << "invoke element has relative src URI with no baseURI set."; return; } @@ -1131,7 +1102,7 @@ void InterpreterImpl::executeContent(const Arabica::DOM::Node& cont if (_dataModel) { if (HAS_ATTR(content, "src")) { URL scriptUrl(ATTR(content, "src")); - if (!toAbsoluteURI(scriptUrl)) { + if (!scriptUrl.toAbsolute(_baseURI)) { LOG(ERROR) << "script element has relative URI " << ATTR(content, "src") << " with no base URI set for interpreter"; return; } diff --git a/src/uscxml/Interpreter.h b/src/uscxml/Interpreter.h index 5207930..f28eb69 100644 --- a/src/uscxml/Interpreter.h +++ b/src/uscxml/Interpreter.h @@ -107,7 +107,6 @@ public: URL getBaseURI() { return _baseURI; } - bool toAbsoluteURI(URL& uri); void setCmdLineOptions(int argc, char** argv); Data getCmdLineOptions() { @@ -262,8 +261,6 @@ protected: InterpreterServlet* _httpServlet; std::set _monitors; - static URL toBaseURI(const URL& url); - void executeContent(const Arabica::DOM::Node& content, bool rethrow = false); void executeContent(const Arabica::DOM::NodeList& content, bool rethrow = false); void executeContent(const Arabica::XPath::NodeSet& content, bool rethrow = false); @@ -374,9 +371,6 @@ public: URL getBaseURI() { return _impl->getBaseURI(); } - bool toAbsoluteURI(URL& uri) { - return _impl->toAbsoluteURI(uri); - } void setCmdLineOptions(int argc, char** argv) { return _impl->setCmdLineOptions(argc, argv); diff --git a/src/uscxml/URL.cpp b/src/uscxml/URL.cpp index b441bbf..83d3dcb 100644 --- a/src/uscxml/URL.cpp +++ b/src/uscxml/URL.cpp @@ -196,7 +196,11 @@ const bool URLImpl::toAbsoluteCwd() { return false; } currPath[sizeof(currPath) - 1] = '\0'; /* not really required */ +#ifdef _WIN32 + return toAbsolute(std::string("file://" + std::string(currPath) + "/")); +#else return toAbsolute(std::string("file://" + std::string(currPath) + "/")); +#endif } std::string URLImpl::getLocalFilename(const std::string& suffix) { @@ -247,10 +251,37 @@ std::string URLImpl::getLocalFilename(const std::string& suffix) { return std::string(tmpl); } +void URL::toBaseURL(URL& uri) { + uri = asBaseURL(uri); +} + +URL URL::asBaseURL(const URL& uri) { + std::string uriStr = uri.asString(); + std::string baseUriStr = uriStr.substr(0, uriStr.find_last_of("/\\") + 1); +#ifdef _WIN32 + if (baseUriStr.find("file://") == 0) { + baseUriStr = baseUriStr.substr(7); + } +#endif + return URL(baseUriStr); +} + + const bool URLImpl::toAbsolute(const std::string& baseUrl) { if (_uri.is_absolute()) return true; + + std::string uriStr = _uri.as_string(); +#ifdef _WIN32 + if (baseUrl.find("file://") == 0) { + _uri = Arabica::io::URI("file:///" + baseUrl.substr(7), _uri.as_string()); + } else { + _uri = Arabica::io::URI(baseUrl, _uri.as_string()); + } +#else _uri = Arabica::io::URI(baseUrl, _uri.as_string()); +#endif + if (!_uri.is_absolute()) return false; return true; @@ -259,8 +290,11 @@ const bool URLImpl::toAbsolute(const std::string& baseUrl) { boost::shared_ptr URLImpl::toLocalFile(const std::string& content, const std::string& suffix) { boost::shared_ptr urlImpl = boost::shared_ptr(new URLImpl()); urlImpl->_localFile = urlImpl->getLocalFilename(suffix); +#ifdef _WIN32 urlImpl->_uri = std::string("file://") + urlImpl->_localFile; - +#else + urlImpl->_uri = std::string("file://") + urlImpl->_localFile; +#endif std::ofstream file(urlImpl->_localFile.c_str(), std::ios_base::out); if(file.is_open()) { file << content; diff --git a/src/uscxml/URL.h b/src/uscxml/URL.h index 61a225c..37b0614 100644 --- a/src/uscxml/URL.h +++ b/src/uscxml/URL.h @@ -177,6 +177,9 @@ public: const std::string asLocalFile(const std::string& suffix, bool reload = false) { return _impl->asLocalFile(suffix, reload); } + + static URL asBaseURL(const URL& url); + static void toBaseURL(URL& uri); static URL toLocalFile(const std::string& content, const std::string& suffix) { boost::shared_ptr impl = URLImpl::toLocalFile(content, suffix); diff --git a/src/uscxml/plugins/element/fetch/FetchElement.cpp b/src/uscxml/plugins/element/fetch/FetchElement.cpp index 56c1815..e6ceb3f 100644 --- a/src/uscxml/plugins/element/fetch/FetchElement.cpp +++ b/src/uscxml/plugins/element/fetch/FetchElement.cpp @@ -90,7 +90,7 @@ void FetchElement::enterElement(const Arabica::DOM::Node& node) { _targetUrl = URL(_target); if (!_targetUrl.isAbsolute()) { - if (!_interpreter->toAbsoluteURI(_targetUrl)) { + if (!_targetUrl.toAbsolute(_interpreter->getBaseURI())) { LOG(ERROR) << "Cannot transform " << _target << " into absolute URL"; return; } diff --git a/src/uscxml/plugins/invoker/filesystem/dirmon/DirMonInvoker.cpp b/src/uscxml/plugins/invoker/filesystem/dirmon/DirMonInvoker.cpp index 882c174..8e3209a 100644 --- a/src/uscxml/plugins/invoker/filesystem/dirmon/DirMonInvoker.cpp +++ b/src/uscxml/plugins/invoker/filesystem/dirmon/DirMonInvoker.cpp @@ -90,7 +90,7 @@ void DirMonInvoker::invoke(const InvokeRequest& req) { std::multimap::const_iterator dirIter = req.params.find("dir"); while(dirIter != req.params.upper_bound("dir")) { URL url(dirIter->second); - if (!_interpreter->toAbsoluteURI(url) || !boost::iequals(url.scheme(), "file")) { + if (!url.toAbsolute(_interpreter->getBaseURI()) || !boost::iequals(url.scheme(), "file")) { LOG(ERROR) << "Given directory '" << dirIter->second << "' cannot be transformed to absolute path"; } else { _dir = url.path(); diff --git a/test/src/test-url.cpp b/test/src/test-url.cpp index 86fcb9f..c889f86 100644 --- a/test/src/test-url.cpp +++ b/test/src/test-url.cpp @@ -3,6 +3,8 @@ #include "uscxml/Interpreter.h" #include "uscxml/server/HTTPServer.h" +#include + #include #include #include @@ -26,8 +28,34 @@ public: bool _canAdaptPath; }; +bool canResolve(const std::string& url) { + Arabica::SAX::InputSource is(url); + Arabica::SAX::InputSourceResolver res1(is, Arabica::default_string_adaptor()); + if(res1.resolve()) { + std::cout << "good: " << url << std::endl; + return true; + } else { + std::cout << "bad: " << url << std::endl; + return false; + } +} + int main(int argc, char** argv) { + std::string exeName = argv[0]; + exeName = exeName.substr(exeName.find_last_of("\\/") + 1); + + { + URL url(argv[0]); + assert(canResolve(argv[0])); + assert(canResolve(url.asString())); + + URL baseUrl = URL::asBaseURL(url); + URL exeUrl(exeName); + exeUrl.toAbsolute(baseUrl); + assert(canResolve(exeUrl.asString())); + } + { // Interpreter interpreter = Interpreter::fromURI("https://raw.github.com/tklab-tud/uscxml/master/test/samples/uscxml/test-execution.scxml"); // assert(interpreter); -- cgit v0.12