summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/http/ngx_http_parse.c5
-rw-r--r--src/http/ngx_http_request_body.c30
-rw-r--r--src/http/v3/ngx_http_v3_request.c24
3 files changed, 35 insertions, 24 deletions
diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c
index a351f2b27..2015f56b2 100644
--- a/src/http/ngx_http_parse.c
+++ b/src/http/ngx_http_parse.c
@@ -2377,11 +2377,6 @@ ngx_http_parse_chunked(ngx_http_request_t *r, ngx_buf_t *b,
}
}
- if (b->last_buf) {
- /* XXX client prematurely closed connection */
- return NGX_ERROR;
- }
-
data:
ctx->state = state;
diff --git a/src/http/ngx_http_request_body.c b/src/http/ngx_http_request_body.c
index 7a9bbdd5d..a6dbcf502 100644
--- a/src/http/ngx_http_request_body.c
+++ b/src/http/ngx_http_request_body.c
@@ -960,6 +960,15 @@ ngx_http_request_body_length_filter(ngx_http_request_t *r, ngx_chain_t *in)
break;
}
+ size = cl->buf->last - cl->buf->pos;
+
+ if (cl->buf->last_buf && (off_t) size < rb->rest) {
+ ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+ "client prematurely closed connection");
+ r->connection->error = 1;
+ return NGX_HTTP_BAD_REQUEST;
+ }
+
tl = ngx_chain_get_free_buf(r->pool, &rb->free);
if (tl == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
@@ -977,8 +986,6 @@ ngx_http_request_body_length_filter(ngx_http_request_t *r, ngx_chain_t *in)
b->end = cl->buf->end;
b->flush = r->request_body_no_buffering;
- size = cl->buf->last - cl->buf->pos;
-
if ((off_t) size < rb->rest) {
cl->buf->pos = cl->buf->last;
rb->rest -= size;
@@ -990,11 +997,6 @@ ngx_http_request_body_length_filter(ngx_http_request_t *r, ngx_chain_t *in)
b->last_buf = 1;
}
- if (cl->buf->last_buf && rb->rest > 0) {
- /* XXX client prematurely closed connection */
- return NGX_ERROR;
- }
-
*ll = tl;
ll = &tl->next;
}
@@ -1148,6 +1150,20 @@ ngx_http_request_body_chunked_filter(ngx_http_request_t *r, ngx_chain_t *in)
continue;
}
+ if (rc == NGX_AGAIN && cl->buf->last_buf) {
+
+ /* last body buffer */
+
+ if (rb->chunked->length > 0) {
+ ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+ "client prematurely closed connection");
+ r->connection->error = 1;
+ return NGX_HTTP_BAD_REQUEST;
+ }
+
+ rc = NGX_DONE;
+ }
+
if (rc == NGX_DONE) {
/* a whole response has been parsed successfully */
diff --git a/src/http/v3/ngx_http_v3_request.c b/src/http/v3/ngx_http_v3_request.c
index 24ad771d6..fe3c79bf0 100644
--- a/src/http/v3/ngx_http_v3_request.c
+++ b/src/http/v3/ngx_http_v3_request.c
@@ -379,6 +379,10 @@ ngx_http_v3_parse_request_body(ngx_http_request_t *r, ngx_buf_t *b,
ngx_int_t rc;
ngx_connection_t *c;
ngx_http_v3_parse_data_t *st;
+ enum {
+ sw_start = 0,
+ sw_skip
+ };
c = r->connection;
st = ctx->h3_parse;
@@ -395,12 +399,8 @@ ngx_http_v3_parse_request_body(ngx_http_request_t *r, ngx_buf_t *b,
ctx->h3_parse = st;
}
- if (ctx->size) {
- ctx->length = ctx->size + 1;
- return (b->pos == b->last) ? NGX_AGAIN : NGX_OK;
- }
+ while (b->pos < b->last && ctx->size == 0) {
- while (b->pos < b->last) {
rc = ngx_http_v3_parse_data(c, st, *b->pos++);
if (rc > 0) {
@@ -414,27 +414,27 @@ ngx_http_v3_parse_request_body(ngx_http_request_t *r, ngx_buf_t *b,
}
if (rc == NGX_AGAIN) {
+ ctx->state = sw_skip;
continue;
}
/* rc == NGX_DONE */
ctx->size = st->length;
- return NGX_OK;
+ ctx->state = sw_start;
}
- if (!b->last_buf) {
+ if (ctx->state == sw_skip) {
ctx->length = 1;
return NGX_AGAIN;
}
- if (st->state) {
- goto failed;
+ if (b->pos == b->last) {
+ ctx->length = ctx->size;
+ return NGX_AGAIN;
}
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse header done");
-
- return NGX_DONE;
+ return NGX_OK;
failed: