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