Status Update: November 6, 2025
This project implements a complete HTTP server with cookie-based authentication and a reverse proxy server with load balancing capabilities. The implementation consists of modular components that can work independently or together to provide web serving and proxying functionality.
- Multi-threaded Request Handling: Each client connection runs in a separate daemon thread
- Cookie-based Session Management: Parse and validate authentication cookies
- POST/GET Request Processing: Full HTTP protocol support with proper body parsing
- Static File Serving: Serve HTML, CSS, JavaScript, and image files
- Authentication Flow: Login endpoint with credential validation
- Request Forwarding: Route incoming requests to backend servers
- Load Balancing Policies:
- Round-robin distribution
- Least-connections routing
- IP-hash for session affinity
- Multiple Backend Support: Configure multiple upstream servers
- Host-based Routing: Route based on Host header values
- HTTP Protocol Layer: Generic HTTP processing (
httpadapter,request,response) - Application Logic Layer: User-defined business logic in separate applications
- Daemon Infrastructure: Backend server management and client handling
| File | Purpose | Responsibility |
|---|---|---|
backend.py |
HTTP server daemon | Accept connections, spawn threads |
httpadapter.py |
HTTP protocol adapter | Parse requests, route to handlers |
request.py |
HTTP request processing | Parse headers, body, cookies |
response.py |
HTTP response building | Generate HTTP responses, handle static files |
proxy.py |
Reverse proxy implementation | Forward requests, load balancing |
| File | Purpose | Framework Used |
|---|---|---|
session_base_http_server.py |
Manual Route Management | Direct daemon usage |
start_sampleapp_new.py |
WeApRous Framework | Uses @route decorators |
| File | Purpose | Port |
|---|---|---|
start_backend.py |
HTTP server startup | 9000 |
start_proxy.py |
Proxy server startup | 8080 |
Current Implementation: Single parameter approach
@app.route('/login', methods=['POST'])
def login(req): # β
Current: Pass request object
headers = req.headers
body = req.body
cookies = req.cookiesOriginal Design: Two parameter approach (deprecated)
def login(headers="guest", body="anonymous"): # β Original designRationale: Single parameter provides better access to full request context and follows modern web framework patterns.
# Manual route registration
routes = {
('GET', '/'): route_index,
('POST', '/login'): route_login,
('GET', '/login.html'): route_login_page
}
# Direct daemon usage
daemon = WeApRous()
daemon.create_backend('127.0.0.1', 9000, routes)# Automatic route registration via decorators
@app.route('/login', methods=['POST'])
def login(req):
return handle_login_logic(req)
# WeApRous framework manages registration
app.run('127.0.0.1', 9000)# Single backend routing
host "127.0.0.1:8080" {
proxy_pass http://127.0.0.1:9000;
}
# Load balancing with multiple backends
host "app2.local" {
proxy_pass http://192.168.56.210:9002;
proxy_pass http://192.168.56.220:9002;
dist_policy round-robin
}# Terminal 1: Start HTTP server with session-based authentication
python ./session_base_http_server.py
# This will start the server on 127.0.0.1:9000 with the following routes:
# - GET /login - Login page
# - POST /login - Handle login authentication
# - GET /login.html - Login form
# - GET /logout - Logout functionality
# - GET / - Main page (requires authentication)
# - GET /index.html - Index page (requires authentication)
# Access directly: http://127.0.0.1:9000/# Terminal 1: Start HTTP server with session authentication
python ./session_base_http_server.py
# Terminal 2: Start proxy server
python ./start_proxy.py --server-ip 127.0.0.1 --server-port 8080
# Access via proxy: http://127.0.0.1:8080/
# Proxy forwards requests to backend (port 9000)
# This demonstrates the complete reverse proxy functionality# Terminal 1-3: Start multiple HTTP servers with session auth
python session_base_http_server.py # Will run on port 9000
# Note: Modify port in session_base_http_server.py for multiple instances
# Terminal 4: Start proxy (configure proxy.conf first)
python start_proxy.py --server-ip 127.0.0.1 --server-port 8080For a complete step-by-step demonstration of the authentication and proxy functionality, see: DemoTask1_compressed.mp4 - Shows the complete login flow, cookie authentication, and proxy routing in action (compressed version for GitHub compatibility).
# Run all tests
cd test/
python run_all_test.py
# Run individual tests
python test_proxy.py # Proxy routing tests
python test_authentication.py # Cookie authentication tests
python quick_test.py # Basic functionality test
python test_file_read.py # File operations test- Authentication Flow: Access
/, login withadmin/password, verify cookie persistence - Proxy Routing: Compare responses from
:9000vs:8080 - Load Balancing: Send multiple requests, observe backend selection
| Test File | Status | Purpose |
|---|---|---|
quick_test.py |
β PASSED | Basic HTTP request/response |
test_file_read.py |
β PASSED | Static file serving |
test_proxy.py |
Proxy routing (needs running servers) | |
test_authentication.py |
Cookie auth (needs running servers) |
- Behavior: Distribute requests sequentially across backends
- Use Case: Equal load distribution for similar backend capacities
- Implementation: Global counter per hostname
- Behavior: Route to backend with fewest active connections
- Use Case: Varying request processing times
- Implementation: Track active connections per backend
- Behavior: Consistent routing based on client IP hash
- Use Case: Session affinity requirements
- Implementation: MD5 hash of client IP modulo backend count
β
Completed: Basic HTTP server with cookie authentication
β
Completed: Reverse proxy with load balancing
β
Completed: Modular architecture with clean separation
- Utilize
start_sampleapp_new.py(WeApRous framework approach) - Leverage
@routedecorators for automatic handler registration - Build upon existing daemon infrastructure
- Extend load balancing policies as needed
- Browser form submissions may require additional debugging vs Postman
- Proxy configuration requires manual host entry management
- Test suite needs running servers for full validation
- Single Parameter Handler: Chose
handler(req)overhandler(headers, body)for better extensibility - Manual Route Management: Implemented direct route dictionary for fine-grained control
- Framework Preparation: Created foundation for decorator-based routing in Task 2
- Modular Design: Separated HTTP protocol handling from application logic
- Load Balancing: Implemented multiple policies for different use cases
# Test login flow
curl -X POST http://127.0.0.1:8080/login \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "username=admin&password=password"
# Test authenticated access
curl http://127.0.0.1:8080/ \
-H "Cookie: auth=true"# Send multiple requests to see round-robin
for i in {1..5}; do
curl http://127.0.0.1:8080/
echo "Request $i completed"
doneProject Team: HCMUT - Computer Networks Course
Implementation Period: October 29 - November 6, 2025
Current Phase: Task 1 Complete, Task 2 Preparation
Note: This implementation follows PEP 8 style guidelines and includes comprehensive docstrings as required by the assignment.