mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 05:52:46 +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:
		
							parent
							
								
									e770cf06b0
								
							
						
					
					
						commit
						cd4ebc45a0
					
				
					 2 changed files with 23 additions and 2 deletions
				
			
		|  | @ -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.
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Ali Mohammad Pur
						Ali Mohammad Pur