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

Pure, strict, bounded parser for an HTTP/1.1 request head. More...

#include <stddef.h>
Include dependency graph for n_http_req.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

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_MAX   (1024u * 1024u)
 Maximum declared Content-Length (body size), in bytes.
#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_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 }
 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

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)

Detailed Description

Pure, strict, bounded parser for an HTTP/1.1 request head.

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, 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. No sockets, no allocation, never over-reads its buffer. The OK / INCOMPLETE / ERROR split lets a transport read incrementally.

Author
Castagnier Mickael
Version
1.0

Definition in file n_http_req.h.


Data Structure Documentation

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

Examples
ex_http_req.c.

Definition at line 68 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_method method
char path[2048u+1]

Macro Definition Documentation

◆ N_HTTP_REQ_AUTH_MAX

#define N_HTTP_REQ_AUTH_MAX   256u

Longest captured Authorization header value.

Definition at line 54 of file n_http_req.h.

Referenced by n_http_request_parse().

◆ N_HTTP_REQ_BODY_MAX

#define N_HTTP_REQ_BODY_MAX   (1024u * 1024u)

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

Definition at line 52 of file n_http_req.h.

Referenced by parse_body_len().

◆ N_HTTP_REQ_HEAD_MAX

#define N_HTTP_REQ_HEAD_MAX   16384u

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

Definition at line 46 of file n_http_req.h.

Referenced by n_http_request_parse().

◆ N_HTTP_REQ_HEADERS_MAX

#define N_HTTP_REQ_HEADERS_MAX   64u

Maximum number of header lines.

Definition at line 50 of file n_http_req.h.

Referenced by n_http_request_parse().

◆ N_HTTP_REQ_PATH_MAX

#define N_HTTP_REQ_PATH_MAX   2048u

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

Definition at line 48 of file n_http_req.h.

Referenced by n_http_request_parse().

Enumeration Type Documentation

◆ n_http_req_method

The methods accepted.

Append-only.

Enumerator
N_HTTP_REQ_GET 
N_HTTP_REQ_POST 

Definition at line 57 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 78 of file n_http_req.h.

Function Documentation

◆ 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 83 of file n_http_req.c.

References n_http_request::authorization, n_http_request::content_length, n_http_request::head_len, le(), n_http_request::method, N_HTTP_REQ_AUTH_MAX, N_HTTP_REQ_ERROR, N_HTTP_REQ_GET, N_HTTP_REQ_HEAD_MAX, N_HTTP_REQ_HEADERS_MAX, N_HTTP_REQ_INCOMPLETE, N_HTTP_REQ_OK, N_HTTP_REQ_PATH_MAX, N_HTTP_REQ_POST, name_eq(), name_token_ok(), parse_body_len(), n_http_request::path, and target_ok().

Referenced by main(), and parse().

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