diff options
author | Michael Meeks <michael.meeks@collabora.com> | 2018-05-01 14:57:17 +0100 |
---|---|---|
committer | Michael Meeks <michael.meeks@collabora.com> | 2018-05-01 16:29:56 +0100 |
commit | b5a1af763cf0e2295286f3e27c767ec51551cf2f (patch) | |
tree | 874ea4614a1c8d0cb1728c1cddf463fe08d28747 /net/Socket.cpp | |
parent | wsd: to filter clientAddress before POST action. (diff) | |
download | online-b5a1af763cf0e2295286f3e27c767ec51551cf2f.tar.gz online-b5a1af763cf0e2295286f3e27c767ec51551cf2f.zip |
Share HTTP header parsing inside the StreamSocket.
Change-Id: Id98e895a939d931ac10b7cd7403da4cbe822ee82
Diffstat (limited to 'net/Socket.cpp')
-rw-r--r-- | net/Socket.cpp | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/net/Socket.cpp b/net/Socket.cpp index 1bf847cba6..9a07986c9b 100644 --- a/net/Socket.cpp +++ b/net/Socket.cpp @@ -17,6 +17,8 @@ #include <Poco/DateTime.h> #include <Poco/DateTimeFormat.h> #include <Poco/DateTimeFormatter.h> +#include <Poco/MemoryStream.h> +#include <Poco/Net/HTTPRequest.h> #include <Poco/Net/HTTPResponse.h> #include <SigUtil.hpp> @@ -241,6 +243,70 @@ bool ServerSocket::bind(Type type, int port) return rc == 0; } +bool StreamSocket::parseHeader(const char *clientName, + Poco::MemoryInputStream &message, + Poco::Net::HTTPRequest &request, + size_t *requestSize) +{ + LOG_TRC("#" << getFD() << " handling incoming " << _inBuffer.size() << " bytes."); + + assert(!requestSize || *requestSize == 0); + + // Find the end of the header, if any. + static const std::string marker("\r\n\r\n"); + auto itBody = std::search(_inBuffer.begin(), _inBuffer.end(), + marker.begin(), marker.end()); + if (itBody == _inBuffer.end()) + { + LOG_TRC("#" << getFD() << " doesn't have enough data yet."); + return false; + } + + // Skip the marker. + itBody += marker.size(); + if (requestSize) + *requestSize = static_cast<size_t>(itBody - _inBuffer.begin()); + + try + { + request.read(message); + + Log::StreamLogger logger = Log::info(); + if (logger.enabled()) + { + logger << "#" << getFD() << ": " << clientName << " HTTP Request: " + << request.getMethod() << ' ' + << request.getURI() << ' ' + << request.getVersion(); + + for (const auto& it : request) + { + logger << " / " << it.first << ": " << it.second; + } + + LOG_END(logger); + } + + const std::streamsize contentLength = request.getContentLength(); + const auto offset = itBody - _inBuffer.begin(); + const std::streamsize available = _inBuffer.size() - offset; + + if (contentLength != Poco::Net::HTTPMessage::UNKNOWN_CONTENT_LENGTH && available < contentLength) + { + LOG_DBG("Not enough content yet: ContentLength: " << contentLength << ", available: " << available); + return false; + } + } + catch (const std::exception& exc) + { + // Probably don't have enough data just yet. + // TODO: timeout if we never get enough. + return false; + } + + return true; +} + namespace HttpHelper { |