Skip to content

Commit 22b57fd

Browse files
committed
Merge branch 'Add_Chunk_Responses' into my-main
# Conflicts: # adafruit_httpserver.py
2 parents 8aa5ead + 2a0c7e6 commit 22b57fd

File tree

1 file changed

+42
-2
lines changed

1 file changed

+42
-2
lines changed

adafruit_httpserver.py

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,14 @@ class HTTPResponse:
194194
"\r\n"
195195
)
196196

197+
_CHUNK_HEADERS_FORMAT = (
198+
"HTTP/1.1 {}\r\n"
199+
"Content-Type: {}\r\n"
200+
"Transfer-Encoding: chunked\r\n"
201+
"Connection: close\r\n"
202+
"\r\n"
203+
)
204+
197205
def __init__(
198206
self,
199207
*,
@@ -244,6 +252,22 @@ def send(self, conn: Any) -> None:
244252
else:
245253
self._send_response(conn, self.status, self.content_type, self.body, self.cache)
246254

255+
def send_chunk_headers(self, conn: Any):
256+
"""Send Headers for a chunked response over the given socket."""
257+
self._send_bytes(
258+
conn, self._CHUNK_HEADERS_FORMAT.format(self.status, self.content_type)
259+
)
260+
261+
def send_body_chunk(self, conn: Any, chunk: str):
262+
"""Send chunk of data to the given socket. Send an empty("") chunk to finish the session.
263+
264+
:param Any conn: Current connection.
265+
:param str chunk: String data to be sent.
266+
"""
267+
size="%X\r\n".encode() % len(chunk)
268+
self._send_bytes(conn, size)
269+
self._send_bytes(conn, chunk.encode() + b'\r\n')
270+
247271
def _send_response(self, conn, status, content_type, body, cache):
248272
self._send_bytes(
249273
conn, self._HEADERS_FORMAT.format(status, content_type, len(body), cache)
@@ -305,7 +329,17 @@ def route_func(request):
305329
raw_text = request.raw_request.decode("utf8")
306330
print("Received a request of length", len(raw_text), "bytes")
307331
return HTTPResponse(body="hello world")
308-
332+
333+
@server.route(path, method)
334+
def route_func(request, conn):
335+
raw_text = request.raw_request.decode("utf8")
336+
print("Received a request of length", len(raw_text), "bytes")
337+
res = HTTPResponse(content_type="text/html")
338+
res.send_chunk_headers(conn)
339+
res.send_body_chunk(conn, "Some content")
340+
res.send_body_chunk(conn, "Some more content")
341+
res.send_body_chunk(conn, "") # Send empty packet to finish chunked stream
342+
return None # Return None, so server knows that nothing else needs to be sent.
309343
"""
310344

311345
def route_decorator(func: Callable) -> Callable:
@@ -364,7 +398,13 @@ def poll(self):
364398
# If a route exists for this request, call it. Otherwise try to serve a file.
365399
route = self.routes.get(request, None)
366400
if route:
367-
response = route(request)
401+
# Use try, so we don't break old api of this lib.
402+
try:
403+
response = route(request, conn)
404+
except TypeError:
405+
response = route(request)
406+
if response is None:
407+
return
368408
elif request.method == "GET":
369409
response = HTTPResponse(filename=request.path, cache=604800, root=self.root_path)
370410
else:

0 commit comments

Comments
 (0)