Nilorea Library
C utilities for networking, threading, graphics
Loading...
Searching...
No Matches
HTTP FORMS: strict percent, query and urlencoded decoding

Data Structures

struct  N_HTTP_FIELD
 one decoded name=value pair; both are NUL-terminated and hold no NUL More...
struct  N_HTTP_FORM
 decoded fields, in the order they were sent More...
struct  N_HTTP_FORM_MULTIPART
 a parsed multipart/form-data body More...
struct  N_HTTP_FORM_PART
 one part of a multipart/form-data body; the body is NOT copied More...

Macros

#define N_HTTP_FORM_BOUNDARY_MAX   70
 longest boundary RFC 2046 allows
#define N_HTTP_FORM_PART_FILENAME_MAX   255
 longest multipart filename accepted
#define N_HTTP_FORM_PART_HEAD_MAX   8192
 largest header block of one part
#define N_HTTP_FORM_PART_NAME_MAX   200
 longest multipart field name accepted
#define N_HTTP_FORM_PART_TYPE_MAX   127
 longest part Content-Type kept
#define N_HTTP_FORM_PLUS_SPACE   1
 decode '+' as a space (query strings and urlencoded forms, not paths)
#define N_HTTP_FORM_RAW_BYTES   2
 accept decoded bytes that are not well-formed UTF-8 (NUL stays refused)
#define N_HTTP_FORM_SKIP_INVALID   4
 n_http_form_parse(): drop a pair that fails to decode instead of failing

Functions

size_t n_http_form_count (const N_HTTP_FORM *form, const char *name)
 number of fields named name (exact, case-sensitive)
void n_http_form_free (N_HTTP_FORM **form)
 free a form and set *form to NULL
const char * n_http_form_get (const N_HTTP_FORM *form, const char *name, size_t *value_len)
 value of the LAST field named name, like PHP's $_GET / $_POST
int n_http_form_multipart_boundary (const char *content_type, size_t len, char *out)
 boundary of a multipart/form-data Content-Type, parsed strictly
size_t n_http_form_multipart_count (const N_HTTP_FORM_MULTIPART *mp, const char *name)
 number of parts named name
void n_http_form_multipart_free (N_HTTP_FORM_MULTIPART **mp)
 free a parsed body and set *mp to NULL
const N_HTTP_FORM_PART * n_http_form_multipart_get (const N_HTTP_FORM_MULTIPART *mp, const char *name)
 the LAST part named name (PHP semantics, like n_http_form_get())
N_HTTP_FORM_MULTIPART * n_http_form_multipart_parse (const char *buf, size_t len, const char *boundary, size_t max_parts)
 parse a multipart/form-data body strictly, without copying it
N_HTTP_FORM * n_http_form_parse (const char *s, size_t len, size_t max_fields, int flags)
 decode a query string or an urlencoded body into fields
int n_http_percent_decode (const char *s, size_t len, int flags, N_STR **out)
 percent-decode [s, s+len), appending to *out

Detailed Description


Data Structure Documentation

◆ N_HTTP_FIELD

struct N_HTTP_FIELD

one decoded name=value pair; both are NUL-terminated and hold no NUL

Definition at line 66 of file n_http_form.h.

Collaboration diagram for N_HTTP_FIELD:
Data Fields
char * name decoded name
size_t name_len length of name
char * value decoded value, "" for "name" or "name="
size_t value_len length of value

◆ N_HTTP_FORM

struct N_HTTP_FORM

decoded fields, in the order they were sent

Examples
ex_http_form.c.

Definition at line 78 of file n_http_form.h.

Collaboration diagram for N_HTTP_FORM:
Data Fields
N_HTTP_FIELD * fields the fields, nb_fields of them
size_t nb_fields number of fields

◆ N_HTTP_FORM_MULTIPART

struct N_HTTP_FORM_MULTIPART

a parsed multipart/form-data body

Examples
ex_http_form.c.

Definition at line 161 of file n_http_form.h.

Collaboration diagram for N_HTTP_FORM_MULTIPART:
Data Fields
size_t nb_parts number of parts
N_HTTP_FORM_PART * parts the parts, in order

◆ N_HTTP_FORM_PART

struct N_HTTP_FORM_PART

one part of a multipart/form-data body; the body is NOT copied

Examples
ex_http_form.c.

Definition at line 144 of file n_http_form.h.

