Skip to content

Commit 142c97d

Browse files
authored
Merge pull request #7 from karlfl/main
Split serve_forever to allow polling in loop and add another example with polling in while loop.
2 parents 67c3ac3 + 1824d21 commit 142c97d

File tree

2 files changed

+76
-22
lines changed

2 files changed

+76
-22
lines changed

adafruit_httpserver.py

+40-22
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ def __init__(self, socket_source: Any) -> None:
275275
self.routes = {}
276276
self._socket_source = socket_source
277277
self._sock = None
278+
self.root_path = "/"
278279

279280
def route(self, path: str, method: str = "GET"):
280281
"""Decorator used to add a route.
@@ -302,33 +303,50 @@ def serve_forever(self, host: str, port: int = 80, root: str = "") -> None:
302303
:param int port: port
303304
:param str root: root directory to serve files from
304305
"""
305-
self._sock = self._socket_source.socket(
306-
self._socket_source.AF_INET, self._socket_source.SOCK_STREAM
307-
)
308-
self._sock.bind((host, port))
309-
self._sock.listen(1)
306+
self.start(host, port, root)
310307

311308
while True:
312309
try:
313-
conn, _ = self._sock.accept()
310+
self.poll()
314311
except OSError:
315312
continue
316-
with conn:
317-
# If reading fails, close connection and retry.
318-
try:
319-
length, _ = conn.recvfrom_into(self._buffer)
320-
except OSError:
321-
continue
322313

323-
request = _HTTPRequest(raw_request=self._buffer[:length])
314+
def start(self, host: str, port: int = 80, root: str = "") -> None:
315+
"""
316+
Start the HTTP server at the given host and port. Requires calling
317+
poll() in a while loop to handle incoming requests.
324318
325-
# If a route exists for this request, call it. Otherwise try to serve a file.
326-
route = self.routes.get(request, None)
327-
if route:
328-
response = route(request)
329-
elif request.method == "GET":
330-
response = HTTPResponse(filename=request.path, root=root)
331-
else:
332-
response = HTTPResponse(status=HTTPStatus.INTERNAL_SERVER_ERROR)
319+
:param str host: host name or IP address
320+
:param int port: port
321+
:param str root: root directory to serve files from
322+
"""
323+
self.root_path = root
324+
325+
self._sock = self._socket_source.socket(
326+
self._socket_source.AF_INET, self._socket_source.SOCK_STREAM
327+
)
328+
self._sock.bind((host, port))
329+
self._sock.listen(10)
333330

334-
response.send(conn)
331+
def poll(self):
332+
"""
333+
Call this method inside your main event loop to get the server to
334+
check for new incoming client requests. When a request comes in,
335+
the application callable will be invoked.
336+
"""
337+
conn, _ = self._sock.accept()
338+
with conn:
339+
length, _ = conn.recvfrom_into(self._buffer)
340+
341+
request = _HTTPRequest(raw_request=self._buffer[:length])
342+
343+
# If a route exists for this request, call it. Otherwise try to serve a file.
344+
route = self.routes.get(request, None)
345+
if route:
346+
response = route(request)
347+
elif request.method == "GET":
348+
response = HTTPResponse(filename=request.path, root=self.root_path)
349+
else:
350+
response = HTTPResponse(status=HTTPStatus.INTERNAL_SERVER_ERROR)
351+
352+
response.send(conn)

examples/httpserve_simplepolling.py

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# SPDX-FileCopyrightText: 2022 Dan Halbert for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: Unlicense
4+
5+
from secrets import secrets # pylint: disable=no-name-in-module
6+
7+
import socketpool
8+
import wifi
9+
10+
from adafruit_httpserver import HTTPServer, HTTPResponse
11+
12+
ssid = secrets["ssid"]
13+
print("Connecting to", ssid)
14+
wifi.radio.connect(ssid, secrets["password"])
15+
print("Connected to", ssid)
16+
print(f"Listening on http://{wifi.radio.ipv4_address}:80")
17+
18+
pool = socketpool.SocketPool(wifi.radio)
19+
server = HTTPServer(pool)
20+
21+
22+
@server.route("/")
23+
def base(request): # pylint: disable=unused-argument
24+
"""Default reponse is /index.html"""
25+
return HTTPResponse(filename="/index.html")
26+
27+
28+
# startup the server
29+
server.start(str(wifi.radio.ipv4_address))
30+
31+
while True:
32+
try:
33+
# processing any waiting requests
34+
server.poll()
35+
except OSError:
36+
continue

0 commit comments

Comments
 (0)