@@ -30,7 +30,7 @@ class HTTPResponse:
30
30
status : HTTPStatus
31
31
headers : HTTPHeaders
32
32
content_type : str
33
-
33
+ cache : Optional [ int ]
34
34
filename : Optional [str ]
35
35
root_path : str
36
36
@@ -42,6 +42,7 @@ def __init__( # pylint: disable=too-many-arguments
42
42
body : str = "" ,
43
43
headers : Union [HTTPHeaders , Dict [str , str ]] = None ,
44
44
content_type : str = MIMEType .TYPE_TXT ,
45
+ cache : Optional [int ] = 0 ,
45
46
filename : Optional [str ] = None ,
46
47
root_path : str = "" ,
47
48
http_version : str = "HTTP/1.1" ,
@@ -57,6 +58,7 @@ def __init__( # pylint: disable=too-many-arguments
57
58
headers .copy () if isinstance (headers , HTTPHeaders ) else HTTPHeaders (headers )
58
59
)
59
60
self .content_type = content_type
61
+ self .cache = cache
60
62
self .filename = filename
61
63
self .root_path = root_path
62
64
self .http_version = http_version
@@ -67,8 +69,10 @@ def _construct_response_bytes( # pylint: disable=too-many-arguments
67
69
status : HTTPStatus = CommonHTTPStatus .OK_200 ,
68
70
content_type : str = MIMEType .TYPE_TXT ,
69
71
content_length : Union [int , None ] = None ,
70
- headers : HTTPHeaders = None ,
72
+ cache : int = 0 ,
73
+ headers : Dict [str , str ] = None ,
71
74
body : str = "" ,
75
+ chunked : bool = False ,
72
76
) -> bytes :
73
77
"""Constructs the response bytes from the given parameters."""
74
78
@@ -81,11 +85,21 @@ def _construct_response_bytes( # pylint: disable=too-many-arguments
81
85
)
82
86
headers .setdefault ("Connection" , "close" )
83
87
84
- for header , value in headers .items ():
85
- response_message_header += f"{ header } : { value } \r \n "
86
- response_message_header += "\r \n "
88
+ response_headers .setdefault ("Content-Type" , content_type )
89
+ response_headers .setdefault ("Connection" , "close" )
90
+ if chunked :
91
+ response_headers .setdefault ("Transfer-Encoding" , "chunked" )
92
+ else :
93
+ response_headers .setdefault ("Content-Length" , content_length or len (body ))
94
+
95
+ for header , value in response_headers .items ():
96
+ response += f"{ header } : { value } \r \n "
97
+
98
+ response += f"Cache-Control: max-age={ cache } \r \n "
87
99
88
- return response_message_header .encode ("utf-8" ) + encoded_response_message_body
100
+ response += f"\r \n { body } "
101
+
102
+ return response .encode ("utf-8" )
89
103
90
104
def send (self , conn : Union ["SocketPool.Socket" , "socket.socket" ]) -> None :
91
105
"""
@@ -118,6 +132,33 @@ def send(self, conn: Union["SocketPool.Socket", "socket.socket"]) -> None:
118
132
body = self .body ,
119
133
)
120
134
135
+ def send_chunk_headers (
136
+ self , conn : Union ["SocketPool.Socket" , "socket.socket" ]
137
+ ) -> None :
138
+ """Send Headers for a chunked response over the given socket."""
139
+ self ._send_bytes (
140
+ conn ,
141
+ self ._construct_response_bytes (
142
+ status = self .status ,
143
+ content_type = self .content_type ,
144
+ chunked = True ,
145
+ cache = self .cache ,
146
+ body = "" ,
147
+ ),
148
+ )
149
+
150
+ def send_body_chunk (
151
+ self , conn : Union ["SocketPool.Socket" , "socket.socket" ], chunk : str
152
+ ) -> None :
153
+ """Send chunk of data to the given socket. Send an empty("") chunk to finish the session.
154
+
155
+ :param Union["SocketPool.Socket", "socket.socket"] conn: Current connection.
156
+ :param str chunk: String data to be sent.
157
+ """
158
+ size = "%X\r \n " .encode () % len (chunk )
159
+ self ._send_bytes (conn , size )
160
+ self ._send_bytes (conn , chunk .encode () + b"\r \n " )
161
+
121
162
def _send_response ( # pylint: disable=too-many-arguments
122
163
self ,
123
164
conn : Union ["SocketPool.Socket" , "socket.socket" ],
@@ -131,6 +172,7 @@ def _send_response( # pylint: disable=too-many-arguments
131
172
self ._construct_response_bytes (
132
173
status = status ,
133
174
content_type = content_type ,
175
+ cache = self .cache ,
134
176
headers = headers ,
135
177
body = body ,
136
178
),
@@ -150,6 +192,7 @@ def _send_file_response( # pylint: disable=too-many-arguments
150
192
status = self .status ,
151
193
content_type = MIMEType .from_file_name (filename ),
152
194
content_length = file_length ,
195
+ cache = self .cache ,
153
196
headers = headers ,
154
197
),
155
198
)
0 commit comments