Mercurial > hg > nginx
comparison src/http/v3/ngx_http_v3_request.c @ 9251:3728a0ed243a
HTTP/3: fixed handling of request body larger than Content-Length.
Previously, 413 (Request entity too large) was returned, and incorrect
"client intended to send too large body" error message was logged.
Fix is to return 400 (Bad request) and log the "client intended to send
body data larger than declared" error message, similarly to what HTTP/2
code does.
Additionally, previously "client_max_body_size 0;" was incorrectly handled
by the HTTP/3 code, resulting in 413 instead of no limit. This is also
fixed by the correct checks added.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Sat, 27 Apr 2024 18:17:03 +0300 |
parents | 07ca679842de |
children | cb1e214efe41 |
comparison
equal
deleted
inserted
replaced
9250:55a5a40dccde | 9251:3728a0ed243a |
---|---|
1480 | 1480 |
1481 | 1481 |
1482 static ngx_int_t | 1482 static ngx_int_t |
1483 ngx_http_v3_request_body_filter(ngx_http_request_t *r, ngx_chain_t *in) | 1483 ngx_http_v3_request_body_filter(ngx_http_request_t *r, ngx_chain_t *in) |
1484 { | 1484 { |
1485 off_t max; | |
1486 size_t size; | 1485 size_t size; |
1487 u_char *p; | 1486 u_char *p; |
1488 ngx_int_t rc; | 1487 ngx_int_t rc; |
1489 ngx_buf_t *b; | 1488 ngx_buf_t *b; |
1490 ngx_uint_t last; | 1489 ngx_uint_t last; |
1508 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); | 1507 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); |
1509 | 1508 |
1510 rb->rest = cscf->large_client_header_buffers.size; | 1509 rb->rest = cscf->large_client_header_buffers.size; |
1511 } | 1510 } |
1512 | 1511 |
1513 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | |
1514 | |
1515 max = r->headers_in.content_length_n; | |
1516 | |
1517 if (max == -1 && clcf->client_max_body_size) { | |
1518 max = clcf->client_max_body_size; | |
1519 } | |
1520 | |
1521 out = NULL; | 1512 out = NULL; |
1522 ll = &out; | 1513 ll = &out; |
1523 last = 0; | 1514 last = 0; |
1524 | 1515 |
1525 for (cl = in; cl; cl = cl->next) { | 1516 for (cl = in; cl; cl = cl->next) { |
1573 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 1564 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
1574 } | 1565 } |
1575 | 1566 |
1576 /* rc == NGX_OK */ | 1567 /* rc == NGX_OK */ |
1577 | 1568 |
1578 if (max != -1 && (uint64_t) (max - rb->received) < st->length) { | 1569 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
1570 | |
1571 if (clcf->client_max_body_size | |
1572 && (uint64_t) (clcf->client_max_body_size - rb->received) | |
1573 < st->length) | |
1574 { | |
1579 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | 1575 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
1580 "client intended to send too large " | 1576 "client intended to send too large " |
1581 "body: %O+%ui bytes", | 1577 "body: %O+%ui bytes", |
1582 rb->received, st->length); | 1578 rb->received, st->length); |
1583 | 1579 |
1584 return NGX_HTTP_REQUEST_ENTITY_TOO_LARGE; | 1580 return NGX_HTTP_REQUEST_ENTITY_TOO_LARGE; |
1581 } | |
1582 | |
1583 if (r->headers_in.content_length_n != -1 | |
1584 && (uint64_t) (r->headers_in.content_length_n | |
1585 - rb->received) | |
1586 < st->length) | |
1587 { | |
1588 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, | |
1589 "client intended to send body data " | |
1590 "larger than declared"); | |
1591 | |
1592 return NGX_HTTP_BAD_REQUEST; | |
1585 } | 1593 } |
1586 | 1594 |
1587 continue; | 1595 continue; |
1588 } | 1596 } |
1589 | 1597 |