]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
tests/http: add abrupt server close test master
authorDaniel McCarney <daniel@binaryparadox.net>
Wed, 8 Apr 2026 20:28:06 +0000 (16:28 -0400)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 10 Apr 2026 13:58:39 +0000 (15:58 +0200)
Test that connecting to a server that immediately closes the connection
produces an error instead of hanging/timing out.

tests/http/test_05_errors.py

index 7a64e3055d28be022c9809724783691d7af7aa60..c50310404f8d5e1a15f1ee7a92dc9c3a9014cd12 100644 (file)
@@ -26,6 +26,8 @@
 #
 import logging
 import os
+import socket
+import threading
 
 import pytest
 from testenv import CurlClient, Env
@@ -179,3 +181,34 @@ class TestErrors:
         r.check_response(http_status=401)
         # No retries on a 401
         assert r.stats[0]['num_retries'] == 0, f'{r}'
+
+    # Server closes the connection immediately after accept,
+    def test_05_09_handshake_eof(self, env: Env, httpd, nghttpx):
+        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server:
+            server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+            server.bind(('127.0.0.1', 0))
+            server.listen(1)
+            port = server.getsockname()[1]
+
+            # accept one connection and immediately close it
+            def accept_and_close():
+                try:
+                    conn, _ = server.accept()
+                    conn.close()
+                except Exception:
+                    pass
+
+            t = threading.Thread(target=accept_and_close)
+            t.start()
+
+            curl = CurlClient(env=env, timeout=5)
+            url = f'https://127.0.0.1:{port}/'
+            r = curl.run_direct(args=[url, '--insecure'])
+
+            t.join(timeout=2)
+
+        # We expect an error code, not success (0) and not timeout (-1)
+        # Expected error code is:
+        # - CURLE_SSL_CONNECT_ERROR (35) - common for handshake failures
+        assert r.exit_code == 35, \
+            f'Expected error 35, got {r.exit_code}\n{r.dump_logs()}'