Lightweight HTTP Server in C, with HTTPS support. Serves static files, supports MIME type detection, handles directory listing (with basic vim motions) and file previews with proper HTTP responses.
I wanted to know more about HTTP requests & servers, request-handling, and have some experience in C. Plus whenever I was using a local server, I was missing the vim motions to navigate around in the file tree.
So I decided to build one for a hopefully great learning experience and my personal usage.
It would have been a lot easier to do this in JavaScript, but I chose C to get low-level and get to have some experience with manipulating sockets, file-descriptors, HTTP Protocol with its headers and MIME types, and the C language in general.
Update:
Over the iterations, I have made this server capable of hosting a real website
.
Currently I am hosting my own website using this exact server here: navrajkalsi.com
- Supports Linux & most UNIX systems, as most libraries used are part of the C standard.
- Uses threads for concurrent processing of requests.
- TLS is used to support HTTPS, done using
openssl
. - MIME detection ensures proper previewing of file, done using
libmagic
. - Supported formats for preview: Text, Images, PDFs.
- Informs if a requested file is empty or unsupported for preview(can be downloaded in that case), with help of content-type header.
- Supports keep-alive connections with socket timeouts.
- Directory listing is done by using a static html file & javascript.
- Custom Error Page is served in case of any error, which changes dynamically based on the response status code.
- Clean Shutdown is done by handling interrupt and kill signals.
- URL Decoding of ASCII chars from hex digits.
AS OF NOW, THIS SERVER ONLY SUPPORTS UNIX SYSTEMS.
For Windows
, winsock API has to be implemented. Although, WSL
can be used in that case.
Install Dependencies
The following dependencies are required to build and run the program on Linux:
gcc
: C Compilermake
: Project buildlibmagic
: MIME detectionopenssl
: TLS handling & HTTPS support
If using a package manager, please check to see the exact names of these programs for your distro.
Download the source
git clone https://github.com/navrajkalsi/server-c
cd server-c
Build the project
# Building
make
# Installing the binary & static files
make install
# Cleaning build objects
make clean
# Uninstall
make uninstall
Variable | Default | Description |
---|---|---|
STATIC_DIR | "/usr/local/share/server-c/static" | Directory in which the server will look for static support files(_server.html, _server.js, _error.html, etc). |
DESTDIR | To create a staging environment & manage files manually. | |
DOMAIN_CERT | "/etc/ssl/domain/domain.cert" | Path to domain certificate for HTTPS. |
PRIVATE_KEY | "/etc/ssl/domain/private.key" | Path to private key for HTTPS. |
STATIC_DIR, DOMAIN_CERT & PRIVATE_KEY CAN ONLY BE CHANGED DURING COMPILATION, i.e., during make
, as it is used as a preprocessor macro.
If server-c
command is not found after installation, the directory in which the binary got installed is not on the PATH.
ADD THE MAKE INSTALLATION DIRECTORY TO THE PATH AND TRY AGAIN.
The following flags can be used to alter the behaviour of the program:
Flag | Flag Description | Required Argument | Default |
---|---|---|---|
-a | Listen to connections on all interfaces of the machine | Localhost only | |
-d | Debug Mode (Prints all functions calls to the console) | ||
-h | Print usage on command line | ||
-p | Port to listen on | Port number | 1419 |
-r | Root of the directory to serve | Directory path | Current directory |
-s | Use HTTPS (Remember to configure HTTPS files) | HTTP only | |
-v | Print version number |
The following url param can be used to alter the behaviour, when serving a directory:
Param | true | false | Default |
---|---|---|---|
show_dir | Always list directory contents. Ignores index.html, if found. | List directory contents, if no index.html is found. Otherwise, serves index.html when requesting directory. | false |
server-c
By default:
- Serves the current working directory.
- Uses port 1419.
- Listens to only localhost requests.
- Uses HTTP only.
- Prints the client's address, request method & path on the console.
- Serves index.html, if a directory is requested and index.html is present.
server-c -a -p 8080 -r /DIR_TO_SERVE -s
- Serves 'DIR_TO_SERVE' on port 8080 and listens to all requests from all IPs.
- Here, since we have passed -a flag, we can access files on your machine from different devices by visiting the IP address of your machine and targeting the appropriate port.
- Domain certificate & private keys is used to enable TLS.
See CHANGELOG.md for changes made.