Nilorea Library
C utilities for networking, threading, graphics
Loading...
Searching...
No Matches
n_http_server.c File Reference

HTTP/1.1 server (see n_http_server.h). More...

#include "nilorea/n_http_server.h"
#include "nilorea/n_common.h"
#include "nilorea/n_log.h"
#include "nilorea/n_network.h"
#include "nilorea/n_str.h"
#include <errno.h>
#include <pthread.h>
#include <signal.h>
#include <stdatomic.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <time.h>
#include <unistd.h>
#include <poll.h>
#include <sys/socket.h>
#include <openssl/err.h>
#include <openssl/ssl.h>
Include dependency graph for n_http_server.c:

Go to the source code of this file.

Data Structures

struct  _conn
struct  _ip_slot
struct  N_HTTP_SERVER
 a server (opaque) More...

Macros

#define _IO_CLOSED   0
#define _IO_ERROR   (-1)
#define _IO_STOPPED   (-3)
#define _IO_TIMEOUT   (-2)
#define _SOCK_AGAIN(e)
#define _SOCK_ERR()
#define _SOCK_INTR(e)
#define _SOCK_LEN(n)
#define N_HTTP_SERVER_ACCEPT_MS   250
#define N_HTTP_SERVER_BUF   (N_HTTP_REQ_HEAD_MAX + 16384u)
#define N_HTTP_SERVER_SLICE_MS   250

Functions

static long long _body_chunk (_conn *c, char *dst, size_t want)
static int _body_fail (N_HTTP_SERVER_REQUEST *req, long long rc)
static int _body_start (N_HTTP_SERVER_REQUEST *req, long long max)
static int _content_too_large (const char *b, size_t n)
static void _drop_sigpipe (void)
static int _handshake (_conn *c)
static int _has_head_end (const char *b, size_t n)
static void _ip_release (N_HTTP_SERVER *srv, const char *ip)
static int _ip_take (N_HTTP_SERVER *srv, const char *ip)
static long long _now_ms (void)
static long long _recv (_conn *c, char *dst, size_t cap)
static void _send_error (_conn *c, int status)
static void _serve (_conn *c)
static void _stat_add (N_HTTP_SERVER *srv, unsigned long long *field, long long delta)
static int _unsupported_method (const char *b, size_t n)
static int _value_is (const char *v, size_t n, const char *token)
static int _wait (_conn *c, int for_write)
static void * _worker (void *arg)
static ssize_t _write_fn (void *ctx, const void *buf, size_t len)
void n_http_server_config_defaults (N_HTTP_SERVER_CONFIG *cfg)
 fill a config with the documented defaults
void n_http_server_free (N_HTTP_SERVER **srv)
 free a stopped server and set *srv to NULL
const char * n_http_server_header (const N_HTTP_SERVER_REQUEST *req, const char *name, size_t *len)
 a request header, see n_http_request_header()
N_HTTP_SERVER * n_http_server_new (const N_HTTP_SERVER_CONFIG *cfg)
 bind the listening socket and load the TLS context
int n_http_server_read_body (N_HTTP_SERVER_REQUEST *req, long long max, N_STR **out)
 read the whole body into memory, refusing more than max
int n_http_server_read_body_to_fd (N_HTTP_SERVER_REQUEST *req, long long max, int fd)
 read the whole body into an open file descriptor, refusing more than max
int n_http_server_run (N_HTTP_SERVER *srv)
 serve until n_http_server_stop()
void n_http_server_stats (N_HTTP_SERVER *srv, N_HTTP_SERVER_STATS *out)
 copy of the counters
void n_http_server_stop (N_HTTP_SERVER *srv)
 ask the server to stop (async-signal-safe)

Detailed Description

HTTP/1.1 server (see n_http_server.h).

Author
Castagnier Mickael
Version
1.0
Date
2026

Definition in file n_http_server.c.


Data Structure Documentation

◆ _conn

struct _conn

Definition at line 106 of file n_http_server.c.

Collaboration diagram for _conn:
Data Fields
long long body_left
int body_read
char * buf
long long deadline
size_t head_len
int idle_phase
size_t len
NETWORK * netw
N_HTTP_SERVER * srv
SSL * ssl

◆ _ip_slot

struct _ip_slot

Definition at line 83 of file n_http_server.c.

Collaboration diagram for _ip_slot:
Data Fields
size_t count
char ip[64]

◆ N_HTTP_SERVER

struct N_HTTP_SERVER

a server (opaque)

Examples
ex_http_server.c.

Definition at line 88 of file n_http_server.c.

Collaboration diagram for N_HTTP_SERVER:
Data Fields
N_HTTP_SERVER_CONFIG cfg
pthread_cond_t cond
SSL_CTX * ctx
_ip_slot * ips
NETWORK * listen
pthread_mutex_t lock
size_t nb_threads
size_t qhead
size_t qlen
NETWORK ** queue
N_HTTP_SERVER_STATS stats
atomic_int stop
pthread_t * threads

