Skip to content

Latest commit

 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 

Repository files navigation

C HTTP Server

A lightweight, high-performance HTTP/1.1 server written from scratch in C. This project implements the core of the HTTP protocol, supporting concurrent connections, file handling, and data compression.

The project demonstrates low-level systems programming concepts including TCP sockets, process management (fork), manual HTTP request parsing, and GZIP compression using zlib.

Features

  • TCP & Sockets: Raw implementation of server/client sockets.
  • Concurrency: Handles multiple simultaneous clients using fork() (multi-process architecture).
  • HTTP 1.1 Parsing: Manually parses HTTP verbs, paths, and headers.
  • File Handling:
    • GET: Reads and serves files directly from the disk.
    • POST: Creates and writes content to new files.
  • GZIP Compression: Automatically compresses responses using zlib if the client sends the Accept-Encoding: gzip header.
  • Persistent Connections: Implicit support for Connection: keep-alive.

Arhitecture Diagram

The server follows a multi-process arhitecture to ensure stability and performance. The main process handles initial TCP handshake and immediately forks a child process for each new client connection.

sequenceDiagram
    participant Client
    participant Server (Main)
    participant Server (Child)
    
    Note over Server (Main): Socket Create -> Bind -> Listen
    Client->>Server (Main): Connect (TCP Handshake)
    Server (Main)->>Server (Main): Accept Connection
    Server (Main)->>Server (Child): FORK Process
    
    rect rgb(20, 20, 20)
        Note right of Server (Child): Handle Request in Isolation
        Client->>Server (Child): HTTP Request (GET /file)
        Server (Child)-->>Client: HTTP Response (200 OK + Data)
        Server (Child)->>Server (Child): Exit Process
    end
    
    Note over Server (Main): Continue listening for new clients...
Loading

Build & Run

Prerequisites

  • GCC (GNU Compiler Collection)
  • Zlib (Required for compression. On Ubuntu/Debian: sudo apt install zlib1g-dev)

Compilation

Compile the server using gcc. It is essential to include the -lz flag to link the zlib library.

gcc main.c -o server -lz

Run

Start the server by executing the generated binary:

./server

The server will listen on port 4221. Note the server is configured to serve and save files by default in the HOME directory of the current user.

API Endpoints & Examples

Here is a complete list of supported routes and how to test them using curl.

1. Basic Status Check(/)

Checks if the server is online

  • Request: GET /
  • Response: 200 OK
curl -v http://localhost:4221/

2. Echo(/echo/{string})

Return the string provided in the URL as the response body. Useful for testing parsing logic.

curl -v http://localhost:4221/echo/hello-world

3. User Agent(/user-agent)

Reads the User-Agent header sent by the client and returns it to the body.

  • Request: GET /user-agent
  • Response: 200 OK, Example Body: curl/8.5.0
curl -v http://localhost:4221/user-agent

4. Read Files(GET /{filename})

Looks for specific files in the user's HOME directory and sends the content back to the user. The Dir header can be of any form (Dir: 1, Dir: 12123), just needs to be specified for file reading.

  • Request: GET /test.txt
  • Response:
    • If found: 200 OK, Content-Type: application/octet-stream, Body: file content
    • Else: 404 Not found
curl -v -H "Dir: 1" http://localhost:4221/test.txt

5. Write Files(POST /{filename})

Creates (or overwrites) a file in the HOME directory with the content sent in the request body.

  • Request: POST /test.txt (Body: "Hello, World!")
  • Response: 201 Created
curl -v -d "Hello, World!" http://localhost:4221/test.txt 

6. GZIP Compression

The server automatically detects if the clients support compression.

  • Request: Any request that includes the Accept-Encoding: gzip header.
  • Response: Includes Content-Encoding: gzip header and compressed body.
curl -v -H "Accept-Encoding: gzip" http://localhost:4221/echo/long_string

About & Learning Journey

This project was built as a self-directed educational implementation of the HTTP standard, inspired by the "Build Your Own HTTP Server" challenge from CodeCrafters.

I undertook this project to deconstruct the "black box" of web servers. My goal was to step away from high-level frameworks and understand the raw mechanics of the HTTP protocol and systems programming in C.

Key Learnings

Building this server from scratch pushed me to understand:

  • The Unix Philosophy: Working directly with file descriptors, system calls, and the TCP/IP stack without abstraction layers.
  • Concurrency Models Implementing a multi-process architecture using fork() to handle simultaneous connections, learning how the OS schedules and isolates processes.

This project served as a deep dive into the fundamentals of software engineering, bridging the gap between writing code and understanding how the machine executes it.

About

Minimal HTTP/1.1 server written in C using POSIX sockets, with fork-based concurrency and gzip compression.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages