diff options
author | Michael Meeks <michael.meeks@collabora.com> | 2019-05-22 02:54:12 +0100 |
---|---|---|
committer | Michael Meeks <michael.meeks@collabora.com> | 2019-05-22 02:56:11 +0100 |
commit | 4f804a48fe743ac37ee45b8a4c323cad072cdb5e (patch) | |
tree | 37272550c2018cac4784156f61d4a24ed61a6db2 | |
parent | tdf#123482 - cleanup convert-to folder even more reliably. (diff) | |
download | online-4f804a48fe743ac37ee45b8a4c323cad072cdb5e.tar.gz online-4f804a48fe743ac37ee45b8a4c323cad072cdb5e.zip |
Initial HTTP Expect: 100-continue implementation.
Change-Id: Ic9aa59cac5103151d91f6eb59d12313e545c7916
-rw-r--r-- | net/Socket.cpp | 9 | ||||
-rw-r--r-- | net/Socket.hpp | 4 | ||||
-rw-r--r-- | test/Makefile.am | 6 | ||||
-rw-r--r-- | test/UnitHTTP.cpp | 97 |
4 files changed, 114 insertions, 2 deletions
diff --git a/net/Socket.cpp b/net/Socket.cpp index c1225877af..ba72e16c11 100644 --- a/net/Socket.cpp +++ b/net/Socket.cpp @@ -681,6 +681,15 @@ bool StreamSocket::parseHeader(const char *clientName, LOG_DBG("Not enough content yet: ContentLength: " << contentLength << ", available: " << available); return false; } + + if (request.getExpectContinue() && !_sentHTTPContinue) + { + LOG_TRC("#" << getFD() << " got Expect: 100-continue, sending Continue"); + // FIXME: should validate authentication headers early too. + send("HTTP/1.1 100 Continue\r\n\r\n", + sizeof("HTTP/1.1 100 Continue\r\n\r\n") - 1); + _sentHTTPContinue = true; + } } catch (const Poco::Exception& exc) { diff --git a/net/Socket.hpp b/net/Socket.hpp index 0764df1598..5995570dcd 100644 --- a/net/Socket.hpp +++ b/net/Socket.hpp @@ -801,6 +801,7 @@ public: _bytesRecvd(0), _wsState(WSState::HTTP), _closed(false), + _sentHTTPContinue(false), _shutdownSignalled(false) { LOG_DBG("StreamSocket ctor #" << fd); @@ -1154,6 +1155,9 @@ protected: /// True if we are already closed. bool _closed; + /// True if we've received a Continue in response to an Expect: 100-continue + bool _sentHTTPContinue; + /// True when shutdown was requested via shutdown(). bool _shutdownSignalled; }; diff --git a/test/Makefile.am b/test/Makefile.am index 0432955aef..eed2abd5da 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -17,7 +17,7 @@ noinst_LTLIBRARIES = \ unit-timeout.la unit-prefork.la \ unit-storage.la unit-client.la \ unit-admin.la unit-tilecache.la \ - unit-fuzz.la unit-oob.la unit-oauth.la \ + unit-fuzz.la unit-oob.la unit-http.la unit-oauth.la \ unit-wopi.la unit-wopi-saveas.la \ unit-wopi-ownertermination.la unit-wopi-versionrestore.la \ unit-wopi-documentconflict.la unit_wopi_renamefile.la @@ -86,6 +86,7 @@ fakesockettest_LDADD = $(CPPUNIT_LIBS) # unit test modules: unit_oob_la_SOURCES = UnitOOB.cpp +unit_http_la_SOURCES = UnitHTTP.cpp unit_fuzz_la_SOURCES = UnitFuzz.cpp unit_admin_la_SOURCES = UnitAdmin.cpp unit_admin_la_LIBADD = $(CPPUNIT_LIBS) @@ -130,7 +131,8 @@ check-local: TESTS = unit-typing.la unit-convert.la unit-prefork.la unit-tilecache.la \ unit-timeout.la unit-oauth.la unit-wopi.la unit-wopi-saveas.la \ unit-wopi-ownertermination.la unit-wopi-versionrestore.la \ - unit-wopi-documentconflict.la unit_wopi_renamefile.la + unit-wopi-documentconflict.la unit_wopi_renamefile.la \ + unit-http.la # TESTS = unit-client.la # TESTS += unit-admin.la # TESTS += unit-storage.la diff --git a/test/UnitHTTP.cpp b/test/UnitHTTP.cpp new file mode 100644 index 0000000000..d0530fe101 --- /dev/null +++ b/test/UnitHTTP.cpp @@ -0,0 +1,97 @@ +/* -*- 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/. + */ + +#include <config.h> + +#include <cassert> + +#include <helpers.hpp> +#include <Poco/Util/Application.h> +#include <Poco/Net/StringPartSource.h> +#include <Poco/Net/HTMLForm.h> +#include <Poco/Net/HTTPRequest.h> +#include <Poco/Net/HTTPResponse.h> +#include <Poco/Net/HTTPSClientSession.h> + +#include <Log.hpp> +#include <Util.hpp> +#include <Unit.hpp> + +class UnitHTTP : public UnitWSD +{ +public: + UnitHTTP() + { + } + + void configure(Poco::Util::LayeredConfiguration& config) override + { + UnitWSD::configure(config); + // force HTTPS - to test harder + config.setBool("ssl.enable", true); + } + + // FIXME: can hook with (UnitWSD::get().handleHttpRequest(request, message, socket)) ... + void invokeTest() override + { + for (int i = 0; i < 3; ++i) + { + std::unique_ptr<Poco::Net::HTTPClientSession> session(helpers::createSession(Poco::URI(helpers::getTestServerURI()))); + + std::string sent = "Hello world test\n"; + + Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, "/lool/convert-to/txt"); + + switch(i) + { + case 0: + request.setExpectContinue(false); + break; + case 1: + request.setExpectContinue(true); + break; + default: + break; + } + Poco::Net::HTMLForm form; + form.setEncoding(Poco::Net::HTMLForm::ENCODING_MULTIPART); + form.set("format", "txt"); + form.addPart("data", new Poco::Net::StringPartSource(sent, "text/plain", "foobaa.txt")); + form.prepareSubmit(request); + form.write(session->sendRequest(request)); + + Poco::Net::HTTPResponse response; + std::stringstream actualStream; + std::istream& responseStream = session->receiveResponse(response); + Poco::StreamCopier::copyStream(responseStream, actualStream); + + std::string responseStr = actualStream.str(); + responseStr.erase(0,3); // remove utf-8 bom. + + if (sent != responseStr) + { + std::cerr << "Test " << i << " failed - mismatching string '" << responseStr << " vs. '" << sent << "'\n"; + exitTest(TestResult::Failed); + return; + } + } + // Give those convertors time to save and cleanup. + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + + std::cerr << "All tests passed.\n"; + exitTest(TestResult::Ok); + } +}; + +UnitBase *unit_create_wsd(void) +{ + return new UnitHTTP(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |