Nilorea Library
C utilities for networking, threading, graphics
Loading...
Searching...
No Matches
HTTP/1.1 REQUEST HEAD: strict, bounded parser

Data Structures

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). More...
struct  n_http_req_limits
 Limits for n_http_request_parse_ex(). More...
struct  n_http_request
 A parsed request head. More...

Macros

#define N_HTTP_REQ_AUTH_MAX   256u
 Longest captured Authorization header value.
#define N_HTTP_REQ_BODY_LIMIT_MAX   (1024LL * 1024LL * 1024LL)
 Highest body cap n_http_request_parse_ex() accepts (1 GiB).
#define N_HTTP_REQ_BODY_MAX   (1024u * 1024u)
 Maximum declared Content-Length (body size), in bytes, for n_http_request_parse().
#define N_HTTP_REQ_HEAD_MAX   16384u
 Largest request head (request line + headers, through CRLFCRLF) accepted.
#define N_HTTP_REQ_HEADERS_MAX   64u
 Maximum number of header lines.
#define N_HTTP_REQ_METHOD_BIT(m)
 Bit of a method in n_http_req_limits.methods.
#define N_HTTP_REQ_PATH_MAX   2048u
 Longest origin-form request target ('/'-prefixed, query included).

Enumerations

enum  n_http_req_method { N_HTTP_REQ_GET = 0 , N_HTTP_REQ_POST = 1 , N_HTTP_REQ_HEAD = 2 }
 The methods accepted. More...
enum  n_http_req_status { N_HTTP_REQ_OK = 0 , N_HTTP_REQ_INCOMPLETE = 1 , N_HTTP_REQ_ERROR = 2 }
 Result of n_http_request_parse. More...

Functions

const char * n_http_request_header (const n_http_request *req, const char *buf, const char *name, size_t *value_len)
 find a header of a parsed request
size_t n_http_request_header_count (const n_http_request *req, const char *buf, const char *name)
 count the headers of a parsed request that carry a name
n_http_req_status n_http_request_parse (const char *buf, size_t len, n_http_request *out)
 parse an HTTP/1.1 request head from [buf, buf+len)
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)
 parse an HTTP/1.1 request head with caller-chosen limits

Detailed Description


Data Structure Documentation

◆ n_http_req_header

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).

Definition at line 89 of file n_http_req.h.

Collaboration diagram for n_http_req_header:
Data Fields
size_t name_len
size_t name_off
size_t value_len
size_t value_off

◆ n_http_req_limits

struct n_http_req_limits

Limits for n_http_request_parse_ex().

Examples
ex_http_req.c.

Definition at line 97 of file n_http_req.h.

Collaboration diagram for n_http_req_limits:
Data Fields
long long body_max largest accepted Content-Length, 0 to N_HTTP_REQ_BODY_LIMIT_MAX
unsigned methods accepted methods, an OR of N_HTTP_REQ_METHOD_BIT(); any other method is an error
int require_host non-zero: an HTTP/1.1 request must carry exactly one Host header and an HTTP/1.0 one at most one (RFC 9112 section 3.2)

◆ n_http_request

struct n_http_request

A parsed request head.

path is the origin-form target (leading '/', query included, fragment rejected). content_length is the declared body length (0 when there is no Content-Length header). head_len is the byte offset just past the terminating CRLFCRLF, where the body begins in the caller's buffer. authorization is the Authorization header value, empty if absent; an over-long value errors the whole request rather than truncating. version_minor is 0 for HTTP/1.0, 1 for HTTP/1.1. headers[0..nb_headers) lists every header line in arrival order (offsets into the parsed buffer, read them with n_http_request_header()).

Examples
ex_http_req.c.

Definition at line 117 of file n_http_req.h.

Collaboration diagram for n_http_request:
Data Fields
char authorization[256u+1]
long long content_length
size_t head_len
n_http_req_header headers[64u]
n_http_req_method method
size_t nb_headers
char path[2048u+1]
int version_minor

Macro Definition Documentation

◆ N_HTTP_REQ_AUTH_MAX

#define N_HTTP_REQ_AUTH_MAX   256u

Longest captured Authorization header value.

Definition at line 74 of file n_http_req.h.

Referenced by n_http_request_parse_ex().

◆ N_HTTP_REQ_BODY_LIMIT_MAX

#define N_HTTP_REQ_BODY_LIMIT_MAX   (1024LL * 1024LL * 1024LL)

Highest body cap n_http_request_parse_ex() accepts (1 GiB).

Examples
ex_http_req.c.

Definition at line 72 of file n_http_req.h.

Referenced by _content_too_large(), _serve(), main(), n_http_request_parse_ex(), and n_http_server_new().

◆ N_HTTP_REQ_BODY_MAX

#define N_HTTP_REQ_BODY_MAX   (1024u * 1024u)

Maximum declared Content-Length (body size), in bytes, for n_http_request_parse().

n_http_request_parse_ex() takes its own cap.

Definition at line 70 of file n_http_req.h.

Referenced by n_http_request_parse().

◆ N_HTTP_REQ_HEAD_MAX

#define N_HTTP_REQ_HEAD_MAX   16384u

Largest request head (request line + headers, through CRLFCRLF) accepted.

Definition at line 63 of file n_http_req.h.

Referenced by _serve(), and n_http_request_parse_ex().

◆ N_HTTP_REQ_HEADERS_MAX

#define N_HTTP_REQ_HEADERS_MAX   64u

Maximum number of header lines.

Definition at line 67 of file n_http_req.h.

Referenced by n_http_request_header(), n_http_request_header_count(), and n_http_request_parse_ex().

◆ N_HTTP_REQ_METHOD_BIT

#define N_HTTP_REQ_METHOD_BIT ( m)
Value:
(1u << (unsigned)(m))

Bit of a method in n_http_req_limits.methods.

Examples
ex_http_req.c.

Definition at line 84 of file n_http_req.h.

Referenced by _serve(), main(), n_http_request_parse(), n_http_request_parse_ex(), and n_router_match().

◆ N_HTTP_REQ_PATH_MAX

#define N_HTTP_REQ_PATH_MAX   2048u

Longest origin-form request target ('/'-prefixed, query included).

Definition at line 65 of file n_http_req.h.

Referenced by _compile(), n_http_request_parse_ex(), and n_router_match().

Enumeration Type Documentation

◆ n_http_req_method

The methods accepted.

Append-only.

Enumerator
N_HTTP_REQ_GET 
N_HTTP_REQ_POST 
N_HTTP_REQ_HEAD 
Examples
ex_http_router.c.

Definition at line 77 of file n_http_req.h.

◆ n_http_req_status

Result of n_http_request_parse.

The INCOMPLETE / ERROR split lets a transport read incrementally: keep buffering on INCOMPLETE, close on ERROR.

Enumerator
N_HTTP_REQ_OK 

a complete, valid head was parsed

N_HTTP_REQ_INCOMPLETE 

no CRLFCRLF yet, still under the cap

N_HTTP_REQ_ERROR 

malformed / oversized / unsupported

Examples
ex_http_req.c.

Definition at line 130 of file n_http_req.h.

Function Documentation

◆ n_http_request_header()

const char * n_http_request_header ( const n_http_request * req,
const char * buf,
const char * name,
size_t * value_len )

find a header of a parsed request

Looks for the first header whose name matches name, ASCII case-insensitively, among the headers n_http_request_parse() / n_http_request_parse_ex() recorded from buf. The value is not NUL-terminated: use value_len.

Parameters
reqthe parsed request
bufthe same buffer that was parsed, unchanged since
namethe header name, any case
value_lenreceives the value length (may be NULL)
Returns
a pointer to the value inside buf, or NULL if absent or on a NULL argument

Definition at line 253 of file n_http_req.c.

References h(), n_http_request::headers, N_HTTP_REQ_HEADERS_MAX, name_ieq(), and n_http_request::nb_headers.

