@@ -29,7 +29,7 @@ class HTTPResponse:
29
29
status : HTTPStatus
30
30
headers : Dict [str , str ]
31
31
content_type : str
32
-
32
+ cache : Optional [ int ]
33
33
filename : Optional [str ]
34
34
root_path : str
35
35
@@ -41,6 +41,7 @@ def __init__( # pylint: disable=too-many-arguments
41
41
body : str = "" ,
42
42
headers : Dict [str , str ] = None ,
43
43
content_type : str = MIMEType .TYPE_TXT ,
44
+ cache : Optional [int ] = 0 ,
44
45
filename : Optional [str ] = None ,
45
46
root_path : str = "" ,
46
47
http_version : str = "HTTP/1.1" ,
@@ -54,6 +55,7 @@ def __init__( # pylint: disable=too-many-arguments
54
55
self .body = body
55
56
self .headers = headers or {}
56
57
self .content_type = content_type
58
+ self .cache = cache
57
59
self .filename = filename
58
60
self .root_path = root_path
59
61
self .http_version = http_version
@@ -64,8 +66,10 @@ def _construct_response_bytes( # pylint: disable=too-many-arguments
64
66
status : HTTPStatus = CommonHTTPStatus .OK_200 ,
65
67
content_type : str = MIMEType .TYPE_TXT ,
66
68
content_length : Union [int , None ] = None ,
69
+ cache : int = 0 ,
67
70
headers : Dict [str , str ] = None ,
68
71
body : str = "" ,
72
+ chunked : bool = False ,
69
73
) -> bytes :
70
74
"""Constructs the response bytes from the given parameters."""
71
75
@@ -75,12 +79,17 @@ def _construct_response_bytes( # pylint: disable=too-many-arguments
75
79
response_headers = {} if headers is None else headers .copy ()
76
80
77
81
response_headers .setdefault ("Content-Type" , content_type )
78
- response_headers .setdefault ("Content-Length" , content_length or len (body ))
79
82
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 ))
80
87
81
88
for header , value in response_headers .items ():
82
89
response += f"{ header } : { value } \r \n "
83
90
91
+ response += f"Cache-Control: max-age={ cache } \r \n "
92
+
84
93
response += f"\r \n { body } "
85
94
86
95
return response .encode ("utf-8" )
@@ -116,6 +125,33 @@ def send(self, conn: Union["SocketPool.Socket", "socket.socket"]) -> None:
116
125
body = self .body ,
117
126
)
118
127
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
+
119
155
def _send_response ( # pylint: disable=too-many-arguments
120
156
self ,
121
157
conn : Union ["SocketPool.Socket" , "socket.socket" ],
@@ -129,6 +165,7 @@ def _send_response( # pylint: disable=too-many-arguments
129
165
self ._construct_response_bytes (
130
166
status = status ,
131
167
content_type = content_type ,
168
+ cache = self .cache ,
132
169
headers = headers ,
133
170
body = body ,
134
171
),
@@ -148,6 +185,7 @@ def _send_file_response( # pylint: disable=too-many-arguments
148
185
status = self .status ,
149
186
content_type = MIMEType .from_file_name (filename ),
150
187
content_length = file_length ,
188
+ cache = self .cache ,
151
189
headers = headers ,
152
190
),
153
191
)
0 commit comments