Macro Definition Documentation

◆ _IO_CLOSED

#define _IO_CLOSED   0

Definition at line 77 of file n_http_server.c.

Referenced by _recv().

◆ _IO_ERROR

#define _IO_ERROR   (-1)

Definition at line 78 of file n_http_server.c.

Referenced by _recv(), and _wait().

◆ _IO_STOPPED

#define _IO_STOPPED   (-3)

Definition at line 80 of file n_http_server.c.

Referenced by _wait().

◆ _IO_TIMEOUT

#define _IO_TIMEOUT   (-2)

Definition at line 79 of file n_http_server.c.

Referenced by _body_fail(), _handshake(), _serve(), and _wait().

◆ _SOCK_AGAIN

#define _SOCK_AGAIN ( e)
Value:
((e) == EAGAIN || (e) == EWOULDBLOCK)

Definition at line 71 of file n_http_server.c.

Referenced by _recv(), and _write_fn().

◆ _SOCK_ERR

#define _SOCK_ERR ( )
Value:
errno

Definition at line 70 of file n_http_server.c.

Referenced by _recv(), _wait(), and _write_fn().

◆ _SOCK_INTR

#define _SOCK_INTR ( e)
Value:
((e) == EINTR)

Definition at line 72 of file n_http_server.c.

Referenced by _recv(), _wait(), and _write_fn().

◆ _SOCK_LEN

#define _SOCK_LEN ( n)
Value:
(n)

Definition at line 73 of file n_http_server.c.

Referenced by _recv(), and _write_fn().

◆ N_HTTP_SERVER_ACCEPT_MS

#define N_HTTP_SERVER_ACCEPT_MS   250

Definition at line 61 of file n_http_server.c.

Referenced by n_http_server_run().

◆ N_HTTP_SERVER_BUF

#define N_HTTP_SERVER_BUF   (N_HTTP_REQ_HEAD_MAX + 16384u)

Definition at line 57 of file n_http_server.c.

Referenced by _serve(), and _worker().

◆ N_HTTP_SERVER_SLICE_MS

#define N_HTTP_SERVER_SLICE_MS   250

Definition at line 59 of file n_http_server.c.

Referenced by _wait().

Function Documentation

◆ _body_chunk()

long long _body_chunk ( _conn * c,
char * dst,
size_t want )
static

Definition at line 338 of file n_http_server.c.

References _recv(), _conn::buf, _conn::head_len, and _conn::len.

Referenced by n_http_server_read_body(), and n_http_server_read_body_to_fd().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _body_fail()

int _body_fail ( N_HTTP_SERVER_REQUEST * req,
long long rc )
static

Definition at line 381 of file n_http_server.c.

References _IO_TIMEOUT, _stat_add(), N_HTTP_SERVER_REQUEST::body_status, N_HTTP_SERVER_REQUEST::conn, _conn::srv, N_HTTP_SERVER::stats, and N_HTTP_SERVER_STATS::timeouts.

Referenced by n_http_server_read_body(), and n_http_server_read_body_to_fd().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _body_start()

◆ _content_too_large()

int _content_too_large ( const char * b,
size_t n )
static

Definition at line 506 of file n_http_server.c.

References le(), and N_HTTP_REQ_BODY_LIMIT_MAX.

Referenced by _serve().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _drop_sigpipe()

void _drop_sigpipe ( void )
static

Definition at line 219 of file n_http_server.c.

Referenced by _handshake(), _worker(), and _write_fn().

Here is the caller graph for this function:

◆ _handshake()

int _handshake ( _conn * c)
static

◆ _has_head_end()

int _has_head_end ( const char * b,
size_t n )
static

Definition at line 480 of file n_http_server.c.

Referenced by _serve().

Here is the caller graph for this function:

◆ _ip_release()

void _ip_release ( N_HTTP_SERVER * srv,
const char * ip )
static

Definition at line 715 of file n_http_server.c.

References N_HTTP_SERVER::cfg, _ip_slot::count, _ip_slot::ip, N_HTTP_SERVER::ips, N_HTTP_SERVER_CONFIG::max_per_ip, and N_HTTP_SERVER_CONFIG::workers.

Referenced by _worker().

Here is the caller graph for this function:

◆ _ip_take()

int _ip_take ( N_HTTP_SERVER * srv,
const char * ip )
static

Definition at line 694 of file n_http_server.c.

References N_HTTP_SERVER::cfg, _ip_slot::count, _ip_slot::ip, N_HTTP_SERVER::ips, N_HTTP_SERVER_CONFIG::max_per_ip, and N_HTTP_SERVER_CONFIG::workers.

Referenced by n_http_server_run().

Here is the caller graph for this function:

◆ _now_ms()

long long _now_ms ( void )
static

Definition at line 123 of file n_http_server.c.

Referenced by _body_start(), _handshake(), _send_error(), _serve(), and _wait().

Here is the caller graph for this function:

◆ _recv()

