[Libreoffice-commits] online.git: Branch 'private/Ashod/nonblocking' - net/clientnb.cpp net/common.hpp net/loolnb.cpp net/socket.hpp
Michael Meeks
michael.meeks at collabora.com
Thu Feb 16 10:14:39 UTC 2017
net/clientnb.cpp | 69 ++++++++++++++++++++++++++++++++++++++++++-------------
net/common.hpp | 48 ++++++++++++++++++++++++++++++++++++++
net/loolnb.cpp | 14 +++++++++++
net/socket.hpp | 1
4 files changed, 116 insertions(+), 16 deletions(-)
New commits:
commit 6b3972153e1f5f831074b3e47b1dc0fed0ed883f
Author: Michael Meeks <michael.meeks at collabora.com>
Date: Thu Feb 16 10:14:08 2017 +0000
Initial http header parsing pieces.
diff --git a/net/clientnb.cpp b/net/clientnb.cpp
index ec7c578..99bda95 100644
--- a/net/clientnb.cpp
+++ b/net/clientnb.cpp
@@ -35,6 +35,8 @@
#include <Poco/Util/Option.h>
#include <Poco/Util/OptionSet.h>
+#include "common.hpp"
+
using Poco::Net::HTTPClientSession;
using Poco::Net::HTTPRequest;
using Poco::Net::HTTPResponse;
@@ -46,41 +48,48 @@ using Poco::Util::HelpFormatter;
using Poco::Util::Option;
using Poco::Util::OptionSet;
+const char *HostName = "127.0.0.1";
constexpr int PortNumber = 9191;
-Poco::Net::SocketAddress addr("127.0.0.1", PortNumber);
-
-struct Client : public Poco::Util::Application
+struct Session
{
-public:
- int main(const std::vector<std::string>& /* args */) override
+ std::string _session_name;
+ Poco::Net::HTTPClientSession *_session;
+
+ Session(const char *session_name, bool https = false)
+ : _session_name(session_name)
{
- const char *hostname = "127.0.0.1";
- bool https = false;
- Poco::Net::HTTPClientSession *session;
if (https)
- session = new Poco::Net::HTTPSClientSession(hostname, PortNumber);
+ _session = new Poco::Net::HTTPSClientSession(HostName, PortNumber);
else
- session = new Poco::Net::HTTPClientSession(hostname, PortNumber);
- Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, "/ping");
+ _session = new Poco::Net::HTTPClientSession(HostName, PortNumber);
+ }
+ void sendPing(int i)
+ {
+ Poco::Net::HTTPRequest request(
+ Poco::Net::HTTPRequest::HTTP_POST,
+ "/ping/" + _session_name + "/" + std::to_string(i));
try {
Poco::Net::HTMLForm form;
form.setEncoding(Poco::Net::HTMLForm::ENCODING_MULTIPART);
form.prepareSubmit(request);
- form.write(session->sendRequest(request));
+ form.write(_session->sendRequest(request));
}
catch (const Poco::Exception &e)
{
std::cerr << "Failed to write data: " << e.name() <<
" " << e.message() << "\n";
- return -1;
+ throw;
}
-
+ }
+ int getResponse()
+ {
+ int number = 42;
Poco::Net::HTTPResponse response;
try {
std::cerr << "try to get response\n";
- std::istream& responseStream = session->receiveResponse(response);
+ std::istream& responseStream = _session->receiveResponse(response);
std::string result(std::istreambuf_iterator<char>(responseStream), {});
std::cerr << "Got response '" << result << "'\n";
@@ -89,8 +98,36 @@ public:
{
std::cerr << "Exception converting: " << e.name() <<
" " << e.message() << "\n";
- return -1;
+ throw;
}
+ return number;
+ }
+};
+
+void testParseHTTP()
+{
+}
+
+struct Client : public Poco::Util::Application
+{
+public:
+ int main(const std::vector<std::string>& /* args */) override
+ {
+ testParseHTTP();
+
+ Session first("init");
+ Session second("init");
+
+ int count = 42, back;
+ first.sendPing(count);
+ second.sendPing(count + 1);
+
+ back = first.getResponse();
+ assert (back == count + 1);
+
+ back = second.getResponse();
+ assert (back == count + 1);
+
return 0;
}
};
diff --git a/net/common.hpp b/net/common.hpp
new file mode 100644
index 0000000..da1ca25
--- /dev/null
+++ b/net/common.hpp
@@ -0,0 +1,48 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef NB_COMMON_HPP
+#define NB_COMMON_HPP
+
+typedef std::vector<std::string> HeaderStrings;
+typedef std::vector<unsigned char> Payload;
+
+// FIXME: lots of return conditions:
+// partial data, malicious/invalid data, complete data
+// does this belong in a separate method ?
+size_t parseHTTP(const std::vector<unsigned char> data,
+ HeaderStrings &headers, Payload & /* payload */)
+{
+ size_t i, start;
+ for (i = start = 0; i < data.size(); ++i)
+ {
+ unsigned char c = data[i];
+ if (c == 0)
+ { // someone doing something cute.
+ return -1;
+ }
+ if (c == '\r' || c == '\n')
+ {
+ std::string header(reinterpret_cast<const char *>(&data[start]), i - start);
+ while (++i < data.size() &&
+ (data[i] == '\n' || data[i] == '\r'))
+ {}
+ start = i;
+ // terminating \r\n
+ if (header.size() == 0)
+ break;
+ headers.push_back(header);
+ }
+ }
+ return i;
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/net/loolnb.cpp b/net/loolnb.cpp
index bffc684..a6a94eb 100644
--- a/net/loolnb.cpp
+++ b/net/loolnb.cpp
@@ -21,6 +21,7 @@
#include <Poco/Net/SocketAddress.h>
#include "socket.hpp"
+#include "common.hpp"
constexpr int PortNumber = 9191;
@@ -34,6 +35,19 @@ public:
virtual void handleIncomingMessage() override
{
std::cerr << "message had size " << _inBuffer.size() << "\n";
+
+ HeaderStrings headers;
+ Payload payload;
+ size_t skip;
+ if ((skip = parseHTTP(_inBuffer, headers, payload) > 0))
+ {
+ for (auto i = headers.begin(); i != headers.end(); ++i)
+ {
+ std::cerr << "header '" << *i << "'\n";
+ }
+ }
+ // else close socket ? ...
+
std::ostringstream oss;
oss << "HTTP/1.1 200 OK\r\n"
<< "Date: Once, Upon a time GMT\r\n" // Mon, 27 Jul 2009 12:28:53 GMT
diff --git a/net/socket.hpp b/net/socket.hpp
index 449f6e0..3b55405 100644
--- a/net/socket.hpp
+++ b/net/socket.hpp
@@ -290,6 +290,7 @@ public:
{
bool closeSocket = false;
+ // FIXME: need to close input, but not output (?)
if (events & POLLIN)
closeSocket = !readIncomingData();
More information about the Libreoffice-commits
mailing list