mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-01 06:55:30 +00:00
Use isc_buffer_t to keep track of incoming POST data
This commit replaces the ad-hoc 64K buffer for incoming POST data with isc_buffer_t backed by dynamically allocated buffer sized accordingly to the value in the "Content-Length" header.
This commit is contained in:
@@ -536,11 +536,18 @@ on_server_data_chunk_recv_callback(int32_t stream_id, const uint8_t *data,
|
|||||||
isc_nmsocket_h2_t *h2 = ISC_LIST_HEAD(session->sstreams);
|
isc_nmsocket_h2_t *h2 = ISC_LIST_HEAD(session->sstreams);
|
||||||
while (h2 != NULL) {
|
while (h2 != NULL) {
|
||||||
if (stream_id == h2->stream_id) {
|
if (stream_id == h2->stream_id) {
|
||||||
size_t new_bufsize = h2->bufsize + len;
|
if (isc_buffer_base(&h2->rbuf) == NULL) {
|
||||||
|
isc_buffer_init(
|
||||||
|
&h2->rbuf,
|
||||||
|
isc_mem_allocate(session->mctx,
|
||||||
|
h2->content_length),
|
||||||
|
MAX_DNS_MESSAGE_SIZE);
|
||||||
|
}
|
||||||
|
size_t new_bufsize = isc_buffer_usedlength(&h2->rbuf) +
|
||||||
|
len;
|
||||||
if (new_bufsize <= MAX_DNS_MESSAGE_SIZE &&
|
if (new_bufsize <= MAX_DNS_MESSAGE_SIZE &&
|
||||||
new_bufsize <= h2->content_length) {
|
new_bufsize <= h2->content_length) {
|
||||||
memmove(h2->buf + h2->bufsize, data, len);
|
isc_buffer_putmem(&h2->rbuf, data, len);
|
||||||
h2->bufsize = new_bufsize;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1660,6 +1667,7 @@ server_on_begin_headers_callback(nghttp2_session *ngsession,
|
|||||||
.stream_id = frame->hd.stream_id,
|
.stream_id = frame->hd.stream_id,
|
||||||
.headers_error_code = ISC_HTTP_ERROR_SUCCESS
|
.headers_error_code = ISC_HTTP_ERROR_SUCCESS
|
||||||
};
|
};
|
||||||
|
isc_buffer_initnull(&socket->h2.rbuf);
|
||||||
session->nsstreams++;
|
session->nsstreams++;
|
||||||
isc__nm_httpsession_attach(session, &socket->h2.session);
|
isc__nm_httpsession_attach(session, &socket->h2.session);
|
||||||
socket->tid = session->handle->sock->tid;
|
socket->tid = session->handle->sock->tid;
|
||||||
@@ -1990,8 +1998,11 @@ static struct http_error_responses {
|
|||||||
static isc_result_t
|
static isc_result_t
|
||||||
server_send_error_response(const isc_http_error_responses_t error,
|
server_send_error_response(const isc_http_error_responses_t error,
|
||||||
nghttp2_session *ngsession, isc_nmsocket_t *socket) {
|
nghttp2_session *ngsession, isc_nmsocket_t *socket) {
|
||||||
socket->h2.bufsize = 0;
|
void *base = isc_buffer_base(&socket->h2.rbuf);
|
||||||
socket->h2.bufpos = 0;
|
if (base != NULL) {
|
||||||
|
isc_mem_free(socket->h2.session->mctx, base);
|
||||||
|
isc_buffer_initnull(&socket->h2.rbuf);
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t i = 0;
|
for (size_t i = 0;
|
||||||
i < sizeof(error_responses) / sizeof(error_responses[0]); i++)
|
i < sizeof(error_responses) / sizeof(error_responses[0]); i++)
|
||||||
@@ -2053,11 +2064,13 @@ server_on_request_recv(nghttp2_session *ngsession,
|
|||||||
if (socket->h2.request_path == NULL || socket->h2.cb == NULL) {
|
if (socket->h2.request_path == NULL || socket->h2.cb == NULL) {
|
||||||
code = ISC_HTTP_ERROR_NOT_FOUND;
|
code = ISC_HTTP_ERROR_NOT_FOUND;
|
||||||
} else if (socket->h2.request_type == ISC_HTTP_REQ_POST &&
|
} else if (socket->h2.request_type == ISC_HTTP_REQ_POST &&
|
||||||
socket->h2.bufsize > socket->h2.content_length)
|
isc_buffer_usedlength(&socket->h2.rbuf) >
|
||||||
|
socket->h2.content_length)
|
||||||
{
|
{
|
||||||
code = ISC_HTTP_ERROR_PAYLOAD_TOO_LARGE;
|
code = ISC_HTTP_ERROR_PAYLOAD_TOO_LARGE;
|
||||||
} else if (socket->h2.request_type == ISC_HTTP_REQ_POST &&
|
} else if (socket->h2.request_type == ISC_HTTP_REQ_POST &&
|
||||||
socket->h2.bufsize != socket->h2.content_length)
|
isc_buffer_usedlength(&socket->h2.rbuf) !=
|
||||||
|
socket->h2.content_length)
|
||||||
{
|
{
|
||||||
code = ISC_HTTP_ERROR_BAD_REQUEST;
|
code = ISC_HTTP_ERROR_BAD_REQUEST;
|
||||||
}
|
}
|
||||||
@@ -2079,7 +2092,7 @@ server_on_request_recv(nghttp2_session *ngsession,
|
|||||||
isc__buffer_usedregion(&decoded_buf, &data);
|
isc__buffer_usedregion(&decoded_buf, &data);
|
||||||
} else if (socket->h2.request_type == ISC_HTTP_REQ_POST) {
|
} else if (socket->h2.request_type == ISC_HTTP_REQ_POST) {
|
||||||
INSIST(socket->h2.content_length > 0);
|
INSIST(socket->h2.content_length > 0);
|
||||||
data = (isc_region_t){ socket->h2.buf, socket->h2.bufsize };
|
isc_buffer_usedregion(&socket->h2.rbuf, &data);
|
||||||
} else {
|
} else {
|
||||||
INSIST(0);
|
INSIST(0);
|
||||||
ISC_UNREACHABLE();
|
ISC_UNREACHABLE();
|
||||||
@@ -2734,6 +2747,7 @@ isc__nm_async_httpclose(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||||||
static void
|
static void
|
||||||
failed_httpstream_read_cb(isc_nmsocket_t *sock, isc_result_t result,
|
failed_httpstream_read_cb(isc_nmsocket_t *sock, isc_result_t result,
|
||||||
isc_nm_http_session_t *session) {
|
isc_nm_http_session_t *session) {
|
||||||
|
isc_region_t data;
|
||||||
REQUIRE(VALID_NMSOCK(sock));
|
REQUIRE(VALID_NMSOCK(sock));
|
||||||
INSIST(sock->type == isc_nm_httpsocket);
|
INSIST(sock->type == isc_nm_httpsocket);
|
||||||
|
|
||||||
@@ -2746,8 +2760,8 @@ failed_httpstream_read_cb(isc_nmsocket_t *sock, isc_result_t result,
|
|||||||
(void)nghttp2_submit_rst_stream(
|
(void)nghttp2_submit_rst_stream(
|
||||||
session->ngsession, NGHTTP2_FLAG_END_STREAM, sock->h2.stream_id,
|
session->ngsession, NGHTTP2_FLAG_END_STREAM, sock->h2.stream_id,
|
||||||
NGHTTP2_REFUSED_STREAM);
|
NGHTTP2_REFUSED_STREAM);
|
||||||
server_call_cb(sock, session, result,
|
isc_buffer_usedregion(&sock->h2.rbuf, &data);
|
||||||
&(isc_region_t){ sock->h2.buf, sock->h2.bufsize });
|
server_call_cb(sock, session, result, &data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -3015,6 +3029,12 @@ isc__nm_http_cleanup_data(isc_nmsocket_t *sock) {
|
|||||||
isc_mem_free(sock->mgr->mctx, sock->h2.buf);
|
isc_mem_free(sock->mgr->mctx, sock->h2.buf);
|
||||||
sock->h2.buf = NULL;
|
sock->h2.buf = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isc_buffer_base(&sock->h2.rbuf) != NULL) {
|
||||||
|
void *base = isc_buffer_base(&sock->h2.rbuf);
|
||||||
|
isc_mem_free(sock->mgr->mctx, base);
|
||||||
|
isc_buffer_initnull(&sock->h2.rbuf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((sock->type == isc_nm_httplistener ||
|
if ((sock->type == isc_nm_httplistener ||
|
||||||
|
@@ -803,6 +803,7 @@ typedef struct isc_nmsocket_h2 {
|
|||||||
uint8_t *buf;
|
uint8_t *buf;
|
||||||
size_t bufsize;
|
size_t bufsize;
|
||||||
size_t bufpos;
|
size_t bufpos;
|
||||||
|
isc_buffer_t rbuf;
|
||||||
|
|
||||||
int32_t stream_id;
|
int32_t stream_id;
|
||||||
isc_nm_http_session_t *session;
|
isc_nm_http_session_t *session;
|
||||||
|
Reference in New Issue
Block a user