Static HTTP server

Github repository
View discussion on reddit

Why ?

Computer Networks is one of the courses this semester. But, due to the COVID-19 pandemic, it was cut short and some of the stuff we were supposed to learn was not covered. So, I thought "may be I'll learn it online and see what I can do". This server is result of that thought.

Features

  1. Static HTTP GET
  2. Multithreading
  3. Nothing else

Running

  1. You'll need a POSIX compliant system, gcc and make(optional).
  2. clone this repository and run make.
  3. If you don't have make run gcc -Wall server.c -o server in root directory.
  4. Place your static content in the html/ directory or pass your directory name as an argument. In anycase, the static directory must be in the same directory as the server binary.
  5. Execute the server binary. When you want to stop, type exit

How does it work ?

  1. The main() sets up a listening socket, a threadpool with 8 worker threads (default) and waits for incoming connections using epoll().
  2. When a new connection arrives, it puts the client socket file descriptor in a queue and sends a signal to the threadpool using the pthread_cond_wait() method and forgets about it.
  3. A free thread from the threadpool dequeues this connection. If no thread is free, then it will sit in the queue until some thread comes for it.
  4. The worker thread receives the HTTP request from client and returns the appropriate HTTP response and closes the connection.

Benchmarks

I included a html page full of images of puppies and a script to make a 100 requests to the server and time it. On my laptop with an i5 processor and 8 GB RAM, each request takes around a second to complete. To run the benchmark yourself, in the root directory of this repository run bash benchmark.sh.

$ bash benchmark.sh
Benchmark url: http://localhost:8000//benchmark/puppies/index.html
Made 100 requests
Total time: 41 s
Average time per request: 412 ms

Usage

$ ./server -h

Static HTTP server
Usage: ./server [-p port number] [-h html directory] [-t thread pool size]

[Optional arguments]
 -p Server port (Default 8000)
 -t Thread pool size. Number of threads for the server to use. (Default 8)
 -s HTML files in this directory are served. This directory must be in the same directory as the server binary and don't add './' to the directory name! (Default 'html')
 -h Shows available arguments