Collaboration diagram for N_HTTP_FORM_PART:
Data Fields
size_t body_len body length
size_t body_off body offset in the parsed buffer
char content_type[127+1] the part's Content-Type as sent, "" when absent: untrusted
char filename[255+1] the filename as sent (UTF-8, no control byte, may be ""): untrusted, never use it as a path
int has_filename non-zero when the part carried a filename parameter (a file field)
char name[200+1] field name (non-empty, UTF-8, no control byte)

Macro Definition Documentation

◆ N_HTTP_FORM_BOUNDARY_MAX

#define N_HTTP_FORM_BOUNDARY_MAX   70

longest boundary RFC 2046 allows

Examples
ex_http_form.c.

Definition at line 133 of file n_http_form.h.

Referenced by n_http_form_multipart_boundary(), n_http_form_multipart_parse(), and test_multipart().

◆ N_HTTP_FORM_PART_FILENAME_MAX

#define N_HTTP_FORM_PART_FILENAME_MAX   255

longest multipart filename accepted

Definition at line 137 of file n_http_form.h.

Referenced by _mp_part_headers().

◆ N_HTTP_FORM_PART_HEAD_MAX

#define N_HTTP_FORM_PART_HEAD_MAX   8192

largest header block of one part

Examples
ex_http_form.c.

Definition at line 141 of file n_http_form.h.

Referenced by n_http_form_multipart_parse(), and test_multipart().

◆ N_HTTP_FORM_PART_NAME_MAX

#define N_HTTP_FORM_PART_NAME_MAX   200

longest multipart field name accepted

Examples
ex_http_form.c.

Definition at line 135 of file n_http_form.h.

Referenced by _mp_part_headers(), and test_multipart().

◆ N_HTTP_FORM_PART_TYPE_MAX

#define N_HTTP_FORM_PART_TYPE_MAX   127

longest part Content-Type kept

Definition at line 139 of file n_http_form.h.

Referenced by _mp_part_headers().

◆ N_HTTP_FORM_PLUS_SPACE

#define N_HTTP_FORM_PLUS_SPACE   1

decode '+' as a space (query strings and urlencoded forms, not paths)

Examples
ex_http_form.c.

Definition at line 59 of file n_http_form.h.

Referenced by _form_decode_into(), n_http_form_parse(), and test_decode().

◆ N_HTTP_FORM_RAW_BYTES

#define N_HTTP_FORM_RAW_BYTES   2

accept decoded bytes that are not well-formed UTF-8 (NUL stays refused)

Examples
ex_http_form.c.

Definition at line 61 of file n_http_form.h.

Referenced by _form_decode_dup(), n_http_form_parse(), test_decode(), and test_form().

◆ N_HTTP_FORM_SKIP_INVALID

#define N_HTTP_FORM_SKIP_INVALID   4

n_http_form_parse(): drop a pair that fails to decode instead of failing

Examples
ex_http_form.c.

Definition at line 63 of file n_http_form.h.

Referenced by n_http_form_parse(), and test_form().

Function Documentation

◆ n_http_form_count()

size_t n_http_form_count ( const N_HTTP_FORM * form,
const char * name )

number of fields named name (exact, case-sensitive)

Parameters
formthe parsed form
namethe decoded name
Returns
the count, 0 on a NULL argument

number of fields named name (exact, case-sensitive)

Parameters
formthe parsed form
namethe decoded name
Returns
the count, 0 on a NULL argument

Definition at line 241 of file n_http_form.c.

References N_HTTP_FORM::fields, N_HTTP_FIELD::name, and N_HTTP_FORM::nb_fields.

Referenced by test_form().

Here is the caller graph for this function:

◆ n_http_form_free()

void n_http_form_free ( N_HTTP_FORM ** form)

free a form and set *form to NULL

Parameters
formaddress of the form pointer (may point to NULL)

Definition at line 129 of file n_http_form.c.

References FreeNoLog.

Referenced by n_http_form_parse(), and test_form().

Here is the caller graph for this function:

◆ n_http_form_get()

const char * n_http_form_get ( const N_HTTP_FORM * form,
const char * name,
size_t * value_len )

value of the LAST field named name, like PHP's $_GET / $_POST

The last occurrence wins, as in PHP, so a server ported from PHP keeps its behaviour on repeated parameters. Use n_http_form_count() to refuse repeats, or walk fields[] for list fields ("tag[]").

