alternator: add content length limit to alternator servers

This patch adds a 16MB content length limit to alternator
HTTP(S) servers. It also comes with a test, which verifies
that larger requests are refused.

Fixes #5832

Tests: alternator-test(local,remote)

Message-Id: <29d5708f4bf9f41883d33d21b9cca72b05170e6c.1582285070.git.sarna@scylladb.com>
This commit is contained in:
Piotr Sarna
2020-02-21 12:40:50 +01:00
committed by Nadav Har'El
parent 085cd857ab
commit 4ad577b40c
3 changed files with 17 additions and 1 deletions

View File

@@ -19,7 +19,7 @@
import pytest
import requests
from botocore.exceptions import ClientError
from botocore.exceptions import BotoCoreError, ClientError
def gen_json(n):
return '{"":'*n + '{}' + '}'*n
@@ -78,3 +78,13 @@ def test_exceed_nested_level_a_little(dynamodb, test_table):
with pytest.raises(ClientError, match='ValidationException.*nested'):
test_table.put_item(Item={'p': p, 'c': c, 'nested': nested})
def test_too_large_request(dynamodb, test_table):
p = 'abc'
c = 'def'
big = 'x' * (16 * 1024 * 1024 + 7)
# The exception type differs due to differences between HTTP servers
# in alternator and DynamoDB. The former returns 413, the latter
# a ClientError explaining that the element size was too large.
with pytest.raises(BotoCoreError):
test_table.put_item(Item={'p': p, 'c': c, 'big': big})

View File

@@ -358,6 +358,9 @@ future<> server::init(net::inet_address addr, std::optional<uint16_t> port, std:
_control.start().get();
_control.set_routes(std::bind(&server::set_routes, this, std::placeholders::_1)).get();
_control.listen(socket_address{addr, *port}).get();
_control.server().invoke_on_all([] (http_server& serv) {
serv.set_content_length_limit(server::content_length_limit);
}).get();
_enabled_servers.push_back(std::ref(_control));
slogger.info("Alternator HTTP server listening on {} port {}", addr, *port);
}
@@ -365,6 +368,7 @@ future<> server::init(net::inet_address addr, std::optional<uint16_t> port, std:
_https_control.start().get();
_https_control.set_routes(std::bind(&server::set_routes, this, std::placeholders::_1)).get();
_https_control.server().invoke_on_all([creds] (http_server& serv) {
serv.set_content_length_limit(server::content_length_limit);
return serv.set_tls_credentials(creds->build_server_credentials());
}).get();

View File

@@ -28,10 +28,12 @@
#include <optional>
#include <alternator/auth.hh>
#include <utils/small_vector.hh>
#include <seastar/core/units.hh>
namespace alternator {
class server {
static constexpr size_t content_length_limit = 16*MB;
using alternator_callback = std::function<future<executor::request_return_type>(executor&, executor::client_state&, tracing::trace_state_ptr, std::unique_ptr<request>)>;
using alternator_callbacks_map = std::unordered_map<std::string_view, alternator_callback>;