long long _recv ( _conn * c,
char * dst,
size_t cap )
static

Definition at line 176 of file n_http_server.c.

References _IO_CLOSED, _IO_ERROR, _SOCK_AGAIN, _SOCK_ERR, _SOCK_INTR, _SOCK_LEN, _wait(), NETWORK::link, _conn::netw, N_SOCKET::sock, and _conn::ssl.

Referenced by _body_chunk(), and _serve().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _send_error()

void _send_error ( _conn * c,
int status )
static

◆ _serve()

void _serve ( _conn * c)
static

Definition at line 552 of file n_http_server.c.

References _content_too_large(), _has_head_end(), _IO_TIMEOUT, _now_ms(), _recv(), _send_error(), _stat_add(), _unsupported_method(), _value_is(), _write_fn(), N_HTTP_SERVER_STATS::bad_requests, _conn::body_left, n_http_req_limits::body_max, _conn::body_read, _conn::buf, N_HTTP_SERVER::cfg, N_HTTP_SERVER_REQUEST::conn, n_http_request::content_length, _conn::deadline, Free, N_HTTP_SERVER_CONFIG::handler, N_HTTP_SERVER_REQUEST::head, _conn::head_len, n_http_request::head_len, N_HTTP_SERVER_CONFIG::header_timeout_ms, _conn::idle_phase, N_HTTP_SERVER_CONFIG::idle_timeout_ms, N_SOCKET::ip, _conn::len, NETWORK::link, Malloc, N_HTTP_SERVER_CONFIG::max_body, N_HTTP_SERVER_CONFIG::max_requests_per_conn, n_http_request::method, n_http_req_limits::methods, N_HTTP_REQ_BODY_LIMIT_MAX, N_HTTP_REQ_ERROR, N_HTTP_REQ_GET, N_HTTP_REQ_HEAD, N_HTTP_REQ_HEAD_MAX, N_HTTP_REQ_INCOMPLETE, N_HTTP_REQ_METHOD_BIT, N_HTTP_REQ_POST, n_http_request_parse_ex(), n_http_response_free(), n_http_response_new(), n_http_response_set_connection(), n_http_response_write(), N_HTTP_SERVER_BUF, n_http_server_header(), _conn::netw, n_http_request::path, N_HTTP_SERVER_REQUEST::path, N_HTTP_SERVER_REQUEST::path_len, N_HTTP_SERVER_REQUEST::peer_ip, N_HTTP_SERVER_REQUEST::query, N_HTTP_SERVER_REQUEST::query_len, N_HTTP_SERVER_REQUEST::raw, N_HTTP_SERVER_STATS::requests, n_http_req_limits::require_host, N_HTTP_SERVER_CONFIG::require_host, _conn::srv, _conn::ssl, N_HTTP_SERVER::stats, N_HTTP_RESP::status, N_HTTP_SERVER::stop, N_HTTP_SERVER_REQUEST::target, N_HTTP_SERVER_STATS::timeouts, N_HTTP_SERVER_REQUEST::tls, N_HTTP_SERVER_CONFIG::user, n_http_request::version_minor, and N_HTTP_SERVER_CONFIG::write_timeout_ms.

Referenced by _worker().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _stat_add()

void _stat_add ( N_HTTP_SERVER * srv,
unsigned long long * field,
long long delta )
static

Definition at line 133 of file n_http_server.c.

References N_HTTP_SERVER::lock.

Referenced by _body_fail(), _handshake(), _serve(), and _worker().

Here is the caller graph for this function:

◆ _unsupported_method()

int _unsupported_method ( const char * b,
size_t n )
static

Definition at line 490 of file n_http_server.c.

Referenced by _serve().

Here is the caller graph for this function:

◆ _value_is()

int _value_is ( const char * v,
size_t n,
const char * token )
static

Definition at line 322 of file n_http_server.c.

Referenced by _serve().

Here is the caller graph for this function:

◆ _wait()

int _wait ( _conn * c,
int for_write )
static

Definition at line 142 of file n_http_server.c.

References _IO_ERROR, _IO_STOPPED, _IO_TIMEOUT, _now_ms(), _SOCK_ERR, _SOCK_INTR, _conn::deadline, _conn::idle_phase, NETWORK::link, N_HTTP_SERVER_SLICE_MS, _conn::netw, N_SOCKET::sock, _conn::srv, and N_HTTP_SERVER::stop.

Referenced by _handshake(), _recv(), and _write_fn().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _worker()

◆ _write_fn()

ssize_t _write_fn ( void * ctx,
const void * buf,
size_t len )
static

Definition at line 230 of file n_http_server.c.

References _drop_sigpipe(), _SOCK_AGAIN, _SOCK_ERR, _SOCK_INTR, _SOCK_LEN, _wait(), NETWORK::link, _conn::netw, N_SOCKET::sock, and _conn::ssl.

Referenced by _body_start(), _send_error(), and _serve().

Here is the call graph for this function:
Here is the caller graph for this function: