# fasthttp The `fasthttp` module is a high-performance HTTP server library for V that provides low-level socket management and non-blocking I/O. ## Features - **High Performance**: Uses platform-specific I/O multiplexing: - `epoll` on Linux for efficient connection handling - `kqueue` on macOS and BSD for high-performance event notification - **Non-blocking I/O**: Handles multiple concurrent connections efficiently - **Simple API**: Easy-to-use request handler pattern - **Cross-platform**: Supports Linux, macOS, FreeBSD, OpenBSD, NetBSD and DragonFly ## Installation The module is part of the standard V library. Import it in your V code: ```v import fasthttp ``` ## Quick Start Here's a minimal HTTP server example: ```v oksyntax import fasthttp fn handle_request(req fasthttp.HttpRequest) ![]u8 { path := req.buffer[req.path.start..req.path.start + req.path.len].bytestr() mut body := '' mut status_line := '' if path == '/' { body = 'Hello, World!\n' status_line = 'HTTP/1.1 200 OK' } else { body = '${path} not found\n' status_line = 'HTTP/1.1 404 Not Found' } headers := [ status_line, 'Content-Type: text/plain', 'Content-Length: ${body.len}', 'Connection: close', ] header_string := headers.join('\r\n') return '${header_string}\r\n\r\n${body}'.bytes() } fn main() { mut server := fasthttp.new_server(fasthttp.ServerConfig{ port: 3000 handler: handle_request }) or { eprintln('Failed to create server: ${err}') return } println('Server listening on http://localhost:3000') server.run() or { eprintln('error: ${err}') } } ``` ## API Reference ### `HttpRequest` Struct Represents an incoming HTTP request. **Fields:** - `buffer: []u8` - The raw request buffer containing the complete HTTP request - `method: Slice` - The HTTP method (GET, POST, etc.) - `path: Slice` - The request path - `version: Slice` - The HTTP version (e.g., "HTTP/1.1") - `client_conn_fd: int` - Internal socket file descriptor ### `Slice` Struct Represents a slice of the request buffer. **Fields:** - `start: int` - Starting index in the buffer - `len: int` - Length of the slice **Usage:** ```v ignore method := req.buffer[req.method.start..req.method.start + req.method.len].bytestr() path := req.buffer[req.path.start..req.path.start + req.path.len].bytestr() ``` ## Request Handler Pattern The handler function receives an `HttpRequest` and must return either: - `[]u8` - A byte array containing the HTTP response body - An error if processing failed The handler should extract method and path information from the request and route accordingly. **Example:** ```v ignore fn my_handler(req fasthttp.HttpRequest) ![]u8 { method := req.buffer[req.method.start..req.method.start + req.method.len].bytestr() path := req.buffer[req.path.start..req.path.start + req.path.len].bytestr() match method { 'GET' { if path == '/' { return 'Home page'.bytes() } } 'POST' { if path == '/api/data' { return 'Data received'.bytes() } } else {} } return '404 Not Found'.bytes() } ``` ## Response Format Responses should be returned as byte arrays. The server will send them directly to the client as HTTP response bodies. ```v ignore // Simple text response return 'Hello, World!'.bytes() // HTML response return 'Hello'.bytes() // JSON response return '{"message": "success"}'.bytes() ``` ## Example See the complete example in `examples/fasthttp/` for a more detailed server implementation with multiple routes and controllers. ```sh ./v examples/fasthttp ./examples/fasthttp/fasthttp ``` ## Platform Support - **Linux**: Uses `epoll` for high-performance I/O multiplexing - **macOS**: Uses `kqueue` for event notification - **Windows**: Currently not supported ## Performance Considerations - The `fasthttp` module is designed for high throughput and low latency - Handler functions should be efficient; blocking operations will affect other connections - Use goroutines within handlers if you need to perform long-running operations without blocking the I/O loop ## Request-scoped allocation with `-prealloc` When an application is compiled with `-prealloc`, `fasthttp` starts a scoped prealloc arena for each request before decoding the HTTP request and before calling the request handler. All V allocations made by the request parser, the handler, and code called by the handler use that request arena while the handler is running. The arena is freed as a unit after the response no longer needs request-owned data. On Linux the normal response path sends the response synchronously, then ends the request arena. On macOS and BSD the response buffer can be kept by the connection until `kqueue` finishes writing it; in that case `fasthttp` detaches the scope from the request thread and frees it after the write completes. This means request-local V allocations are cheap bump-pointer allocations, and freeing them does not require walking individual objects. Startup state, server state, and allocations made directly by C libraries are not part of a request arena. If a handler starts V `spawn` work while the request scope is active, the generated thread wrapper retains that scope until the spawned function returns; void spawned functions also run inside their own scoped arena, which is freed at thread exit. Manual takeover responses transfer ownership to user code and currently abandon the request arena, so long-lived takeover handlers should manage their own allocation lifetime explicitly. To inspect request arena usage while developing, build with: ```sh v -prealloc -d trace_prealloc run . ``` ## Notes - HTTP headers are currently not parsed; the entire request is available in the buffer - Only the request method, path, and version are parsed automatically - Response status codes and headers must be manually constructed if needed - The module provides low-level access for maximum control and performance