SwiftServe made for fun is a minimalist, high-performance HTTP server written in C++. It is designed to be simple to use while providing powerful features for building web applications and APIs. SwiftServe focuses on non-blocking I/O and efficient request handling to achieve low latency and high throughput.
- Non-blocking I/O powered by
poll(2) - Full HTTP/1.1 protocol support (keep-alive by default)
- Regex-based route matching with capture groups
- Supports GET, HEAD, POST, PUT, PATCH, DELETE, and OPTIONS methods
- Chunked transfer encoding (both request and response)
- Built-in static file server with:
- MIME type detection
- Byte-range requests (
Rangeheader) - Conditional caching (
If-Modified-Since) - Automatic directory listing
- Streaming file responses for large files
- Chunked request trailer headers
- Cookie and query string parsing
- Safe path resolution (blocks directory traversal attacks)
- A C++20 compatible compiler (GCC 11+, Clang 14+)
- Linux or macOS (uses POSIX
poll) makeorcmake
Using Make:
makeUsing CMake:
mkdir build && cd build
cmake ..
make./swiftserve -p 8080 -d ./public| Flag | Description | Default |
|---|---|---|
-p, --port |
Port to listen on | 8080 |
-d, --directory |
Directory to serve | ./ |
-h, --help |
Show help message |
Open your browser and visit http://localhost:8080/.
SwiftServe can also be used as a library to build custom HTTP applications.
#include "http/server.h"
int main() {
swiftserve::http::Server server;
server.get("/hello", [](swiftserve::http::Request* req,
swiftserve::http::Response* res) {
res->status(200)->end("Hello, World!");
});
server.start(8080, [] { return 3500; });
return 0;
}server.get("/user/(\\d+)", [](swiftserve::http::Request* req,
swiftserve::http::Response* res) {
std::string user_id = req->params[1];
res->status(200)->end("User ID: " + user_id);
});server.post("/submit",
swiftserve::http::Server::with_body(
[](swiftserve::http::Request* req,
swiftserve::http::Response* res,
const char* data, int length) {
std::string body(data, length);
res->status(200)->end("Received: " + body);
}
)
);server.get("/download", [](swiftserve::http::Request* req,
swiftserve::http::Response* res) {
auto reader = std::make_shared<swiftserve::http::FileBodyReader>(
std::make_unique<std::ifstream>("largefile.bin", std::ios::binary),
file_size
);
res->status(200)->stream(reader, {{"Content-Type", "application/octet-stream"}});
});server.get(".*", [](swiftserve::http::Request* req,
swiftserve::http::Response* res) {
swiftserve::http::serve_static("./public", req, res);
});| Property | Type | Description |
|---|---|---|
method |
std::string |
HTTP method (GET, POST, etc.) |
raw_uri |
std::string |
Original URI from the request line |
path |
std::string |
Decoded, normalised path |
raw_query |
std::string |
Raw query string after ? |
headers |
HeaderMap |
Request headers |
trailers |
HeaderMap |
Trailer headers (chunked requests only) |
params |
std::smatch |
Regex capture groups from route matching |
query() |
const HeaderMap& |
Lazy-parsed query parameters |
cookies() |
const HeaderMap& |
Lazy-parsed cookies |
| Method | Description |
|---|---|
status(int code) |
Set the HTTP status code |
content_length(long len) |
Set Content-Length (omit for chunked) |
end(body, headers) |
Send complete response |
write_head(code, headers) |
Send headers only |
write(data) |
Write a chunk of body data |
stream(reader, headers) |
Stream a file or generated content |
close() |
Close the connection |
MIT @nayandas69