This project is a multi-threaded HTTP server built in Python. It is designed to handle multiple concurrent client connections, serve static files, and process JSON data uploads, while implementing key features of the HTTP protocol and basic security checks.
- Concurrent Request Handling: Utilizes a thread pool to manage multiple client connections simultaneously.
- GET Requests: Serves various file types from a resources directory.
- Renders HTML files (text/html) directly in the browser.
- Handles binary file transfers (.png, .jpg, .txt) as downloadable attachments (application/octet-stream).
- POST Requests: Accepts JSON data (application/json), validates it, and saves it to a file in the resources/uploads directory.
- HTTP/1.1 Keep-Alive: Supports persistent connections to handle multiple requests from the same client efficiently, with a configurable timeout and request limit.
- Security: Implements essential security measures:
- Path Traversal Protection: Prevents clients from accessing files outside the designated resources directory.
- Host Header Validation: Ensures requests are intended for this server, mitigating certain types of request smuggling and DNS rebinding attacks.
- Configurable: Server host, port, and thread pool size can be easily configured via command-line arguments.
- Detailed Logging: Provides real-time console logs for server status, incoming connections, requests, and errors.
The server's concurrency model is based on a classic thread pool architecture, which separates the task of accepting connections from processing them.
- Main Thread: The primary thread's only responsibility is to start a TCP socket listener and run an infinite loop to accept incoming client connections.
- Connection Queue: When the Main Thread accepts a new connection, it does not process it. Instead, it places the client socket object into a thread-safe Queue. This queue holds connections waiting to be handled.
- Worker Threads: A fixed number of worker threads are started when the server launches. Each worker runs in its own infinite loop, constantly trying to pull a connection from the queue. If the queue is empty, the worker waits. Once a worker retrieves a connection, it becomes responsible for the entire request-response cycle for that client.
This design prevents the server from being blocked by slow clients and ensures that new connections can be accepted even while others are being processed.
The project uses the following directory structure:
project/
├── server.py # The main server script.
└── resources/
├── index.html # Default page for the root path '/'.
├── about.html # Other HTML pages for testing.
├── sample.txt # A sample text file for binary download.
├── logo.png # A sample image for binary download.
└── uploads/ # Directory where POSTed JSON files are saved.
- Python 3.6 or newer. No external libraries are needed.
Create the resources and resources/uploads directories and place some test files inside resources as shown in the structure above.
Navigate to the project's root directory in your terminal and run the server.py script.
To run with default settings (Host: 127.0.0.1, Port: 8080, Threads: 10):
python server.py
To run with custom settings:
The script accepts command-line arguments in the following order: [port] [host] [thread_pool_size].
# Example: Run on port 8000, accessible on all network interfaces, with 20 threads.
python server.py 8000 0.0.0.0 20
- HTML Files: Open your web browser and navigate to http://127.0.0.1:8080/. This should display your index.html file.
- Binary Downloads: Navigate to http://127.0.0.1:8080/logo.png or http://127.0.0.1:8080/sample.txt. The browser should prompt you to download the file.
Use a tool like curl to send a POST request with JSON data.
curl -X POST \
[http://127.0.0.1:8080/upload\](http://127.0.0.1:8080/upload) \
-H 'Content-Type: application/json' \
-d '{
"user": "alex",
"id": 123,
"data": "This is a test submission"
}'
The server should respond with a 201 Created status and a JSON body confirming the file was created. A new .json file will appear in the resources/uploads directory.
- No HTTPS: This server does not implement TLS/SSL and all communication is unencrypted.
- Limited HTTP Support: The server only supports a subset of HTTP/1.1 features and headers. It correctly handles GET and POST but will return 405 Method Not Allowed for others.
- Basic Error Handling: Error handling is functional but could be made more robust for a production environment.