Skip to content

This project implements a lightweight HTTP server from scratch using only Python’s built-in libraries (socket, threading, os, gzip).

Notifications You must be signed in to change notification settings

llalyeva/my-http-server

Repository files navigation

Simple HTTP Server in Python

This project implements a lightweight HTTP server from scratch using only Python’s built-in libraries (socket, threading, os, gzip).
It supports basic REST-like endpoints for file upload/download, echo messages, user-agent inspection, and gzip compression.


Features

Supports GET and POST methods
Handles /, /echo/<message>, /user-agent, and /files/<filename> routes
File upload via POST /files/<filename>
File download via GET /files/<filename>
Optional gzip compression for /echo/ responses
Correct Content-Length, Content-Type, and Connection headers
Graceful Connection: close handling
Multi-threaded connections — handles multiple clients simultaneously
No external dependencies (pure Python)


Requirements

  • Python 3.9+
  • No external packages needed

Usage

Run the server on port 4221:

python server.py

To serve or upload files, specify a directory with --directory:

python server.py --directory ./files

Endpoints

/ — Root

Simple health check endpoint.

Request:

GET /

Response:

HTTP/1.1 200 OK

/echo/ — Echo

Returns the message back to the client. Supports gzip if Accept-Encoding: gzip header is provided.

Example 1 (plain):

GET /echo/hello

Response:

HTTP/1.1 200 OK Content-Type: text/plain Content-Length: 5


Example 2 (gzip-compressed):

GET /echo/hello Accept-Encoding: gzip

Response Headers:

HTTP/1.1 200 OK Content-Encoding: gzip Content-Type: text/plain Content-Length: <compressed_size>

/user-agent — Return User-Agent Header

Extracts and returns the User-Agent header value from the request.

Request:

GET /user-agent User-Agent: Mozilla/5.0

Response:

HTTP/1.1 200 OK Content-Type: text/plain Content-Length: 11

Mozilla/5.0

/files/ — File Handling

Upload (POST)

Uploads a file to the given directory.

Request:

POST /files/example.txt Content-Length: 11

Hello World

Response:

HTTP/1.1 201 Created

This creates ./files/example.txt containing Hello World.

Download (GET)

Downloads a file from the server.

Request:

GET /files/example.txt

Response:

HTTP/1.1 200 OK Content-Type: application/octet-stream Content-Length: 11

Hello World

If the file does not exist:

HTTP/1.1 404 Not Found

Command-Line Arguments Argument Description Default --directory Path to serve files from (None)

Example:

python server.py --directory ./uploads

How It Works

  1. Socket Server

Creates a TCP server using:

socket.create_server(("localhost", 4221), reuse_port=True)

Each connection is handled in a new thread (threading.Thread).

  1. Request Parsing

Reads data until a full HTTP header (\r\n\r\n) is received. Splits the first line into method, path, and protocol.

  1. Routing

Depending on the request path and method, routes to:

handle_root()

handle_echo()

handle_user_agent()

handle_file() / handle_post()

  1. Gzip Handling

For /echo/ endpoint — compresses output if the request header includes Accept-Encoding: gzip.

  1. Connection Handling

Supports persistent connections (keeps the socket open)

Closes if header Connection: close is present

Example Tests (via curl)

Echo endpoint:

curl http://localhost:4221/echo/Hello

Echo with gzip:

curl -H "Accept-Encoding: gzip" http://localhost:4221/echo/Hello --output - | gunzip

Upload a file:

curl -X POST --data-binary "Hello World" http://localhost:4221/files/test.txt

Download it:

curl http://localhost:4221/files/test.txt

User-Agent endpoint:

curl -H "User-Agent: MyCustomAgent" http://localhost:4221/user-agent

About

This project implements a lightweight HTTP server from scratch using only Python’s built-in libraries (socket, threading, os, gzip).

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published