A from-scratch HTTP/1.1 server built using Python sockets and threading.
It supports persistent connections, secure path handling, static HTML rendering, binary file streaming, and JSON POST uploads — all using a bounded thread pool for concurrency.
This server implements core HTTP/1.1 semantics, including:
- Host validation
- Connection persistence (Keep-Alive)
- RFC 7231-compliant Date headers (GMT)
- Static file serving
- Binary streaming with
Content-Disposition - JSON upload handling
It serves resources from the resources/ directory and supports both GET and POST requests.
project/
├─ server.py
└─ resources/
├─ index.html
├─ about.html
├─ contact.html
├─ sample.txt
├─ notes.txt
├─ sample.json
├─ bad.json
├─ logo.png
├─ banner.png
├─ photo.jpg
├─ gallery.jpg
└─ uploads/
server.py— main multi-threaded TCP HTTP serverresources/— static assets and upload directory for POST/upload
- Python 3.10+
- Uses only standard libraries:
socket,threading,queue,os,json, etc.
python3 server.py➡️ Binds to 127.0.0.1:8080 with thread pool size 10.
python3 server.py 8000 0.0.0.0 20➡️ Runs on port 8000, host 0.0.0.0, and pool size 20.
- Accept backlog: 50 pending connections.
- Supports
GETandPOST - Parses:
- Method, path, version, headers, body
- Max request size: 8192 bytes
- Invalid requests → 400 Bad Request
| File Type | Content-Type | Behavior |
|---|---|---|
.html |
text/html; charset=utf-8 |
Rendered inline |
.txt, .png, .jpg, .jpeg |
application/octet-stream |
Downloaded as attachments |
- Binary files are streamed in 8KB chunks for efficiency.
- Only accepts:
Content-Type: application/json - Non-JSON → 415 Unsupported Media Type
- Valid JSON is saved in:
resources/uploads/upload_YYYYMMDD_HHMMSS_xxxx.json - Response: 201 Created with file path.
| Protocol | Default Behavior |
|---|---|
| HTTP/1.1 | Persistent unless Connection: close |
| HTTP/1.0 | Closed unless Connection: keep-alive |
- Includes header:
Keep-Alive: timeout=30, max=100 - Server enforces:
- 30s idle timeout
- 100 requests per connection
Logs include:
- Startup info
- Request details
- Host validation results
- File transfer sizes
- Status codes
- Thread pool usage and saturation warnings
- Worker activity snapshots
- Uses:
Content-Type: application/octet-stream Content-Disposition: attachment; filename="..." - Ensures consistent file download behavior.
- Uses
sendall()with 8KB chunked streaming for large files.
- Fixed-size pool of daemon worker threads.
- Threads fetch sockets from a Queue.
- Each thread handles multiple requests (Keep-Alive).
- If all workers are busy:
- New connections are queued.
- Logs: Thread pool saturation warning.
-
Host validation:
Only allows:localhost:PORT 127.0.0.1:PORT <configured_host>:PORTMissing or mismatched Host → 400 / 403.
-
Path traversal protection:
- Rejects
..,./, and absolute paths. - Ensures access only within
resources/.
- Rejects
-
All responses include:
Date: <RFC 7231 HTTP-date in GMT>
Prepare the resources/ folder with the listed files.
curl -i http://127.0.0.1:8080/
curl -i http://127.0.0.1:8080/about.htmlcurl -i -O -J http://127.0.0.1:8080/logo.png
curl -i -O -J http://127.0.0.1:8080/photo.jpg
curl -i -O -J http://127.0.0.1:8080/sample.txtcurl -i -H "Content-Type: application/json" -d '{"ok":true}' http://127.0.0.1:8080/upload| Case | Expected |
|---|---|
| Missing file | 404 Not Found |
| Unsupported method | 405 Method Not Allowed |
| Non-JSON POST | 415 Unsupported Media Type |
| Missing Host header | 400 Bad Request |
| Host mismatch / traversal | 403 Forbidden |
curl -i --http1.1 -H "Connection: keep-alive" http://127.0.0.1:8080/printf "%s\n" logo.png photo.jpg sample.txt | xargs -I{} -P 5 curl -O -J http://127.0.0.1:8080/{}- Request body limit: 8192 bytes
- Chunked transfer-encoding not implemented
- MIME mapping limited to
.html,.txt,.png,.jpg,.jpeg - No TLS/HTTPS (local use only)
- Single-process design for simplicity
This project demonstrates:
- Manual socket-level HTTP handling
- Thread pool design and synchronization
- File I/O and safe path canonicalization
- Basic concurrency debugging and performance observation
Built with 💚 by Prince Shakya