[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