diff options
author | Henry Castro <hcastro@collabora.com> | 2019-02-05 17:03:48 -0400 |
---|---|---|
committer | Henry Castro <hcastro@collabora.com> | 2019-03-05 16:31:51 -0400 |
commit | ed89931ae8ceff62b720a31cf1e163eeee3280fd (patch) | |
tree | 1cc50c6403f412275dad17f3cfd00cda09f19543 /wsd | |
parent | 88a8810ee79215f706c3394bf92072a9dea2c068 (diff) |
wsd: use a tiny parser, variable substitution
Change-Id: I821d27ef504a01d0b040f2b7ae7f66e75b16eb96
Diffstat (limited to 'wsd')
-rw-r--r-- | wsd/FileServer.cpp | 160 | ||||
-rw-r--r-- | wsd/FileServer.hpp | 1 |
2 files changed, 141 insertions, 20 deletions
diff --git a/wsd/FileServer.cpp b/wsd/FileServer.cpp index 07ee9c4cd..7c297deb1 100644 --- a/wsd/FileServer.cpp +++ b/wsd/FileServer.cpp @@ -567,6 +567,26 @@ constexpr char BRANDING[] = "branding"; constexpr char BRANDING_UNSUPPORTED[] = "branding-unsupported"; #endif +void FileServerRequestHandler::getToken(std::istream& istr, std::string& token) +{ + token.clear(); + int chr = istr.get(); + if (chr != -1) + { + if (chr == '<' && istr.peek() == '%') + { + token += "<%"; + istr.get(); + } + else if (chr == '%' && istr.peek() == '>') + { + token += "%>"; + istr.get(); + } + else token += (char) chr; + } +} + void FileServerRequestHandler::preprocessFile(const HTTPRequest& request, Poco::MemoryInputStream& message, const std::shared_ptr<StreamSocket>& socket) { const auto host = ((LOOLWSD::isSSLEnabled() || LOOLWSD::isSSLTermination()) ? "wss://" : "ws://") + (LOOLWSD::ServerName.empty() ? request.getHost() : LOOLWSD::ServerName); @@ -611,13 +631,6 @@ void FileServerRequestHandler::preprocessFile(const HTTPRequest& request, Poco:: } } - Poco::replaceInPlace(preprocess, std::string("%ACCESS_TOKEN%"), escapedAccessToken); - Poco::replaceInPlace(preprocess, std::string("%ACCESS_TOKEN_TTL%"), std::to_string(tokenTtl)); - Poco::replaceInPlace(preprocess, std::string("%ACCESS_HEADER%"), escapedAccessHeader); - Poco::replaceInPlace(preprocess, std::string("%HOST%"), host); - Poco::replaceInPlace(preprocess, std::string("%VERSION%"), std::string(LOOLWSD_VERSION_HASH)); - Poco::replaceInPlace(preprocess, std::string("%SERVICE_ROOT%"), LOOLWSD::ServiceRoot); - static const std::string linkCSS("<link rel=\"stylesheet\" href=\"%s/loleaflet/" LOOLWSD_VERSION_HASH "/%s.css\">"); static const std::string scriptJS("<script src=\"%s/loleaflet/" LOOLWSD_VERSION_HASH "/%s.js\"></script>"); @@ -635,9 +648,6 @@ void FileServerRequestHandler::preprocessFile(const HTTPRequest& request, Poco:: } #endif - Poco::replaceInPlace(preprocess, std::string("<!--%BRANDING_CSS%-->"), brandCSS); - Poco::replaceInPlace(preprocess, std::string("<!--%BRANDING_JS%-->"), brandJS); - // Customization related to document signing. std::string documentSigningDiv; const std::string documentSigningURL = config.getString("per_document.document_signing_url", ""); @@ -645,15 +655,125 @@ void FileServerRequestHandler::preprocessFile(const HTTPRequest& request, Poco:: { documentSigningDiv = "<div id=\"document-signing-bar\"></div>"; } - Poco::replaceInPlace(preprocess, std::string("<!--%DOCUMENT_SIGNING_DIV%-->"), documentSigningDiv); - Poco::replaceInPlace(preprocess, std::string("%DOCUMENT_SIGNING_URL%"), documentSigningURL); - const auto loleafletLogging = config.getString("loleaflet_logging", "false"); - Poco::replaceInPlace(preprocess, std::string("%LOLEAFLET_LOGGING%"), loleafletLogging); - const std::string outOfFocusTimeoutSecs= config.getString("per_view.out_of_focus_timeout_secs", "60"); - Poco::replaceInPlace(preprocess, std::string("%OUT_OF_FOCUS_TIMEOUT_SECS%"), outOfFocusTimeoutSecs); - const std::string idleTimeoutSecs= config.getString("per_view.idle_timeout_secs", "900"); - Poco::replaceInPlace(preprocess, std::string("%IDLE_TIMEOUT_SECS%"), idleTimeoutSecs); + enum class ParseState + { + None, + Subs, + L10n + }; + + std::string token; + std::ostringstream ostr; + std::stringstream varSubs, varL10n; + std::istringstream istr(preprocess); + ParseState state = ParseState::None; + + getToken(istr, token); + while (!token.empty()) + { + if (token == "<%") + { + if (state == ParseState::None) + { + state = ParseState::Subs; + varSubs.str(""); + varSubs.clear(); + } + else ostr << token; + } + else if (token == "%>") + { + if (state == ParseState::Subs) + { + std::string var = varSubs.str(); + if (var == "ACCESS_TOKEN") + { + ostr << escapedAccessToken; + } + else if (var == "ACCESS_TOKEN_TTL") + { + ostr << tokenTtl; + } + else if (var == "ACCESS_HEADER") + { + ostr << escapedAccessHeader; + } + else if (var == "HOST") + { + ostr << host; + } + else if (var == "VERSION") + { + ostr << LOOLWSD_VERSION_HASH; + } + else if (var == "SERVICE_ROOT") + { + ostr << LOOLWSD::ServiceRoot; + } + else if (var == "LOLEAFLET_LOGGING") + { + ostr << config.getString("loleaflet_logging", "false"); + } + else if (var == "OUT_OF_FOCUS_TIMEOUT_SECS") + { + ostr << config.getString("per_view.out_of_focus_timeout_secs", "60"); + } + else if (var == "IDLE_TIMEOUT_SECS") + { + ostr << config.getString("per_view.idle_timeout_secs", "900"); + } + else if (var == "DOCUMENT_SIGNING_DIV") + { + ostr << documentSigningDiv; + } + else if (var == "DOCUMENT_SIGNING_URL") + { + ostr << documentSigningURL; + } + else if (var == "BRANDING_CSS") + { + ostr << brandCSS; + } + else if (var == "BRANDING_JS") + { + ostr << brandJS; + } + else ostr << var; + + state = ParseState::None; + } + else ostr << token; + } + else + { + switch (state) + { + case ParseState::None: + ostr << token; + break; + + case ParseState::Subs: + varSubs << token; + break; + + case ParseState::L10n: + varL10n << token; + break; + } + } + + getToken(istr, token); + } + + if (state == ParseState::Subs) + { + ostr << varSubs.str(); + } + else if (state == ParseState::L10n) + { + ostr << varL10n.str(); + } const std::string mimeType = "text/html"; @@ -664,7 +784,7 @@ void FileServerRequestHandler::preprocessFile(const HTTPRequest& request, Poco:: << "User-Agent: " << WOPI_AGENT_STRING << "\r\n" << "Cache-Control:max-age=11059200\r\n" << "ETag: \"" LOOLWSD_VERSION_HASH "\"\r\n" - << "Content-Length: " << preprocess.size() << "\r\n" + << "Content-Length: " << ostr.tellp() << "\r\n" << "Content-Type: " << mimeType << "\r\n" << "X-Content-Type-Options: nosniff\r\n" << "X-XSS-Protection: 1; mode=block\r\n" @@ -781,7 +901,7 @@ void FileServerRequestHandler::preprocessFile(const HTTPRequest& request, Poco:: } oss << "\r\n" - << preprocess; + << ostr.str(); socket->send(oss.str()); LOG_DBG("Sent file: " << relPath << ": " << preprocess); diff --git a/wsd/FileServer.hpp b/wsd/FileServer.hpp index b415eed65..637424468 100644 --- a/wsd/FileServer.hpp +++ b/wsd/FileServer.hpp @@ -20,6 +20,7 @@ class FileServerRequestHandler { static std::string getRequestPathname(const Poco::Net::HTTPRequest& request); + static void getToken(std::istream&, std::string&); static void preprocessFile(const Poco::Net::HTTPRequest& request, Poco::MemoryInputStream& message, const std::shared_ptr<StreamSocket>& socket); static void preprocessAdminFile(const Poco::Net::HTTPRequest& request, const std::shared_ptr<StreamSocket>& socket); public: |