A coursework project that builds an HTTP/1.1 server from scratch using Python sockets and threading. Focus: concurrency, protocol correctness, and security hardening.
- Thread Pool & Queue — configurable workers (default 10) with graceful back-pressure (503 + Retry-After).
- Persistent Connections — keep-alive support with 30s timeout and 100-request limit.
- Static & Binary Serving — HTML renders in-browser, PNG/JPEG/TXT stream as
application/octet-stream
with download headers. - JSON Uploads —
POST /upload
writes validated JSON toresources/uploads/
. - Security Checks — strict Host validation, path traversal defense, and detailed logging.
server.py
server_core/
config.py # configuration defaults and paths
thread_pool.py # worker pool with bounded queue
http_request.py # request parser (8192-byte limit)
http_response.py # response builder with keep-alive headers
worker.py # request handler loop
utils.py # thread-safe logging helper
resources/
index.html # landing page
about.html
contact.html
sample.txt
logo.png # add your own asset
photo.png # add your own asset
uploads/ # POST output destination
python -m venv venv
venv\Scripts\Activate.ps1
pip install --upgrade pip
python server.py # defaults: 127.0.0.1:8080, 10 threads
# optional: python server.py 8000 0.0.0.0 20
curl -i http://127.0.0.1:8080/
curl -i http://127.0.0.1:8080/about.html
curl -i -O http://127.0.0.1:8080/sample.txt
curl -i -X POST http://127.0.0.1:8080/upload \
-H "Content-Type: application/json" \
-d '{"demo": true}'
curl -i http://127.0.0.1:8080/../etc/passwd # expect 403
curl -i -H "Host: evil.com" http://127.0.0.1:8080/ # expect 403
- Thread pool logs queue status every 15 seconds. Saturation triggers 503 with
Retry-After: 5
. - Each response includes
Keep-Alive: timeout=30, max=100
. - Binary downloads stream in 8 KB chunks to avoid memory spikes.
- Upload filenames follow
upload_YYYYMMDD_HHMMSS_<random>.json
.
[2025-10-10 05:30:00] [MainThread] HTTP server started on http://127.0.0.1:8080
[2025-10-10 05:30:00] [MainThread] Thread pool size: 10
[2025-10-10 05:31:12] [Worker-1] Connection from ('127.0.0.1', 54321)
[2025-10-10 05:31:12] [Worker-1] Request: GET /logo.png HTTP/1.1
[2025-10-10 05:31:12] [Worker-1] Host validation: localhost:8080 ✓
[2025-10-10 05:31:12] [Worker-1] Sending binary file: logo.png (45678 bytes)
- TLS (HTTPS) support
- Chunked transfer encoding
- Automated unit/integration tests
- Access log rotation
Crafted with curiosity and sockets. 🎓