From 7ba28f6a6d3c1e1bb8195c7c0b81b36abe3327f8 Mon Sep 17 00:00:00 2001 From: HÃ¥vard Pettersen Date: Fri, 7 Dec 2018 12:27:31 +0000 Subject: make authority available to GET handler also test header inspection --- vespalib/src/tests/portal/portal_test.cpp | 49 +++++++++++++++++++--- .../src/vespa/vespalib/portal/http_connection.h | 1 + vespalib/src/vespa/vespalib/portal/portal.cpp | 7 +++- vespalib/src/vespa/vespalib/portal/portal.h | 1 + 4 files changed, 52 insertions(+), 6 deletions(-) diff --git a/vespalib/src/tests/portal/portal_test.cpp b/vespalib/src/tests/portal/portal_test.cpp index a277914bef5..6d0d04620d0 100644 --- a/vespalib/src/tests/portal/portal_test.cpp +++ b/vespalib/src/tests/portal/portal_test.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -16,13 +17,14 @@ using namespace vespalib; //----------------------------------------------------------------------------- -vespalib::string do_http(int port, CryptoEngine::SP crypto, const vespalib::string &method, const vespalib::string &uri) { +vespalib::string do_http(int port, CryptoEngine::SP crypto, const vespalib::string &method, const vespalib::string &uri, bool send_host = true) { auto socket = SocketSpec::from_port(port).client_address().connect(); ASSERT_TRUE(socket.valid()); auto conn = SyncCryptoSocket::create(*crypto, std::move(socket), false); vespalib::string http_req = vespalib::make_string("%s %s HTTP/1.1\r\n" - "Host: localhost:%d\r\n" - "\r\n", method.c_str(), uri.c_str(), port); + "My-Header: my value\r\n" + "%s" + "\r\n", method.c_str(), uri.c_str(), send_host ? "Host: HOST:42\r\n" : ""); ASSERT_EQUAL(conn->write(http_req.data(), http_req.size()), ssize_t(http_req.size())); char buf[1024]; vespalib::string result; @@ -35,8 +37,8 @@ vespalib::string do_http(int port, CryptoEngine::SP crypto, const vespalib::stri return result; } -vespalib::string fetch(int port, CryptoEngine::SP crypto, const vespalib::string &path) { - return do_http(port, std::move(crypto), "GET", path); +vespalib::string fetch(int port, CryptoEngine::SP crypto, const vespalib::string &path, bool send_host = true) { + return do_http(port, std::move(crypto), "GET", path, send_host); } //----------------------------------------------------------------------------- @@ -124,6 +126,43 @@ TEST("require that simple GET works with various encryption strategies") { //----------------------------------------------------------------------------- +TEST("require that header values can be inspected") { + auto portal = Portal::create(null_crypto(), 0); + MyGetHandler handler([](Portal::GetRequest request) + { + EXPECT_EQUAL(request.get_header("my-header"), "my value"); + request.respond_with_content("a", "b"); + }); + auto bound = portal->bind("/test", handler); + auto result = fetch(portal->listen_port(), null_crypto(), "/test"); + EXPECT_EQUAL(result, make_expected_response("a", "b")); +} + +TEST("require that request authority can be obtained") { + auto portal = Portal::create(null_crypto(), 0); + MyGetHandler handler([](Portal::GetRequest request) + { + EXPECT_EQUAL(request.get_host(), "HOST:42"); + request.respond_with_content("a", "b"); + }); + auto bound = portal->bind("/test", handler); + auto result = fetch(portal->listen_port(), null_crypto(), "/test"); + EXPECT_EQUAL(result, make_expected_response("a", "b")); +} + +TEST("require that authority has reasonable fallback") { + auto portal = Portal::create(null_crypto(), 0); + auto expect_host = vespalib::make_string("%s:%d", HostName::get().c_str(), portal->listen_port()); + MyGetHandler handler([&expect_host](Portal::GetRequest request) + { + EXPECT_EQUAL(request.get_host(), expect_host); + request.respond_with_content("a", "b"); + }); + auto bound = portal->bind("/test", handler); + auto result = fetch(portal->listen_port(), null_crypto(), "/test", false); + EXPECT_EQUAL(result, make_expected_response("a", "b")); +} + TEST("require that methods other than GET return not implemented error") { auto portal = Portal::create(null_crypto(), 0); auto expect_get = make_expected_error(404, "Not Found"); diff --git a/vespalib/src/vespa/vespalib/portal/http_connection.h b/vespalib/src/vespa/vespalib/portal/http_connection.h index 296a915c873..5deb4d5e81f 100644 --- a/vespalib/src/vespa/vespalib/portal/http_connection.h +++ b/vespalib/src/vespa/vespalib/portal/http_connection.h @@ -45,6 +45,7 @@ public: ~HttpConnection(); void handle_event(bool read, bool write) override; State get_state() const { return _state; } + void resolve_host(const vespalib::string &my_host) { _request.resolve_host(my_host); } const HttpRequest &get_request() const { return _request; } void respond_with_content(const vespalib::string &content_type, const vespalib::string &content); diff --git a/vespalib/src/vespa/vespalib/portal/portal.cpp b/vespalib/src/vespa/vespalib/portal/portal.cpp index c96d7f9f83e..cfd80b41ac7 100644 --- a/vespalib/src/vespa/vespalib/portal/portal.cpp +++ b/vespalib/src/vespa/vespalib/portal/portal.cpp @@ -2,6 +2,8 @@ #include "portal.h" #include "http_connection.h" +#include +#include #include namespace vespalib { @@ -131,6 +133,7 @@ Portal::handle_http(portal::HttpConnection *conn) auto guard = lookup_get_handler(conn->get_request().get_uri(), get_handler); if (guard.valid()) { assert(get_handler != nullptr); + conn->resolve_host(_my_host); get_handler->get(GetRequest(*conn)); } else { conn->respond_with_error(404, "Not Found"); @@ -149,7 +152,8 @@ Portal::Portal(CryptoEngine::SP crypto, int port) _conn_handle(_handle_manager.create()), _listener(), _lock(), - _bind_list() + _bind_list(), + _my_host() { _listener = std::make_unique(_reactor, port, [this](SocketHandle socket) @@ -159,6 +163,7 @@ Portal::Portal(CryptoEngine::SP crypto, int port) handle_accept(std::move(guard), std::move(socket)); } }); + _my_host = vespalib::make_string("%s:%d", HostName::get().c_str(), listen_port()); } Portal::~Portal() diff --git a/vespalib/src/vespa/vespalib/portal/portal.h b/vespalib/src/vespa/vespalib/portal/portal.h index 0c75734de0b..5ce0ec30b2d 100644 --- a/vespalib/src/vespa/vespalib/portal/portal.h +++ b/vespalib/src/vespa/vespalib/portal/portal.h @@ -93,6 +93,7 @@ private: portal::Listener::UP _listener; std::mutex _lock; std::vector _bind_list; + vespalib::string _my_host; Token::UP make_token(); void cancel_token(Token &token); -- cgit v1.2.3