aboutsummaryrefslogtreecommitdiff
path: root/src/supplemental/http/http_msg.c
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2025-01-11 13:29:23 -0800
committerGarrett D'Amore <garrett@damore.org>2025-01-11 13:29:23 -0800
commitb16e6ebf05429cb4ac29b3a5a5c9758fa362c78a (patch)
tree9f0c21017de2fd17b0c8f2c9a9621d78849861bf /src/supplemental/http/http_msg.c
parent588611e180f2e47caa778a6265b1d7f73b90648a (diff)
downloadnng-b16e6ebf05429cb4ac29b3a5a5c9758fa362c78a.tar.gz
nng-b16e6ebf05429cb4ac29b3a5a5c9758fa362c78a.tar.bz2
nng-b16e6ebf05429cb4ac29b3a5a5c9758fa362c78a.zip
http: improve buffer reuse for heeaders, and discard unused bodies
The body content not being consumed was leading to misparses, where we consumed body data as if it were a request. When mixed with proxies this could lead to a security problem where the following request content submitted from a different client winds up as stolen request body content. This also ensures we actually deliver errors to clients without prematurely closing the connection. (There are still problems where the connection may be closed prematurely for an overlarge header.)
Diffstat (limited to 'src/supplemental/http/http_msg.c')
-rw-r--r--src/supplemental/http/http_msg.c128
1 files changed, 0 insertions, 128 deletions
diff --git a/src/supplemental/http/http_msg.c b/src/supplemental/http/http_msg.c
index fbe73e4c..5cc71b7d 100644
--- a/src/supplemental/http/http_msg.c
+++ b/src/supplemental/http/http_msg.c
@@ -66,11 +66,6 @@ void
nni_http_req_reset(nni_http_req *req)
{
http_entity_reset(&req->data);
- if (req->uri != req->ubuf) {
- nni_strfree(req->uri);
- }
- req->uri = NULL;
- (void) snprintf(req->meth, sizeof(req->meth), "GET");
}
void
@@ -78,7 +73,6 @@ nni_http_res_reset(nni_http_res *res)
{
http_entity_reset(&res->data);
nni_strfree(res->rsn);
- res->vers = NNG_HTTP_VERSION_1_1;
res->rsn = NULL;
res->code = 0;
}
@@ -169,125 +163,6 @@ http_parse_header(nng_http *conn, void *line)
return (nni_http_add_header(conn, key, val));
}
-// http_sprintf_headers makes headers for an HTTP request or an HTTP response
-// object. Each header is dumped from the list. If the buf is NULL,
-// or the sz is 0, then a dryrun is done, in order to allow the caller to
-// determine how much space is needed. Returns the size of the space needed,
-// not including the terminating NULL byte. Truncation occurs if the size
-// returned is >= the requested size.
-static size_t
-http_sprintf_headers(char *buf, size_t sz, nni_list *list)
-{
- size_t rv = 0;
- http_header *h;
-
- if (buf == NULL) {
- sz = 0;
- }
-
- NNI_LIST_FOREACH (list, h) {
- size_t l;
- l = snprintf(buf, sz, "%s: %s\r\n", h->name, h->value);
- if (buf != NULL) {
- buf += l;
- }
- sz = (sz > l) ? sz - l : 0;
- rv += l;
- }
- return (rv);
-}
-
-static int
-http_asprintf(char **bufp, size_t *szp, nni_list *hdrs, const char *fmt, ...)
-{
- va_list ap;
- size_t len;
- size_t n;
- char *buf;
-
- va_start(ap, fmt);
- len = vsnprintf(NULL, 0, fmt, ap);
- va_end(ap);
-
- len += http_sprintf_headers(NULL, 0, hdrs);
- len += 3; // \r\n\0
-
- if (len <= *szp) {
- buf = *bufp;
- } else {
- if ((buf = nni_alloc(len)) == NULL) {
- return (NNG_ENOMEM);
- }
- nni_free(*bufp, *szp);
- *bufp = buf;
- *szp = len;
- }
- va_start(ap, fmt);
- n = vsnprintf(buf, len, fmt, ap);
- va_end(ap);
- buf += n;
- len -= n;
- n = http_sprintf_headers(buf, len, hdrs);
- buf += n;
- len -= n;
- snprintf(buf, len, "\r\n");
- NNI_ASSERT(len == 3);
- return (0);
-}
-
-static int
-http_req_prepare(nni_http_req *req)
-{
- int rv;
- if (req->uri == NULL) {
- return (NNG_EINVAL);
- }
- rv = http_asprintf(&req->data.buf, &req->data.bufsz, &req->data.hdrs,
- "%s %s %s\r\n", req->meth, req->uri, req->vers);
- return (rv);
-}
-
-static int
-http_res_prepare(nng_http *conn)
-{
- int rv;
- nng_http_res *res = nni_http_conn_res(conn);
-
- if (res->code == 0) {
- res->code = NNG_HTTP_STATUS_OK;
- }
- rv = http_asprintf(&res->data.buf, &res->data.bufsz, &res->data.hdrs,
- "%s %d %s\r\n", res->vers, res->code, nni_http_get_reason(conn));
- return (rv);
-}
-
-int
-nni_http_req_get_buf(nni_http_req *req, void **data, size_t *szp)
-{
- int rv;
-
- if ((req->data.buf == NULL) && (rv = http_req_prepare(req)) != 0) {
- return (rv);
- }
- *data = req->data.buf;
- *szp = req->data.bufsz - 1; // exclude terminating NUL
- return (0);
-}
-
-int
-nni_http_res_get_buf(nng_http *conn, void **data, size_t *szp)
-{
- int rv;
- nni_http_res *res = nni_http_conn_res(conn);
-
- if ((res->data.buf == NULL) && (rv = http_res_prepare(conn)) != 0) {
- return (rv);
- }
- *data = res->data.buf;
- *szp = res->data.bufsz - 1; // exclude terminating NUL
- return (0);
-}
-
void
nni_http_req_init(nni_http_req *req)
{
@@ -297,8 +172,6 @@ nni_http_req_init(nni_http_req *req)
req->data.data = NULL;
req->data.size = 0;
req->data.own = false;
- req->uri = NULL;
- (void) snprintf(req->meth, sizeof(req->meth), "GET");
}
void
@@ -310,7 +183,6 @@ nni_http_res_init(nni_http_res *res)
res->data.data = NULL;
res->data.size = 0;
res->data.own = false;
- res->vers = NNG_HTTP_VERSION_1_1;
res->rsn = NULL;
res->code = 0;
}