threaded HTTP server, rate limiting, remove slow-web rhetoric
This commit is contained in:
parent
54dbc1a3b1
commit
30f4f1ce3e
6 changed files with 59 additions and 19 deletions
25
gateway.py
25
gateway.py
|
|
@ -2,8 +2,9 @@ import re
|
|||
import sys
|
||||
import time
|
||||
import threading
|
||||
import collections
|
||||
import RNS
|
||||
from http.server import HTTPServer, BaseHTTPRequestHandler
|
||||
from http.server import HTTPServer, ThreadingHTTPServer, BaseHTTPRequestHandler
|
||||
from urllib.parse import parse_qs, urlparse
|
||||
|
||||
APP_NAME = "tinyweb"
|
||||
|
|
@ -11,6 +12,10 @@ ASPECTS = ["server"]
|
|||
GATEWAY_PORT = 8080
|
||||
REQUEST_TIMEOUT = 60
|
||||
MAX_BODY_SIZE = 16 * 1024 * 1024 # 16 MiB — covers /import and every other form
|
||||
RATE_LIMIT_WINDOW = 60
|
||||
RATE_LIMIT_MAX = 30
|
||||
_rate_tracker = collections.defaultdict(list)
|
||||
_rate_lock = threading.Lock()
|
||||
|
||||
|
||||
class GatewayState:
|
||||
|
|
@ -67,12 +72,28 @@ def ensure_link():
|
|||
|
||||
class GatewayHandler(BaseHTTPRequestHandler):
|
||||
|
||||
def _check_rate_limit(self):
|
||||
client = self.client_address[0]
|
||||
now = time.time()
|
||||
with _rate_lock:
|
||||
times = _rate_tracker[client]
|
||||
cutoff = now - RATE_LIMIT_WINDOW
|
||||
while times and times[0] < cutoff:
|
||||
times.pop(0)
|
||||
if len(times) >= RATE_LIMIT_MAX:
|
||||
return False
|
||||
times.append(now)
|
||||
return True
|
||||
|
||||
def _forward(self, method):
|
||||
parsed = urlparse(self.path)
|
||||
query = parse_qs(parsed.query)
|
||||
|
||||
body = {}
|
||||
if method == "POST":
|
||||
if not self._check_rate_limit():
|
||||
self.send_error(429, "Too many requests — slow down.")
|
||||
return
|
||||
try:
|
||||
length = int(self.headers.get("Content-Length", 0))
|
||||
except ValueError:
|
||||
|
|
@ -187,7 +208,7 @@ def main():
|
|||
|
||||
print(f"Gateway listening on http://localhost:{GATEWAY_PORT}")
|
||||
print(f"Open http://localhost:{GATEWAY_PORT} in your browser")
|
||||
HTTPServer(("127.0.0.1", GATEWAY_PORT), GatewayHandler).serve_forever()
|
||||
ThreadingHTTPServer(("127.0.0.1", GATEWAY_PORT), GatewayHandler).serve_forever()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue