@@ -23,7 +23,6 @@ def test_no_408_while_response_in_progress(self):
2323 """Connection streaming file response should not get 408 timeout"""
2424 temp_dir = tempfile .mkdtemp ()
2525 large_file = os .path .join (temp_dir , 'large.bin' )
26- # Large file with tiny chunk size ensures streaming takes multiple iterations
2726 with open (large_file , 'wb' ) as f :
2827 f .write (b'X' * 200_000 )
2928
@@ -32,15 +31,13 @@ def test_no_408_while_response_in_progress(self):
3231 trigger_sock = None
3332
3433 try :
35- # Connect and send request
3634 client_sock = socket .socket (socket .AF_INET , socket .SOCK_STREAM )
3735 client_sock .connect (('localhost' , self .PORT ))
3836 client_sock .setblocking (False )
3937 client_sock .send (
4038 b"GET / HTTP/1.1\r \n Host: localhost\r \n \r \n " )
4139 time .sleep (0.1 )
4240
43- # Get loaded connection
4441 connection = None
4542 for _ in range (10 ):
4643 r , _ , _ = select .select (server .read_sockets , [], [], 0.1 )
@@ -50,14 +47,13 @@ def test_no_408_while_response_in_progress(self):
5047 break
5148 self .assertIsNotNone (connection )
5249
53- # Start file response - streaming keeps _response_started True
5450 connection .respond_file (large_file )
5551 self .assertTrue (connection ._response_started )
5652
5753 # Wait longer than keep_alive_timeout
5854 time .sleep (0.5 )
5955
60- # Trigger cleanup via event_read ( new connection triggers accept)
56+ # Trigger cleanup via new connection
6157 trigger_sock = socket .socket (socket .AF_INET , socket .SOCK_STREAM )
6258 trigger_sock .connect (('localhost' , self .PORT ))
6359 time .sleep (0.1 )
@@ -66,12 +62,11 @@ def test_no_408_while_response_in_progress(self):
6662 if r :
6763 server .event_read (r )
6864
69- # Connection should still be alive (not closed by 408)
7065 self .assertIsNotNone (
7166 connection .socket ,
7267 "Connection should not be closed while response is in progress" )
7368
74- # Drain the response to verify it's still valid
69+ # Drain the response
7570 response = b""
7671 for _ in range (200 ):
7772 w = server .write_sockets
@@ -95,44 +90,57 @@ def test_no_408_while_response_in_progress(self):
9590 client_sock .close ()
9691 if trigger_sock :
9792 trigger_sock .close ()
93+ # Close server first so file handles are released (Windows)
9894 server .close ()
99- os .unlink (large_file )
100- os .rmdir (temp_dir )
95+ time .sleep (0.1 )
96+ try :
97+ os .unlink (large_file )
98+ os .rmdir (temp_dir )
99+ except OSError :
100+ pass
101101
102102 def test_idle_keepalive_still_gets_408 (self ):
103103 """Idle keep-alive connection (no response started) should still get 408"""
104104 server = uhttp_server .HttpServer (
105105 port = self .PORT + 1 , keep_alive_timeout = 0.3 )
106+ trigger_sock = None
106107
107108 try :
108- # Connect but don't send a full request (simulate idle keep-alive)
109109 client_sock = socket .socket (socket .AF_INET , socket .SOCK_STREAM )
110110 client_sock .connect (('localhost' , self .PORT + 1 ))
111111 client_sock .setblocking (False )
112112
113- # Send partial request to create connection in waiting pool
114113 client_sock .send (
115114 b"GET / HTTP/1.1\r \n Host: localhost\r \n \r \n " )
116115 time .sleep (0.1 )
117116
118- # Process the request
119- r , _ , _ = select .select (server .read_sockets , [], [], 0.2 )
120- if r :
121- connection = server .event_read (r )
122- if connection :
123- # Respond and let keep-alive reset
124- connection .respond ('ok' )
125- # Flush send buffer
126- for _ in range (10 ):
127- w = server .write_sockets
128- if w :
129- _ , ww , _ = select .select ([], w , [], 0.1 )
130- if ww :
131- server .event_write (ww )
132- else :
133- break
134-
135- # Wait for timeout
117+ # Process the request and respond
118+ for _ in range (10 ):
119+ r , _ , _ = select .select (server .read_sockets , [], [], 0.1 )
120+ if r :
121+ connection = server .event_read (r )
122+ if connection :
123+ connection .respond ('ok' )
124+ break
125+
126+ # Flush send buffer
127+ for _ in range (20 ):
128+ w = server .write_sockets
129+ if w :
130+ _ , ww , _ = select .select ([], w , [], 0.1 )
131+ if ww :
132+ server .event_write (ww )
133+ else :
134+ break
135+
136+ # Drain the first response
137+ try :
138+ while True :
139+ client_sock .recv (4096 )
140+ except BlockingIOError :
141+ pass
142+
143+ # Wait for keep-alive timeout
136144 time .sleep (0.5 )
137145
138146 # Trigger cleanup
@@ -144,16 +152,21 @@ def test_idle_keepalive_still_gets_408(self):
144152 if r :
145153 server .event_read (r )
146154
155+ # Flush 408 response
156+ for _ in range (20 ):
157+ w = server .write_sockets
158+ if w :
159+ _ , ww , _ = select .select ([], w , [], 0.1 )
160+ if ww :
161+ server .event_write (ww )
162+ else :
163+ break
164+
147165 # Read the 408 response
166+ time .sleep (0.1 )
148167 response = b""
149168 try :
150169 for _ in range (10 ):
151- # Flush server writes
152- w = server .write_sockets
153- if w :
154- _ , ww , _ = select .select ([], w , [], 0.1 )
155- if ww :
156- server .event_write (ww )
157170 chunk = client_sock .recv (4096 )
158171 if chunk :
159172 response += chunk
@@ -166,7 +179,8 @@ def test_idle_keepalive_still_gets_408(self):
166179
167180 finally :
168181 client_sock .close ()
169- trigger_sock .close ()
182+ if trigger_sock :
183+ trigger_sock .close ()
170184 server .close ()
171185
172186
0 commit comments