39 if ((c >=
'a' && c <=
'z') || (c >=
'A' && c <=
'Z') || (c >=
'0' && c <=
'9'))
41 return c !=
'\0' && strchr(
"!#$%&'*+-.^_`|~", c) != NULL;
48 for (i = 0; i < n; i++)
56 return c == 0x21 || (c >= 0x23 && c <= 0x2B) || (c >= 0x2D && c <= 0x3A) ||
57 (c >= 0x3C && c <= 0x5B) || (c >= 0x5D && c <= 0x7E);
62static size_t _cookie_scan(
const char*
h,
size_t len,
const char* name,
const char** first,
size_t* first_len) {
63 size_t i = 0, count = 0, nlen = strlen(name);
65 size_t ps, pe,
eq, ns, ne, vs, ve;
66 while (i < len && (
h[i] ==
' ' ||
h[i] ==
'\t' ||
h[i] ==
';'))
69 while (i < len &&
h[i] !=
';')
75 while (
eq < pe &&
h[
eq] !=
'=')
79 while (ne > ns && (
h[ne - 1] ==
' ' ||
h[ne - 1] ==
'\t'))
84 while (vs < ve && (
h[vs] ==
' ' ||
h[vs] ==
'\t'))
86 while (ve > vs && (
h[ve - 1] ==
' ' ||
h[ve - 1] ==
'\t'))
91 if (!
_cookie_token(
h + ns, ne - ns) || ne - ns != nlen || memcmp(
h + ns, name, nlen) != 0)
93 if (count == 0 && first) {
110const char*
n_http_cookie_get(
const char* header,
size_t len,
const char* name,
size_t* value_len) {
111 const char* v = NULL;
115 if (!header || !name || name[0] ==
'\0')
132 if (!header || !name || name[0] ==
'\0')
142 unsigned char c = (
unsigned char)*p;
143 if (c < 0x20 || c > 0x7E || c ==
';')
153 unsigned char c = (
unsigned char)*d;
154 if (!((c >=
'a' && c <=
'z') || (c >=
'A' && c <=
'Z') || (c >=
'0' && c <=
'9') || c ==
'.' || c ==
'-'))
180 for (i = 0; value[i]; i++)
182 n_log(
LOG_DEBUG,
"set-cookie: value byte 0x%02x refused", (
unsigned char)value[i]);
189 if (strncmp(c->
name,
"__Host-", 7) == 0 &&
192 if (strncmp(c->
name,
"__Secure-", 9) == 0 && !c->
secure)
204 if (!
nstrcat_bytes(tmp,
"; Max-Age=0; Expires=Thu, 01 Jan 1970 00:00:00 GMT"))
207 snprintf(buf,
sizeof(buf),
"; Max-Age=%lld", c->
max_age);
static int h(void *ctx, const N_ROUTE_MATCH *m)
a handler that does nothing (the test only routes)
static int eq(double a, double b)
#define __n_assert(__ptr, __ret)
macro to assert things
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
#define LOG_DEBUG
debug-level messages
int http_only
non-zero: HttpOnly
const char * value
cookie value, RFC 6265 cookie-octets only (may be "")
int secure
non-zero: Secure
const char * path
Path attribute, or NULL.
const char * name
cookie name, an RFC 9110 token
const char * domain
Domain attribute, or NULL (host-only cookie).
N_HTTP_SAMESITE same_site
SameSite attribute.
long long max_age
Max-Age in seconds; N_HTTP_COOKIE_SESSION for a session cookie; 0 deletes the cookie (Max-Age=0 plus ...
size_t n_http_cookie_count(const char *header, size_t len, const char *name)
count the pairs named name in a Cookie header value
int n_http_set_cookie_build(N_STR **out, const N_HTTP_SET_COOKIE *c)
append a Set-Cookie header value, refusing anything that could break out of an attribute or that a br...
#define N_HTTP_COOKIE_SESSION
Max-Age value meaning "session cookie": neither Max-Age nor Expires is sent.
const char * n_http_cookie_get(const char *header, size_t len, const char *name, size_t *value_len)
find a cookie in a Cookie header value (first occurrence wins)
@ N_HTTP_SAMESITE_NONE
SameSite=None, needs Secure.
@ N_HTTP_SAMESITE_STRICT
SameSite=Strict.
@ N_HTTP_SAMESITE_LAX
SameSite=Lax.
@ N_HTTP_SAMESITE_UNSET
no SameSite attribute (browser default)
what a Set-Cookie should carry
size_t written
number of meaningful bytes in data, excluding the null terminator; the size including the null termin...
#define free_nstr(__ptr)
free a N_STR structure and set the pointer to NULL
N_STR * nstrcat_ex(N_STR **dest, void *src, NSTRBYTE size, int resize_flag)
Append data into N_STR using internal N_STR size and cursor position.
#define nstrcat_bytes(__nstr_dst, __void_src)
Macro to quickly concatenate a '\0' ended byte stream to a N_STR.
A box including a string and his lenght.
Common headers and low-level functions & define.
static int _cookie_octet(unsigned char c)
static int _cookie_tchar(unsigned char c)
static int _cookie_domain_ok(const char *d)
static size_t _cookie_scan(const char *h, size_t len, const char *name, const char **first, size_t *first_len)
static int _cookie_path_ok(const char *p)
static int _cookie_token(const char *s, size_t n)
Server-side cookies: read a Cookie header, build a Set-Cookie value.
N_STR and string function declaration.