Harden HID, Wi-Fi, and web server handling
This commit is contained in:
@@ -1,7 +1,13 @@
|
||||
"""Small non-blocking password-protected HTTP configuration interface."""
|
||||
|
||||
import ubinascii
|
||||
import gc
|
||||
import socket
|
||||
import time
|
||||
import ubinascii
|
||||
|
||||
|
||||
CLIENT_TIMEOUT_MS = 5000
|
||||
MAX_REQUEST_BYTES = 4096
|
||||
|
||||
|
||||
class WebServer:
|
||||
@@ -11,32 +17,46 @@ class WebServer:
|
||||
self.on_volume = on_volume
|
||||
self._client = None
|
||||
self._buffer = b""
|
||||
self._last_activity = None
|
||||
self._socket = socket.socket()
|
||||
self._socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
self._socket.bind(("0.0.0.0", 80))
|
||||
self._socket.listen(1)
|
||||
self._socket.settimeout(0)
|
||||
|
||||
def poll(self):
|
||||
def poll(self, now=None):
|
||||
if now is None:
|
||||
now = time.ticks_ms()
|
||||
|
||||
if self._client is None:
|
||||
try:
|
||||
self._client, _ = self._socket.accept()
|
||||
self._client.settimeout(0)
|
||||
self._buffer = b""
|
||||
except OSError:
|
||||
if self._client is not None:
|
||||
self._close()
|
||||
return
|
||||
self._buffer = b""
|
||||
self._last_activity = now
|
||||
|
||||
try:
|
||||
data = self._client.recv(512)
|
||||
if data:
|
||||
self._buffer += data
|
||||
elif not self._buffer:
|
||||
self._close()
|
||||
return
|
||||
except OSError:
|
||||
pass
|
||||
data = None
|
||||
|
||||
if len(self._buffer) > 4096:
|
||||
self._reply(413, "Request too large")
|
||||
if data == b"":
|
||||
self._close()
|
||||
return
|
||||
if data:
|
||||
self._last_activity = now
|
||||
if len(self._buffer) + len(data) > MAX_REQUEST_BYTES:
|
||||
self._reply(413, "Request too large")
|
||||
return
|
||||
self._buffer += data
|
||||
elif time.ticks_diff(now, self._last_activity) >= CLIENT_TIMEOUT_MS:
|
||||
self._close()
|
||||
return
|
||||
else:
|
||||
return
|
||||
marker = self._buffer.find(b"\r\n\r\n")
|
||||
if marker < 0:
|
||||
@@ -108,12 +128,16 @@ class WebServer:
|
||||
self._close()
|
||||
|
||||
def _close(self):
|
||||
try:
|
||||
self._client.close()
|
||||
except OSError:
|
||||
pass
|
||||
client = self._client
|
||||
self._client = None
|
||||
self._buffer = b""
|
||||
self._last_activity = None
|
||||
if client is not None:
|
||||
try:
|
||||
client.close()
|
||||
except OSError:
|
||||
pass
|
||||
gc.collect()
|
||||
|
||||
|
||||
def _parse_form(body):
|
||||
|
||||
Reference in New Issue
Block a user