Referenced by main(), and n_http_server_header().

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

◆ n_http_request_header_count()

size_t n_http_request_header_count ( const n_http_request * req,
const char * buf,
const char * name )

count the headers of a parsed request that carry a name

Lets a caller refuse a repeated header that must be unique (Host, Cookie, Content-Type...).

Parameters
reqthe parsed request
bufthe same buffer that was parsed, unchanged since
namethe header name, any case
Returns
the number of header lines named name, 0 on a NULL argument

Definition at line 271 of file n_http_req.c.

References h(), n_http_request::headers, N_HTTP_REQ_HEADERS_MAX, name_ieq(), and n_http_request::nb_headers.

Referenced by main().

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

◆ n_http_request_parse()

n_http_req_status n_http_request_parse ( const char * buf,
size_t len,
n_http_request * out )

parse an HTTP/1.1 request head from [buf, buf+len)

Returns N_HTTP_REQ_OK only when a complete head (through CRLFCRLF) is present and every rule holds: the method is GET or POST; the target is origin-form ('/'-prefixed, no spaces or control bytes, no fragment, within N_HTTP_REQ_PATH_MAX); the version is HTTP/1.0 or 1.1; at most N_HTTP_REQ_HEADERS_MAX headers; no Transfer-Encoding; at most one Content-Length, a valid non-negative integer within N_HTTP_REQ_BODY_MAX. On OK, out is filled and out->head_len marks the body start.

Returns N_HTTP_REQ_INCOMPLETE when no CRLFCRLF has arrived yet and the buffered bytes are still under N_HTTP_REQ_HEAD_MAX (read more), and N_HTTP_REQ_ERROR for anything malformed, unsupported, or over the head cap. Bounded and over-read safe on every path.

Parameters
bufthe received bytes (may be NULL)
lennumber of bytes in buf
outthe request head to fill (zeroed first)
Returns
one of n_http_req_status

Definition at line 245 of file n_http_req.c.

References n_http_req_limits::body_max, n_http_req_limits::methods, N_HTTP_REQ_BODY_MAX, N_HTTP_REQ_GET, N_HTTP_REQ_METHOD_BIT, N_HTTP_REQ_POST, n_http_request_parse_ex(), and n_http_req_limits::require_host.

Referenced by main(), and parse().

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

◆ n_http_request_parse_ex()

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 )

parse an HTTP/1.1 request head with caller-chosen limits

Same rules and results as n_http_request_parse(), except that the accepted methods, the largest Content-Length and the Host requirement come from limits. n_http_request_parse() is this function with GET and POST, N_HTTP_REQ_BODY_MAX and no Host requirement. A NULL limits, an empty method set or a body_max outside 0..N_HTTP_REQ_BODY_LIMIT_MAX is an error.

Parameters
bufthe received bytes (may be NULL)
lennumber of bytes in buf
limitsaccepted methods, body cap, Host rule
outthe request head to fill (zeroed first)
Returns
one of n_http_req_status

Definition at line 110 of file n_http_req.c.

References n_http_request::authorization, n_http_req_limits::body_max, n_http_request::content_length, n_http_request::head_len, n_http_request::headers, le(), n_http_request::method, n_http_req_limits::methods, N_HTTP_REQ_AUTH_MAX, 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_HEADERS_MAX, N_HTTP_REQ_INCOMPLETE, N_HTTP_REQ_METHOD_BIT, N_HTTP_REQ_OK, N_HTTP_REQ_PATH_MAX, N_HTTP_REQ_POST, name_eq(), n_http_req_header::name_len, n_http_req_header::name_off, name_token_ok(), n_http_request::nb_headers, parse_body_len(), n_http_request::path, n_http_req_limits::require_host, target_ok(), n_http_req_header::value_len, n_http_req_header::value_off, value_ok(), and n_http_request::version_minor.

Referenced by _serve(), main(), and n_http_request_parse().

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