Parameters
formthe parsed form
namethe exact (case-sensitive) decoded name
value_lenreceives the value length (may be NULL)
Returns
the value, or NULL when absent or on a NULL argument

value of the LAST field named name, like PHP's $_GET / $_POST

Parameters
formthe parsed form
namethe exact (case-sensitive) decoded name
value_lenreceives the value length (may be NULL)
Returns
the value, or NULL when absent or on a NULL argument

Definition at line 218 of file n_http_form.c.

References N_HTTP_FORM::fields, N_HTTP_FIELD::name, N_HTTP_FORM::nb_fields, N_HTTP_FIELD::value, and N_HTTP_FIELD::value_len.

Referenced by test_form().

Here is the caller graph for this function:

◆ n_http_form_multipart_boundary()

int n_http_form_multipart_boundary ( const char * content_type,
size_t len,
char * out )

boundary of a multipart/form-data Content-Type, parsed strictly

The media type must be multipart/form-data (any case); parameters are split on ';' (a "boundary=" inside another parameter's quoted value is not taken); exactly one boundary parameter, token or quoted, 1 to 70 RFC 2046 characters, not ending with a space.

Parameters
content_typethe header value
lenits length
outreceives the boundary, at least N_HTTP_FORM_BOUNDARY_MAX + 1 bytes
Returns
TRUE, FALSE when not a valid multipart/form-data type
Parameters
content_typethe header value
lenits length
outreceives the boundary, at least N_HTTP_FORM_BOUNDARY_MAX + 1 bytes
Returns
TRUE, FALSE when not a valid multipart/form-data type

Definition at line 354 of file n_http_form.c.

References _mp_bchar(), _mp_ieq(), _mp_next_param(), N_HTTP_FORM_BOUNDARY_MAX, _mp_param::name, _mp_param::name_len, _mp_param::value, and _mp_param::value_len.

Here is the call graph for this function:

◆ n_http_form_multipart_count()

size_t n_http_form_multipart_count ( const N_HTTP_FORM_MULTIPART * mp,
const char * name )

number of parts named name

Parameters
mpthe parsed body
namethe field name
Returns
the count, 0 on a NULL argument

number of parts named name

Parameters
mpthe parsed body
namethe field name
Returns
the count, 0 on a NULL argument

Definition at line 604 of file n_http_form.c.

References N_HTTP_FORM_PART::name, N_HTTP_FORM_MULTIPART::nb_parts, and N_HTTP_FORM_MULTIPART::parts.

Referenced by test_multipart().

Here is the caller graph for this function:

◆ n_http_form_multipart_free()

void n_http_form_multipart_free ( N_HTTP_FORM_MULTIPART ** mp)

free a parsed body and set *mp to NULL

Parameters
mpaddress of the pointer (may point to NULL)

Definition at line 618 of file n_http_form.c.

References FreeNoLog.

Referenced by n_http_form_multipart_parse(), and test_multipart().

Here is the caller graph for this function:

◆ n_http_form_multipart_get()

const N_HTTP_FORM_PART * n_http_form_multipart_get ( const N_HTTP_FORM_MULTIPART * mp,
const char * name )

the LAST part named name (PHP semantics, like n_http_form_get())

Parameters
mpthe parsed body
namethe field name
Returns
the part, or NULL

the LAST part named name (PHP semantics, like n_http_form_get())

Parameters
mpthe parsed body
namethe field name
Returns
the part, or NULL

Definition at line 588 of file n_http_form.c.

References N_HTTP_FORM_PART::name, N_HTTP_FORM_MULTIPART::nb_parts, and N_HTTP_FORM_MULTIPART::parts.

Referenced by test_multipart().

Here is the caller graph for this function:

◆ n_http_form_multipart_parse()

N_HTTP_FORM_MULTIPART * n_http_form_multipart_parse ( const char * buf,
size_t len,
const char * boundary,
size_t max_parts )

parse a multipart/form-data body strictly, without copying it

Works on any buffer, an mmap of an uploaded file included: part bodies are offsets into it. Refused (NULL): no delimiter at the start (a preamble up to 1 KiB before a CRLF-led delimiter is allowed), a missing closing delimiter (a truncated upload), more than max_parts parts, a part header block over N_HTTP_FORM_PART_HEAD_MAX or with a malformed line, a part without "Content-Disposition: form-data" and a non-empty name, a repeated disposition parameter (two name=, the classic parameter confusion), a name or filename too long, not UTF-8 or holding a control byte.

Parameters
bufthe body
lenits length
boundaryfrom n_http_form_multipart_boundary()
max_partslargest number of parts accepted, at least 1
Returns
the parts (free with n_http_form_multipart_free()), NULL when refused
Parameters
bufthe body
lenits length
boundaryfrom n_http_form_multipart_boundary()
max_partslargest number of parts accepted, at least 1
Returns
the parts (free with n_http_form_multipart_free()), NULL when refused

Definition at line 507 of file n_http_form.c.

References __n_assert, _mp_find_delim(), _mp_part_headers(), _MP_PREAMBLE_MAX, N_HTTP_FORM_PART::body_len, N_HTTP_FORM_PART::body_off, Free, Malloc, N_HTTP_FORM_BOUNDARY_MAX, n_http_form_multipart_free(), N_HTTP_FORM_PART_HEAD_MAX, N_HTTP_FORM_MULTIPART::nb_parts, and N_HTTP_FORM_MULTIPART::parts.

Referenced by mp_parse(), and test_multipart().

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

◆ n_http_form_parse()

N_HTTP_FORM * n_http_form_parse ( const char * s,
size_t len,
size_t max_fields,
int flags )

decode a query string or an urlencoded body into fields

Pairs are separated by '&'; empty pairs ("a=1&&b=2") are skipped; a pair without '=' has an empty value. Names and values are decoded with n_http_percent_decode() and '+' as a space. More than max_fields pairs is an error even with N_HTTP_FORM_SKIP_INVALID, as is an empty name.

Parameters
sthe query (without the '?') or body (may be NULL only when len is 0)
lennumber of bytes
max_fieldslargest number of pairs accepted, at least 1
flagsN_HTTP_FORM_RAW_BYTES, N_HTTP_FORM_SKIP_INVALID
Returns
a new form (free with n_http_form_free()), NULL on error
Parameters
sthe query (without the '?') or body (may be NULL only when len is 0)
lennumber of bytes
max_fieldslargest number of pairs accepted, at least 1
flagsN_HTTP_FORM_RAW_BYTES, N_HTTP_FORM_SKIP_INVALID
Returns
a new form (free with n_http_form_free()), NULL on error

Definition at line 149 of file n_http_form.c.

References __n_assert, _form_decode_dup(), eq(), N_HTTP_FORM::fields, Free, FreeNoLog, LOG_DEBUG, Malloc, n_http_form_free(), N_HTTP_FORM_PLUS_SPACE, N_HTTP_FORM_RAW_BYTES, N_HTTP_FORM_SKIP_INVALID, n_log, N_HTTP_FIELD::name, N_HTTP_FIELD::name_len, N_HTTP_FORM::nb_fields, start(), N_HTTP_FIELD::value, and N_HTTP_FIELD::value_len.

Referenced by test_form().

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

◆ n_http_percent_decode()

int n_http_percent_decode ( const char * s,
size_t len,
int flags,
N_STR ** out )

percent-decode [s, s+len), appending to *out

Refuses a malformed escape, a decoded NUL, and (without N_HTTP_FORM_RAW_BYTES) a result that is not well-formed UTF-8. With N_HTTP_FORM_PLUS_SPACE, '+' becomes a space. On failure *out keeps whatever it held before the call.

Parameters
sencoded bytes (may be NULL only when len is 0)
lennumber of bytes
flagsN_HTTP_FORM_PLUS_SPACE, N_HTTP_FORM_RAW_BYTES
outdestination, appended to (created when *out is NULL)
Returns
TRUE on success, FALSE on invalid input or allocation failure

percent-decode [s, s+len), appending to *out

Parameters
sencoded bytes (may be NULL only when len is 0)
lennumber of bytes
flagsN_HTTP_FORM_PLUS_SPACE, N_HTTP_FORM_RAW_BYTES
outdestination, appended to (created when *out is NULL)
Returns
TRUE on success, FALSE on invalid input or allocation failure

Definition at line 101 of file n_http_form.c.

References __n_assert, _form_decode_dup(), Free, new_nstr(), and nstrcat_ex().

Referenced by decodes_to(), and test_decode().

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