summaryrefslogtreecommitdiffstats
path: root/vespalib
diff options
context:
space:
mode:
authorTor Brede Vekterli <vekterli@oath.com>2018-12-11 12:57:22 +0100
committerGitHub <noreply@github.com>2018-12-11 12:57:22 +0100
commit4d7114a97e4ee22ade4e2ed933d19ccb34bff744 (patch)
tree0bc8c6bb4e7b9385ef2829de87ffd115442a725c /vespalib
parent2a0588f520137e30acf91ab7e601bff638ac52a7 (diff)
parentee9e86725a4fbd32c5c214c1a95b0fcf4b0f3db1 (diff)
Merge pull request #7922 from vespa-engine/havardpe/prepare-for-tls-state-server
Havardpe/prepare for tls state server
Diffstat (limited to 'vespalib')
-rw-r--r--vespalib/src/tests/portal/portal_test.cpp49
-rw-r--r--vespalib/src/vespa/vespalib/portal/http_connection.h1
-rw-r--r--vespalib/src/vespa/vespalib/portal/portal.cpp8
-rw-r--r--vespalib/src/vespa/vespalib/portal/portal.h2
4 files changed, 54 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 <vespa/vespalib/portal/portal.h>
#include <vespa/vespalib/util/exceptions.h>
#include <vespa/vespalib/util/stringfmt.h>
+#include <vespa/vespalib/util/host_name.h>
#include <vespa/vespalib/net/socket_spec.h>
#include <vespa/vespalib/net/crypto_engine.h>
#include <vespa/vespalib/net/sync_crypto_socket.h>
@@ -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..031f364faff 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 <vespa/vespalib/util/stringfmt.h>
+#include <vespa/vespalib/util/host_name.h>
#include <cassert>
namespace vespalib {
@@ -111,6 +113,7 @@ Portal::evict_handle(uint64_t handle)
void
Portal::handle_accept(portal::HandleGuard guard, SocketHandle socket)
{
+ socket.set_keepalive(true);
new HttpConnection(std::move(guard), _reactor, _crypto->create_crypto_socket(std::move(socket), true),
[this](HttpConnection *conn)
{
@@ -131,6 +134,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 +153,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<portal::Listener>(_reactor, port,
[this](SocketHandle socket)
@@ -159,6 +164,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..aa696c85fa2 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<BindState> _bind_list;
+ vespalib::string _my_host;
Token::UP make_token();
void cancel_token(Token &token);
@@ -108,6 +109,7 @@ public:
~Portal();
static SP create(CryptoEngine::SP crypto, int port);
int listen_port() const { return _listener->listen_port(); }
+ const vespalib::string &my_host() const { return _my_host; }
Token::UP bind(const vespalib::string &path_prefix, const GetHandler &handler);
};