1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 14:38:11 +00:00

RequestServer: Avoid multiple connections to incompatible servers

This really only implements a heuristic, assuming that HTTP/1.0 servers
cannot handle having multiple active connections; this assumption has
lots of false positives, but ultimately HTTP/1.0 is an out-of-date HTTP
version and people using it should just switch to a newer standard
anyway.

Specifically, python's "SimpleHTTPRequestHandler" utilises a
single-threaded HTTP/1.0 server, which means no keepalive and more
importantly, hangs and races with more than a single connection present.
This commit makes it so we serialise all requests to servers that are
known to serve only a single request per connection (aka HTTP/1.0 with
our setup, as we unconditionally request keepalive)
This commit is contained in:
Ali Mohammad Pur 2024-01-06 09:24:26 +03:30 committed by Andreas Kling
parent e770cf06b0
commit cd4ebc45a0
2 changed files with 23 additions and 2 deletions

View file

@ -13,6 +13,7 @@ namespace RequestServer::ConnectionCache {
HashMap<ConnectionKey, NonnullOwnPtr<Vector<NonnullOwnPtr<Connection<Core::TCPSocket, Core::Socket>>>>> g_tcp_connection_cache {};
HashMap<ConnectionKey, NonnullOwnPtr<Vector<NonnullOwnPtr<Connection<TLS::TLSv12>>>>> g_tls_connection_cache {};
HashMap<ByteString, InferredServerProperties> g_inferred_server_properties;
void request_did_finish(URL const& url, Core::Socket const* socket)
{
@ -37,6 +38,10 @@ void request_did_finish(URL const& url, Core::Socket const* socket)
}
auto& connection = *connection_it;
auto& properties = g_inferred_server_properties.ensure(partial_key.hostname);
if (!connection->socket->is_open())
properties.requests_served_per_connection = min(properties.requests_served_per_connection, connection->max_queue_length + 1);
if (connection->request_queue.is_empty()) {
// Immediately mark the connection as finished, as new jobs will never be run if they are queued
// before the deferred_invoke() below runs otherwise.