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 <[email protected]> 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(); _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
