@@ -29,7 +29,7 @@ class HTTPResponse:
2929 status : HTTPStatus
3030 headers : Dict [str , str ]
3131 content_type : str
32-
32+ cache : Optional [ int ]
3333 filename : Optional [str ]
3434 root_path : str
3535
@@ -41,6 +41,7 @@ def __init__( # pylint: disable=too-many-arguments
4141 body : str = "" ,
4242 headers : Dict [str , str ] = None ,
4343 content_type : str = MIMEType .TYPE_TXT ,
44+ cache : Optional [int ] = 0 ,
4445 filename : Optional [str ] = None ,
4546 root_path : str = "" ,
4647 http_version : str = "HTTP/1.1" ,
@@ -54,6 +55,7 @@ def __init__( # pylint: disable=too-many-arguments
5455 self .body = body
5556 self .headers = headers or {}
5657 self .content_type = content_type
58+ self .cache = cache
5759 self .filename = filename
5860 self .root_path = root_path
5961 self .http_version = http_version
@@ -64,8 +66,10 @@ def _construct_response_bytes( # pylint: disable=too-many-arguments
6466 status : HTTPStatus = CommonHTTPStatus .OK_200 ,
6567 content_type : str = MIMEType .TYPE_TXT ,
6668 content_length : Union [int , None ] = None ,
69+ cache : int = 0 ,
6770 headers : Dict [str , str ] = None ,
6871 body : str = "" ,
72+ chunked : bool = False ,
6973 ) -> bytes :
7074 """Constructs the response bytes from the given parameters."""
7175
@@ -75,12 +79,17 @@ def _construct_response_bytes( # pylint: disable=too-many-arguments
7579 response_headers = {} if headers is None else headers .copy ()
7680
7781 response_headers .setdefault ("Content-Type" , content_type )
78- response_headers .setdefault ("Content-Length" , content_length or len (body ))
7982 response_headers .setdefault ("Connection" , "close" )
83+ if chunked :
84+ response_headers .setdefault ("Transfer-Encoding" , "chunked" )
85+ else :
86+ response_headers .setdefault ("Content-Length" , content_length or len (body ))
8087
8188 for header , value in response_headers .items ():
8289 response += f"{ header } : { value } \r \n "
8390
91+ response += f"Cache-Control: max-age={ cache } \r \n "
92+
8493 response += f"\r \n { body } "
8594
8695 return response .encode ("utf-8" )
@@ -116,6 +125,33 @@ def send(self, conn: Union["SocketPool.Socket", "socket.socket"]) -> None:
116125 body = self .body ,
117126 )
118127
128+ def send_chunk_headers (
129+ self , conn : Union ["SocketPool.Socket" , "socket.socket" ]
130+ ) -> None :
131+ """Send Headers for a chunked response over the given socket."""
132+ self ._send_bytes (
133+ conn ,
134+ self ._construct_response_bytes (
135+ status = self .status ,
136+ content_type = self .content_type ,
137+ chunked = True ,
138+ cache = self .cache ,
139+ body = "" ,
140+ ),
141+ )
142+
143+ def send_body_chunk (
144+ self , conn : Union ["SocketPool.Socket" , "socket.socket" ], chunk : str
145+ ) -> None :
146+ """Send chunk of data to the given socket. Send an empty("") chunk to finish the session.
147+
148+ :param Union["SocketPool.Socket", "socket.socket"] conn: Current connection.
149+ :param str chunk: String data to be sent.
150+ """
151+ size = "%X\r \n " .encode () % len (chunk )
152+ self ._send_bytes (conn , size )
153+ self ._send_bytes (conn , chunk .encode () + b"\r \n " )
154+
119155 def _send_response ( # pylint: disable=too-many-arguments
120156 self ,
121157 conn : Union ["SocketPool.Socket" , "socket.socket" ],
@@ -129,6 +165,7 @@ def _send_response( # pylint: disable=too-many-arguments
129165 self ._construct_response_bytes (
130166 status = status ,
131167 content_type = content_type ,
168+ cache = self .cache ,
132169 headers = headers ,
133170 body = body ,
134171 ),
@@ -148,6 +185,7 @@ def _send_file_response( # pylint: disable=too-many-arguments
148185 status = self .status ,
149186 content_type = MIMEType .from_file_name (filename ),
150187 content_length = file_length ,
188+ cache = self .cache ,
151189 headers = headers ,
152190 ),
153191 )
0 commit comments