A Multi-threaded HTTP/1.1 server built from scratch using low-level Java socket programming. This project demonstrates a deep understanding of the HTTP protocol, concurrent programming, and network security fundamentals.
- ⚙️ Multi-threaded Architecture: Utilizes a fixed-size thread pool to handle multiple concurrent client connections efficiently.
- 🔄 HTTP/1.1 Protocol Support: Parses and handles
GETandPOSTrequests, with proper error handling for other methods (405 Method Not Allowed). - 📁 Static & Binary File Serving: Serves
.htmlfiles for in-browser rendering and other types (.png,.jpg,.txt) as downloadable binaries. - 📄 JSON Data Processing: Accepts
POSTrequests withapplication/json, validates the payload, and saves it to a file, returning a201 Createdresponse. - 🛡️ Security Hardening: Implements Path Traversal protection and mandatory Host header validation.
- 🔌 Connection Management: Supports persistent connections via
Connection: keep-alivewith idle timeouts and request limits. - 📊 Comprehensive Logging: Detailed, timestamped logs for all server activities, managed by a dedicated
Loggerclass. - 🧪 Interactive Test Suite: Built-in web interface for testing all server endpoints and features.
The project is organized into a standard Maven layout, separating application logic, resources, and tests.
Http_server/
├── pom.xml
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ ├── dto/
│ │ │ │ └── HttpRequest.java # Data Transfer Object for requests
│ │ │ ├── enums/
│ │ │ │ └── Method.java # Enum for HTTP methods
│ │ │ ├── handlers/
│ │ │ │ ├── ClientHandler.java # Handles individual client connections
│ │ │ │ ├── RequestHandler.java # Parses and validates requests
│ │ │ │ └── ResponseHandler.java # Constructs and sends HTTP responses
│ │ │ ├── helpers/
│ │ │ │ ├── Client.java # Wrapper for client socket and streams
│ │ │ │ └── Logger.java # Centralized logging utility
│ │ │ ├── server/
│ │ │ │ └── Server.java # Main server loop and thread pool management
│ │ │ └── Main.java # Application entry point
│ │ └── resources/
│ │ ├── uploads/ # Directory for POST uploads
│ │ ├── about.html # Sample HTML page
│ │ ├── contact.html # Sample HTML page
│ │ ├── index.html # Default home page
│ │ ├── test.html # Interactive test suite
│ │ ├── logo.png # Sample PNG image
│ │ ├── photo.jpg # Sample JPEG image
│ │ └── sample.txt # Sample text file
│ └── test/
│ └── test_server.ps1 # PowerShell test script
├── logs/ # Server logs directory
└── README.md
- Java Development Kit (JDK) 11 or newer
- Apache Maven
- Git
-
Clone the repository:
git clone https://github.com/yamiSukehiro2907/Http_server.git cd Http_server -
Build the project using Maven: This command compiles the source code and packages it into a runnable JAR.
mvn clean package
-
Run the server:
- To run with default settings (
127.0.0.1:8080, 10 threads):java -cp target/myartifactid-0.0-SNAPSHOT.jar Main
- To run with custom settings (e.g., port 8000, any host, 20 threads):
java -cp target/myartifactid-0.0-SNAPSHOT.jar Main 8000 0.0.0.0 20
- To run with default settings (
Once the server is running, you can interact with it using multiple methods.
The easiest way to test all server features is through the built-in web interface:
-
Start the server:
java -cp target/myartifactid-0.0-SNAPSHOT.jar Main
-
Open your browser and navigate to:
http://127.0.0.1:8080/test.html -
Interactive Test Suite Features:
- ✅ GET Requests: Test HTML pages, image downloads, and text files
- ✅ POST Requests: Upload JSON data with editable text areas
- ❌ Error Cases: Test 404, 405, 415, and 400 error responses
- 🔒 Security Tests: Verify path traversal protection
- 📊 Live Response Display: View status codes, headers, and response bodies in real-time
The test interface provides a beautiful, user-friendly way to verify that all server features are working correctly.
For command-line testing, you can use curl:
-
Get HTML page:
curl -v http://localhost:8080/index.html
-
Download a binary file:
curl -v http://localhost:8080/logo.png --output downloaded_logo.png
-
Send a POST request with JSON data:
curl -v -X POST http://localhost:8080/upload \ -H "Content-Type: application/json" \ -H "Host: localhost:8080" \ -d '{"message": "Testing POST request"}'
-
Test path traversal protection:
curl -v http://localhost:8080/../etc/passwd
-
Test unsupported method:
curl -v -X PUT http://localhost:8080/index.html
Use Apache Bench (ab) to simulate concurrent connections and test server performance:
ab -n 1000 -c 50 http://localhost:8080/index.htmlThis command sends 1000 requests with 50 concurrent connections.
You can also use the test_server.ps1 PowerShell script located in the src/test directory for automated testing
scenarios.
The Server.java class initializes a fixed-size thread pool using ExecutorService. It runs an infinite loop to accept
incoming TCP
connections. Each accepted client Socket is wrapped in a Client object and added to a LinkedBlockingQueue. A
separate queue processor thread continuously dequeues clients and submits them to the thread pool for processing.
Key Design Benefits:
- Decouples connection acceptance from request processing
- Prevents thread exhaustion through pool size limits
- Graceful handling of connection spikes through request queuing
- Efficient resource utilization with thread reuse
For each client connection, a ClientHandler instance is executed by a worker thread. The process is as follows:
- Read & Parse:
ClientHandlerreads the raw HTTP request from the socket's input stream using aBufferedReader. - Validation:
RequestHandlerparses the raw string into a structuredHttpRequestDTO. It validates:- Request format and HTTP version
- HTTP method (GET/POST only)
- Required headers (especially
Host) - Path safety (prevents directory traversal)
- Content-Type for POST requests
- Dispatch: Based on the HTTP method,
ClientHandlerproceeds:- GET: Serves static HTML files or binary files (images, text) from the
resourcesdirectory - POST: Validates JSON payload, generates unique filename, and saves to
uploadsdirectory
- GET: Serves static HTML files or binary files (images, text) from the
- Response:
ResponseHandlerconstructs the appropriate HTTP response with proper status codes:200 OK- Successful GET201 Created- Successful POST400 Bad Request- Malformed request or invalid JSON403 Forbidden- Path traversal or host mismatch404 Not Found- Resource doesn't exist405 Method Not Allowed- Unsupported HTTP method415 Unsupported Media Type- Wrong Content-Type or file type500 Internal Server Error- Server-side errors
-
Path Traversal Protection:
RequestHandlervalidates all requested paths before file access:- Blocks
..,./,//, and URL-encoded variants - Canonicalizes paths using Java's
Path.normalize() - Ensures resolved paths stay within
resourcesdirectory - Returns
403 Forbiddenfor any violations
- Blocks
-
Host Header Validation:
- All HTTP/1.1 requests must include a valid
Hostheader - Server validates the header matches its own address
- Accepts
localhost,127.0.0.1, or0.0.0.0variations - Returns
400 Bad Requestif missing,403 Forbiddenif mismatched
- All HTTP/1.1 requests must include a valid
-
Request Size Limiting:
- Maximum request size enforced at 8192 bytes
- Prevents memory exhaustion attacks
-
Input Validation:
- JSON validation using Google's Gson library
- File type restrictions (only HTML, TXT, PNG, JPG/JPEG)
- Content-Type verification for POST requests
The server can be configured via command-line arguments:
java -cp target/myartifactid-0.0-SNAPSHOT.jar Main [port] [host] [thread_pool_size]Parameters:
port: The port number to bind to. (Default:8080)host: The host address to bind to. (Default:127.0.0.1)thread_pool_size: The number of worker threads. (Default:10)
Examples:
# Default configuration
java -cp target/myartifactid-0.0-SNAPSHOT.jar Main
# Custom port
java -cp target/myartifactid-0.0-SNAPSHOT.jar Main 9000
# Bind to all interfaces
java -cp target/myartifactid-0.0-SNAPSHOT.jar Main 8080 0.0.0.0
# Custom port, host, and 20 threads
java -cp target/myartifactid-0.0-SNAPSHOT.jar Main 8000 0.0.0.0 20Use the interactive test interface at http://127.0.0.1:8080/test.html to verify:
- ✅ GET / → Serves index.html
- ✅ GET /about.html → Serves HTML page
- ✅ GET /logo.png → Downloads PNG as binary
- ✅ GET /photo.jpg → Downloads JPEG as binary
- ✅ GET /sample.txt → Downloads text file as binary
- ✅ POST /upload (JSON) → Creates file, returns 201
- ❌ GET /nonexistent.html → Returns 404
- ❌ PUT /index.html → Returns 405
- ❌ DELETE /file.txt → Returns 405
- ❌ POST /upload (XML) → Returns 415
- ❌ POST /upload (invalid JSON) → Returns 400
- ❌ GET /document.pdf → Returns 415
- 🔒 GET /../etc/passwd → Returns 403
- 🔒 GET /../../sensitive.txt → Returns 403
- 🔒 GET //etc/hosts → Returns 403
Vimal Kumar
- GitHub: @yamiSukehiro2907
This project was built as part of a Computer Networks assignment to demonstrate understanding of:
- Low-level socket programming
- HTTP/1.1 protocol implementation
- Multi-threaded server architecture
- Network security best practices
- Concurrent programming patterns