summaryrefslogtreecommitdiffstats
path: root/net/Socket.cpp
diff options
context:
space:
mode:
authorMichael Meeks <michael.meeks@collabora.com>2018-05-01 14:57:17 +0100
committerMichael Meeks <michael.meeks@collabora.com>2018-05-01 16:29:56 +0100
commitb5a1af763cf0e2295286f3e27c767ec51551cf2f (patch)
tree874ea4614a1c8d0cb1728c1cddf463fe08d28747 /net/Socket.cpp
parentwsd: to filter clientAddress before POST action. (diff)
downloadonline-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.cpp66
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
{