Version: 1.0.0
See VERSION.md for documentation changelog
This project is a simple HTTP server written in C. It allows you to create a web server that can handle basic requests from web browsers or other clients.
An HTTP server is a program that:
- Waits for incoming connections from clients (like web browsers)
- Receives HTTP requests (like "GET me this webpage")
- Processes those requests
- Sends back HTTP responses (like HTML content)
The project is organized into these main parts:
src/
├── main.c # Main program entry point
├── lib/ # Library code
├── http/ # HTTP protocol handling
├── net/ # Network (socket) handling
└── env/ # Environment variable handling
This is where the program starts. It:
- Sets up the server configuration (port, host address)
- Defines routes (which function handles which URL path)
- Starts the server
// Example from main.c
http.HandleFunc("/", Index); // When someone visits /, run the Index function
http.HandleFunc("/about", About); // When someone visits /about, run the About function
http.ListenAndServe(hostname, router); // Start the serverThis module handles HTTP-specific tasks:
- Parsing HTTP requests (breaking down the data the browser sends)
- Creating HTTP responses (building the data to send back)
- Routing requests to the right function based on URL
- header.h: Contains definitions for HTTP structures and functions
- handle.c: Handles processing of HTTP requests
- req_parser.c: Parses raw HTTP request data into structured form
This module manages the networking aspects:
- Creating a socket (a communication endpoint)
- Binding to a port (setting up where to listen)
- Accepting client connections
- Sending/receiving data
- header.h: Defines network structures and functions
- listener.c: Creates the socket and listens for connections
- serve.c: Accepts connections and processes them
This simple module lets the program read environment variables, which are settings stored outside the program:
- Getting PORT from environment (to change which port the server listens on)
- Getting HOST from environment (to change which address to bind to)
- Startup: The program starts in main.c, configures settings, and defines routes
- Listening: The server creates a socket and starts listening for connections
- Accepting: When a client connects, the server accepts the connection
- Receiving: The server reads the HTTP request from the client
- Parsing: The request is broken down into its components (method, path, headers, etc.)
- Routing: The server finds which function should handle the request based on the URL path
- Processing: The handler function processes the request
- Responding: The server sends back an HTTP response
- Closing: The connection is closed
HTTP communication follows a request-response pattern:
GET /about HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...
This means:
- Method: GET (asking for data)
- Path: /about (what resource we want)
- Version: HTTP/1.1
- Plus some headers with extra information
HTTP/1.1 200 OK
Content-Type: text/html
<html>
<body>
<h1>About Page</h1>
</body>
</html>
This means:
- Version: HTTP/1.1
- Status: 200 OK (success)
- Headers: Content-Type tells the browser this is HTML
- Body: The actual HTML content
Used to organize related data together, like request information:
struct Request {
char method[MAX_METHOD_LEN];
char path[MAX_PATH_LEN];
char version[MAX_VERSION_LEN];
struct Header headers[MAX_HEADERS];
int header_count;
char body[MAX_BODY_LEN];
// ...
};Used to call different functions based on the requested URL:
typedef int(*HandlerFunc)(ResponseWriter w, Request r);
struct Router {
char* patterns[50];
HandlerFunc handlers[50];
};Used for network communication:
int sockfd = socket(AF_INET, SOCK_STREAM, 0);For working with dynamic memory:
Request* req = parse_http_request(buffer);If you want to add a new page to your server, you would:
- Create a handler function:
int Contact(ResponseWriter w, Request r) {
w.Write("Contact Us Page");
return 0;
}- Register the route in main():
http.HandleFunc("/contact", Contact);- Update your router:
Router router = {{"/","/about","/contact",NULL}, {Index,About,Contact,NULL}};- HTTP: HyperText Transfer Protocol - the protocol used for web communication
- Socket: A software endpoint that establishes communication between processes
- Port: A virtual "doorway" where network connections start and end
- Request: A message from client to server asking for something
- Response: A message from server to client providing an answer
- Route/Path: The part of a URL that specifies which resource is being requested
- Handler Function: Code that processes a specific type of request
- Socket: A communication endpoint for sending/receiving data over a network
- Binding: Associating a socket with an IP address and port number
- Listening: Waiting for incoming connection requests
- Parsing: Breaking down raw data into a structured format
To compile and run the server:
make # Compiles the code and runs the serverIf the default port (9000) is already in use, you can change it:
export PORT=8080
makeThen, open a web browser and navigate to:
http://localhost:8080/
- The Makefile compiles all the source files into object files
- These are linked together into the final executable (bin/server)
- When run, the server:
- Configures itself based on environment variables
- Defines the routes and handlers
- Creates a socket
- Binds to the specified port
- Starts listening for connections
- When a connection arrives, it accepts it and processes the request
- It sends back a response
- Then it waits for the next connection