Table of Contents
include/nilorea/n_http_req.h
Pure, strict, bounded parser for an HTTP/1.1 request head. More...
Structures
| Name | |
|---|---|
| struct | n_http_request A parsed request head. |
| struct | n_http_req_limits Limits for n_http_request_parse_ex(). |
| struct | n_http_req_header One header line, as offsets into the parsed buffer: the name is [name_off, name_off + name_len), the value (surrounding spaces and tabs trimmed) is [value_off, value_off + value_len). |
Detailed Description
Pure, strict, bounded parser for an HTTP/1.1 request head.
Author: Castagnier Mickael
Version: 1.0
A small, hardened scanner, not a general HTTP implementation, for the request line + headers a browser / REST client sends, meant for a server that sniffed a "GET " / "POST " on a connection and needs the head before routing.
It faces hostile network input, so it is deliberately narrow: only GET and POST (plus HEAD through n_http_request_parse_ex()), only origin-form targets ("/path?query"), only HTTP/1.0 or 1.1, Content-Length only, no chunked transfer encoding, with the target, header count and declared body all bounded before use, and a duplicate Content-Length or any Transfer-Encoding header rejected to foreclose request smuggling. Header names must be RFC 9110 tokens and header values may not hold control bytes (a bare CR, LF or NUL inside a value is a smuggling and injection vector). No sockets, no allocation, never over-reads its buffer. The OK / INCOMPLETE / ERROR split lets a transport read incrementally.
Every header line is recorded as offsets into the caller's buffer, so a server reads Host, Cookie, Content-Type... with n_http_request_header() without any copy. Those offsets are only meaningful while the buffer that was parsed is unchanged.
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 N_HTTP_REQ_H
#define N_HTTP_REQ_H
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
#define N_HTTP_REQ_HEAD_MAX 16384u
#define N_HTTP_REQ_PATH_MAX 2048u
#define N_HTTP_REQ_HEADERS_MAX 64u
#define N_HTTP_REQ_BODY_MAX (1024u * 1024u)
#define N_HTTP_REQ_BODY_LIMIT_MAX (1024LL * 1024LL * 1024LL)
#define N_HTTP_REQ_AUTH_MAX 256u
typedef enum {
N_HTTP_REQ_GET = 0,
N_HTTP_REQ_POST = 1,
N_HTTP_REQ_HEAD = 2
} n_http_req_method;
#define N_HTTP_REQ_METHOD_BIT(m) (1u << (unsigned)(m))
typedef struct {
size_t name_off;
size_t name_len;
size_t value_off;
size_t value_len;
} n_http_req_header;
typedef struct {
unsigned methods;
long long body_max;
int require_host;
} n_http_req_limits;
typedef struct {
n_http_req_method method;
char path[N_HTTP_REQ_PATH_MAX + 1];
long long content_length;
size_t head_len;
char authorization[N_HTTP_REQ_AUTH_MAX + 1];
int version_minor;
size_t nb_headers;
n_http_req_header headers[N_HTTP_REQ_HEADERS_MAX];
} n_http_request;
typedef enum {
N_HTTP_REQ_OK = 0,
N_HTTP_REQ_INCOMPLETE = 1,
N_HTTP_REQ_ERROR = 2
} n_http_req_status;
n_http_req_status n_http_request_parse(const char* buf, size_t len, n_http_request* out);
n_http_req_status n_http_request_parse_ex(const char* buf, size_t len, const n_http_req_limits* limits, n_http_request* out);
const char* n_http_request_header(const n_http_request* req, const char* buf, const char* name, size_t* value_len);
size_t n_http_request_header_count(const n_http_request* req, const char* buf, const char* name);
#ifdef __cplusplus
}
#endif
#endif /* N_HTTP_REQ_H */
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