11import enum
22import io
3+ import time
34import typing
45
56from ._streams import Stream
@@ -89,6 +90,7 @@ def __init__(self, stream: Stream, mode: str) -> None:
8990 self .stream = stream
9091 self .parser = ReadAheadParser (stream )
9192 self .mode = {'CLIENT' : Mode .CLIENT , 'SERVER' : Mode .SERVER }[mode ]
93+ self .keepalive_duration = 5.0
9294
9395 # Track state...
9496 if self .mode == Mode .CLIENT :
@@ -107,6 +109,7 @@ def __init__(self, stream: Stream, mode: str) -> None:
107109 # Track connection keep alive...
108110 self .send_keep_alive = True
109111 self .recv_keep_alive = True
112+ self .keepalive_until : float | None = None
110113
111114 # Special states...
112115 self .processing_1xx = False
@@ -119,6 +122,9 @@ async def send_method_line(self, method: bytes, target: bytes, protocol: bytes)
119122
120123 Sending state will switch to SEND_HEADERS state.
121124 """
125+ # Scrub connection keepalive
126+ self .keepalive_until = None
127+
122128 if self .send_state != State .SEND_METHOD_LINE :
123129 msg = f"Called 'send_method_line' in invalid state { self .send_state } "
124130 raise ProtocolError (msg )
@@ -244,6 +250,9 @@ async def recv_method_line(self) -> tuple[bytes, bytes, bytes]:
244250
245251 Receive state will switch to RECV_HEADERS.
246252 """
253+ # Scrub connection keepalive
254+ self .keepalive_until = None
255+
247256 if self .recv_state != State .RECV_METHOD_LINE :
248257 msg = f"Called 'recv_method_line' in invalid state { self .recv_state } "
249258 raise ProtocolError (msg )
@@ -409,6 +418,7 @@ async def complete(self):
409418 self .send_keep_alive = True
410419 self .recv_keep_alive = True
411420 self .processing_1xx = False
421+ self .keepalive_until = time .monotonic () + self .keepalive_duration
412422
413423 async def close (self ):
414424 if self .send_state != State .CLOSED :
@@ -425,6 +435,9 @@ def is_idle(self) -> bool:
425435 def is_closed (self ) -> bool :
426436 return self .send_state == State .CLOSED
427437
438+ def keepalive_expired (self ) -> bool :
439+ return (self .keepalive_until is not None ) and (time .monotonic () > self .keepalive_until )
440+
428441 def description (self ) -> str :
429442 return {
430443 State .SEND_METHOD_LINE : "idle" ,
@@ -439,10 +452,9 @@ def __repr__(self) -> str:
439452
440453
441454class HTTPStream (Stream ):
442- def __init__ (self , parser : HTTPParser , callback : typing . Callable | None = None ):
455+ def __init__ (self , parser : HTTPParser ):
443456 self ._parser = parser
444457 self ._buffer = io .BytesIO ()
445- self ._callback = callback
446458
447459 async def read (self , size = - 1 ) -> bytes :
448460 sections = []
@@ -474,12 +486,8 @@ async def read(self, size=-1) -> bytes:
474486 return output
475487
476488 async def close (self ) -> None :
477- try :
478- self ._buffer .close ()
479- await self ._parser .complete ()
480- finally :
481- if self ._callback is not None :
482- await self ._callback ()
489+ self ._buffer .close ()
490+ await self ._parser .complete ()
483491
484492
485493class ReadAheadParser :
0 commit comments