diff --git a/doc/man7/libweb_handler.7 b/doc/man7/libweb_handler.7 index f975444..bf47567 100644 --- a/doc/man7/libweb_handler.7 +++ b/doc/man7/libweb_handler.7 @@ -76,6 +76,7 @@ struct handler_cfg int (*\fIlength\fP)(unsigned long long len, const struct http_cookie *c, struct http_response *r, void *user); void *\fIuser\fP; size_t \fImax_headers\fP; + struct http_cfg_post \fIpost\fP; }; .EE .in @@ -83,9 +84,10 @@ struct handler_cfg .IR tmpdir , .IR length , -.I user -and +.IR user , .I max_headers +and +.I post are passed directly to the .I struct http_cfg object used to initialize a diff --git a/doc/man7/libweb_http.7 b/doc/man7/libweb_http.7 index 0beb686..de627cb 100644 --- a/doc/man7/libweb_http.7 +++ b/doc/man7/libweb_http.7 @@ -94,6 +94,11 @@ struct http_cfg const char *\fItmpdir\fP; void *\fIuser\fP; size_t \fImax_headers\fP; + + struct http_cfg_post + { + size_t \fImax_pairs\fP, \fImax_files\fP; + } \fIpost\fP; }; .EE .in @@ -221,6 +226,31 @@ Any extra headers sent by the client outside this maximum value shall be silently ignored by .IR libweb . +.I post +contains configuration parameters specific to +.B POST +requests: + +.I max_pairs +refers to the maximum number of key/value pairs that shall be accepted by +.I libweb +on +.B POST +.IR multipart/form-data -encoded +requests. If the maximum number of pairs is exceeded by the request, +.I libweb +shall terminate the connection. + +.I max_files +refers to the maximum number of files that shall be accepted by +.I libweb +on +.B POST +.IR multipart/form-data -encoded +requests. If the maximum number of files is exceeded by the request, +.I libweb +shall terminate the connection. + .SS HTTP payload When a client submits a request to the server, diff --git a/handler.c b/handler.c index f400f2b..3d806e6 100644 --- a/handler.c +++ b/handler.c @@ -110,7 +110,8 @@ static struct client *find_or_alloc_client(struct handler *const h, .length = on_length, .user = ret, .tmpdir = h->cfg.tmpdir, - .max_headers = h->cfg.max_headers + .max_headers = h->cfg.max_headers, + .post = h->cfg.post }; *ret = (const struct client) diff --git a/http.c b/http.c index 478541e..19a1b93 100644 --- a/http.c +++ b/http.c @@ -1728,7 +1728,16 @@ static int apply_from_file(struct http_ctx *const h, struct form *const f) m->f = NULL; + const struct http_cfg_post *const cfg = &h->cfg.post; const size_t n = m->nfiles + 1; + + if (n > cfg->max_files) + { + fprintf(stderr, "%s: exceeded maximum number of files (%zu)\n", + __func__, cfg->max_files); + return 1; + } + struct http_post_file *const files = realloc(m->files, n * sizeof *m->files); @@ -1777,10 +1786,17 @@ static int apply_from_mem(struct http_ctx *const h, struct form *const f) if (name_exists(m, f)) return 1; + const struct http_cfg_post *const cfg = &h->cfg.post; struct http_post_pair *pairs, *p; const size_t n = m->npairs + 1; - if (!(f->value = strndup(h->line, m->written))) + if (n > cfg->max_pairs) + { + fprintf(stderr, "%s: exceeded maximum number of pairs (%zu)\n", + __func__, cfg->max_pairs); + return 1; + } + else if (!(f->value = strndup(h->line, m->written))) { fprintf(stderr, "%s: strndup(3): %s\n", __func__, strerror(errno)); return -1; diff --git a/include/libweb/handler.h b/include/libweb/handler.h index 493e24c..72ef1e0 100644 --- a/include/libweb/handler.h +++ b/include/libweb/handler.h @@ -14,6 +14,7 @@ struct handler_cfg struct http_response *r, void *user); void *user; size_t max_headers; + struct http_cfg_post post; }; struct handler *handler_alloc(const struct handler_cfg *cfg); diff --git a/include/libweb/http.h b/include/libweb/http.h index 7af66b5..4e80570 100644 --- a/include/libweb/http.h +++ b/include/libweb/http.h @@ -106,6 +106,11 @@ struct http_cfg const char *tmpdir; void *user; size_t max_headers; + + struct http_cfg_post + { + size_t max_pairs, max_files; + } post; }; struct http_ctx *http_alloc(const struct http_cfg *cfg);