1 n__http__server_8h
gullradriel edited this page 2026-10-25 10:46:33 +01:00

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 */