Table of Contents
include/nilorea/n_http_server.h
HTTP/1.1 server: TLS or plain, deadlines, limits, keep-alive. More...
Structures
| Name | |
|---|---|
| struct | N_HTTP_SERVER_STATS counters, see n_http_server_stats() |
| struct | N_HTTP_SERVER_REQUEST a request as the handler sees it (fields are read-only) |
| struct | N_HTTP_SERVER_CONFIG server settings; start from n_http_server_config_defaults() |
Detailed Description
HTTP/1.1 server: TLS or plain, deadlines, limits, keep-alive.
Author: Castagnier Mickael
Version: 1.0
Date: 2026
One accept loop hands sockets to a fixed pool of worker threads through a bounded queue; a connection keeps its worker for its whole life, so the pool size is the connection cap, and a full queue refuses new connections. Every socket operation is non-blocking under a deadline: the TLS handshake, the request head (counted from its first byte), the body, each response and the keep-alive wait each have a TOTAL time limit, so a peer that trickles one byte at a time gets nowhere. Heads are parsed by n_http_request_parse_ex() (no chunked bodies, no smuggling). Bodies are read only when the handler asks for them, with its own size cap, into memory or a file; a body left unread closes the connection after the response. Keep-alive and pipelining are supported. The server answers 400, 408, 413, 417, 431, 500, 501 (a well-formed method other than GET, HEAD and POST) and 503 itself.
SIGPIPE is blocked in the worker threads only (a peer closing mid-write is an error return, not a dead process); the application's own signal setup is untouched. n_http_server_stop() is async-signal-safe.
Source code
/*
* Nilorea Library
* Copyright (C) 2005-2026 Castagnier Mickael
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __NILOREA_HTTP_SERVER_HEADER
#define __NILOREA_HTTP_SERVER_HEADER
#ifdef __cplusplus
extern "C" {
#endif
#include "nilorea/n_http_req.h"
#include "nilorea/n_http_response.h"
#include "nilorea/n_str.h"
#include <stddef.h>
struct N_HTTP_SERVER_REQUEST;
typedef N_HTTP_RESP* (*n_http_server_handler)(struct N_HTTP_SERVER_REQUEST* req, void* user);
typedef struct N_HTTP_SERVER_CONFIG {
const char* addr;
const char* port;
const char* tls_key_file;
const char* tls_cert_file;
size_t workers;
size_t max_per_ip;
int handshake_timeout_ms;
int header_timeout_ms;
int idle_timeout_ms;
int body_timeout_ms;
int write_timeout_ms;
size_t max_requests_per_conn;
long long max_body;
int require_host;
n_http_server_handler handler;
void* user;
} N_HTTP_SERVER_CONFIG;
typedef struct N_HTTP_SERVER_REQUEST {
n_http_request head;
const char* raw;
const char* path;
size_t path_len;
const char* query;
size_t query_len;
const char* peer_ip;
int tls;
int body_status;
void* conn;
char target[N_HTTP_REQ_PATH_MAX + 2];
} N_HTTP_SERVER_REQUEST;
typedef struct N_HTTP_SERVER_STATS {
unsigned long long accepted;
unsigned long long refused;
unsigned long long active;
unsigned long long requests;
unsigned long long timeouts;
unsigned long long bad_requests;
unsigned long long tls_failures;
} N_HTTP_SERVER_STATS;
typedef struct N_HTTP_SERVER N_HTTP_SERVER;
void n_http_server_config_defaults(N_HTTP_SERVER_CONFIG* cfg);
N_HTTP_SERVER* n_http_server_new(const N_HTTP_SERVER_CONFIG* cfg);
int n_http_server_run(N_HTTP_SERVER* srv);
void n_http_server_stop(N_HTTP_SERVER* srv);
void n_http_server_free(N_HTTP_SERVER** srv);
void n_http_server_stats(N_HTTP_SERVER* srv, N_HTTP_SERVER_STATS* out);
const char* n_http_server_header(const N_HTTP_SERVER_REQUEST* req, const char* name, size_t* len);
int n_http_server_read_body(N_HTTP_SERVER_REQUEST* req, long long max, N_STR** out);
int n_http_server_read_body_to_fd(N_HTTP_SERVER_REQUEST* req, long long max, int fd);
#ifdef __cplusplus
}
#endif
#endif /* __NILOREA_HTTP_SERVER_HEADER */
Modules
- AABB3D
- ACCEPT_POOL
- ALLEGRO4
- ALLEGRO5
- ANIM_LIB
- ASTAR
- ATLAS_LIB
- AVRO
- CLOCK_SYNC
- COMMONS
- CONFIGFILE
- CYPHER_BASE64
- CYPHER_VIGENERE
- DEAD_RECKONING
- ENUMS
- EXCEPTIONS
- GAME_ENV
- GIT
- GUI
- HASH_TABLE
- ISOMETRIC_ENGINE
- LIST
- LOG
- LOGNODUP
- LZ4
- NETWORKING
- NETWORK_MSG
- N_COOKIES
- N_DIFF
- N_DIGEST
- N_DISK_CACHE
- N_DNS
- N_ECC
- N_ENTROPY
- N_FILES
- N_FLUIDS
- N_GUI_COLOR
- N_GUI_COLORWHEEL
- N_GUI_CURVE
- N_GUI_GRID
- N_GUI_POPUP
- N_HEX
- N_HTTP3
- N_HTTP_COOKIE
- N_HTTP_FORM
- N_HTTP_MIME
- N_HTTP_REQ
- N_HTTP_RESP
- N_HTTP_ROUTER
- N_HTTP_SERVER
- N_ICC
- N_JSON
- N_KAFKA
- N_LINALG
- N_MODULE
- N_OPENSSL_COMPAT
- N_PRETTY
- N_PTH
- N_QUERY
- N_RANDOM
- N_SHA256
- N_STR
- N_TIFF
- N_TIME
- N_USER
- N_X509
- N_ZIP
- PARTICLES
- PCRE
- PHYSICS
- SIGNALS
- STACK
- THREADS
- TRAJECTORY
- TREE
- ZLIB