A high-performance, memory-safe HTTP/1.0 server built from scratch using an epoll-based event loop inspired by nginx.
This project is built based on the HTTP/1.0 RFC spec written. It currently only has implemented GET,PUT and HEAD. All code is memory safe as per extensive testing. It was validated using valgrind.
This project was built to:
- Explore low-level systems programming in C
- Implement a memory-safe HTTP parser from scratch
- Design a scalable event-driven architecture using epoll
- Understand tradeoffs vs thread-per-request models
Why epoll over threads?
I chose an epoll-based event-driven model over a thread-per-request architecture to better handle high concurrency with lower resource overhead. Threaded models are simpler but scale poorly due to memory usage and context-switching costs. In contrast, epoll enables a non-blocking, single-threaded design that efficiently manages thousands of concurrent connections with minimal overhead. The tradeoff is increased implementation complexity (state management, partial I/O handling), but it proved to be a good learning experience :D
- Each process listens on the same port using SO_REUSEPORT. (Using epoll over comes the thundering herd problem)
- Once a connection is made, the process makes a new non-blocking connect socket and add its to the interest list for epoll and waits for IO again.
- When some data is written to a connection socket, we process it, and map the response for it, to each particular socket. I.E each connection socket will have a processed return request mapped to it.
- Then when the socket is ready for read, we write the mapped response to it and close it.
- How real-world servers like nginx work internally
- Tradeoffs between concurrency models
- Writing safe systems code in C, and validating the same using valgrind.
- Designing state machines for streaming protocols
- Caching for repeat requests.
- Extend functionality for DELETE, POST.
- Include Cookie based authentication, and Gzip-encoding.
You can use any generator you want but this project is only written for Unix systems right now.
cmake -S . -B build -G "Unix Makefiles"
cd build
make
For server
./http1 server
For client
./http1 client "GET url HTTP/1.0\r\n"