From 5577ad7f61fc2f7fb9c38273500b7f2267517ba1 Mon Sep 17 00:00:00 2001 From: Clinton Thomas <1033162+KernelClint@users.noreply.github.com> Date: Tue, 1 Sep 2026 14:06:32 -0400 Subject: [PATCH] http: close a connection after its response times out AI-Assisted: yes (GPT-5.6-Cyber) --- scapy/layers/http.py | 2 ++ test/scapy/layers/http.uts | 27 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/scapy/layers/http.py b/scapy/layers/http.py index ac3496fcb24..1923b344530 100644 --- a/scapy/layers/http.py +++ b/scapy/layers/http.py @@ -945,6 +945,8 @@ def request( self._connect_or_reuse(host, port=port, tls=tls, timeout=timeout) continue if not resp: + self.close() + self._sockinfo = None break # First case: auth was required. Handle that if resp.Status_Code in [b"401", b"407"]: diff --git a/test/scapy/layers/http.uts b/test/scapy/layers/http.uts index 1b132a5a614..f0aadc1b9bd 100644 --- a/test/scapy/layers/http.uts +++ b/test/scapy/layers/http.uts @@ -396,6 +396,33 @@ with run_httpserver(mech=HTTP_AUTH_MECHS.BASIC, BASIC_IDENTITIES={"user": "passw assert html == "

OK

" += HTTP - HTTP_Client discards a timed-out connection +~ http-client + +from scapy.layers.http import HTTP_Client, HTTPResponse + +class _TimeoutClient(HTTP_Client): + def __init__(self): + super().__init__(verb=False) + self.connection_count = 0 + self.close_count = 0 + self.responses = [None, HTTPResponse(Status_Code=b"200")] + def _connect_or_reuse(self, host, port=None, tls=False, timeout=5): + key = (host, port, tls) + if self._sockinfo != key: + self.connection_count += 1 + self._sockinfo = key + def sr1(self, req, **kwargs): + return self.responses.pop(0) + def close(self): + self.close_count += 1 + +client = _TimeoutClient() +assert client.request("http://example.test:80/first", timeout=0.01) is None +assert client.request("http://example.test:80/second").Status_Code == b"200" +assert client.close_count == 1 +assert client.connection_count == 2 + = HTTP - HTTP_Server with native python client without auth ~ http-client