Serving files over HTTP three ways: synchronous, epoll, and io_uring

https://lobste.rs/rss Hits: 16
Summary

We take a tour of epoll and io_uring through the lens of an HTTP file server, starting off first with a synchronous thread-per-request server as a baseline.You are getting early access to this article as a subscriber. Your support makes articles like this possible. Thank you.A file server is a nice path through which to explore IO methods because we can write a relatively simple program that still does both network and disk IO. And we can, though in this article we won’t, spend no end of time enhancing and optimizing it (on-the-fly compression, integrity checks, keep-alive, uploads, memory usage, etc.)Let's start with some shared code across IO methods.No matter the IO method, we’ll need to be able to listen on a port.#pragma once #include <arpa/inet.h> #include <errno.h> #include <fcntl.h> #include <netinet/in.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <unistd.h> #define DOCROOT "./" #define MAX_REQ_BUF 4096 #define IO_BUF 16384 static inline int listen_socket(uint16_t port) { int fd = socket(AF_INET, SOCK_STREAM, 0); if (fd < 0) { perror("socket"); exit(1); } int yes = 1; setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)); struct sockaddr_in addr = {0}; addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(port); if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("bind"); exit(1); } if (listen(fd, 128) < 0) { perror("listen"); exit(1); } return fd; } common.hWe’ll need to be able to pull the path out of a GET HTTP request.static inline int parse_http_get(const char *req, size_t len, char *out, size_t n) { if (len < 5 || strncmp(req, "GET ", 4) != 0) return -1; const char *p = req + 4; const char *sp = memchr(p, ' ', len - 4); if (!sp) return -1; size_t plen = (size_t)(sp - p); if (plen == 0 || plen >= n) return -1; if (p[0] != '/') return -1; memcpy(out, p, plen); out[plen] = 0; if (plen == 1) { if (n < sizeof("/index.html")) return...

First seen: 2026-05-25 18:21

Last seen: 2026-05-26 09:31