diff --git a/src/http/ngx_http_header_filter_module.c b/src/http/ngx_http_header_filter_module.c index 1e01c857d..e3efbba5b 100644 --- a/src/http/ngx_http_header_filter_module.c +++ b/src/http/ngx_http_header_filter_module.c @@ -112,7 +112,7 @@ static ngx_str_t ngx_http_status_lines[] = { #define NGX_HTTP_OFF_5XX (NGX_HTTP_LAST_4XX - 400 + NGX_HTTP_OFF_4XX) ngx_string("500 Internal Server Error"), - ngx_string("501 Method Not Implemented"), + ngx_string("501 Not Implemented"), ngx_string("502 Bad Gateway"), ngx_string("503 Service Temporarily Unavailable"), ngx_string("504 Gateway Time-out"), diff --git a/src/http/ngx_http_request_body.c b/src/http/ngx_http_request_body.c index bddd7c580..3c69d052c 100644 --- a/src/http/ngx_http_request_body.c +++ b/src/http/ngx_http_request_body.c @@ -31,9 +31,9 @@ ngx_http_read_client_request_body(ngx_http_request_t *r, { size_t preread; ssize_t size; + ngx_int_t rc; ngx_buf_t *b; ngx_chain_t *cl, **next; - ngx_temp_file_t *tf; ngx_http_request_body_t *rb; ngx_http_core_loc_conf_t *clcf; @@ -45,12 +45,14 @@ ngx_http_read_client_request_body(ngx_http_request_t *r, } if (ngx_http_test_expect(r) != NGX_OK) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; + rc = NGX_HTTP_INTERNAL_SERVER_ERROR; + goto done; } rb = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t)); if (rb == NULL) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; + rc = NGX_HTTP_INTERNAL_SERVER_ERROR; + goto done; } r->request_body = rb; @@ -65,31 +67,9 @@ ngx_http_read_client_request_body(ngx_http_request_t *r, if (r->headers_in.content_length_n == 0) { if (r->request_body_in_file_only) { - tf = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t)); - if (tf == NULL) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; - } - - tf->file.fd = NGX_INVALID_FILE; - tf->file.log = r->connection->log; - tf->path = clcf->client_body_temp_path; - tf->pool = r->pool; - tf->warn = "a client request body is buffered to a temporary file"; - tf->log_level = r->request_body_file_log_level; - tf->persistent = r->request_body_in_persistent_file; - tf->clean = r->request_body_in_clean_file; - - if (r->request_body_file_group_access) { - tf->access = 0660; - } - - rb->temp_file = tf; - - if (ngx_create_temp_file(&tf->file, tf->path, tf->pool, - tf->persistent, tf->clean, tf->access) - != NGX_OK) - { - return NGX_HTTP_INTERNAL_SERVER_ERROR; + if (ngx_http_write_request_body(r, NULL) != NGX_OK) { + rc = NGX_HTTP_INTERNAL_SERVER_ERROR; + goto done; } } @@ -119,7 +99,8 @@ ngx_http_read_client_request_body(ngx_http_request_t *r, b = ngx_calloc_buf(r->pool); if (b == NULL) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; + rc = NGX_HTTP_INTERNAL_SERVER_ERROR; + goto done; } b->temporary = 1; @@ -130,7 +111,8 @@ ngx_http_read_client_request_body(ngx_http_request_t *r, rb->bufs = ngx_alloc_chain_link(r->pool); if (rb->bufs == NULL) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; + rc = NGX_HTTP_INTERNAL_SERVER_ERROR; + goto done; } rb->bufs->buf = b; @@ -148,7 +130,8 @@ ngx_http_read_client_request_body(ngx_http_request_t *r, if (r->request_body_in_file_only) { if (ngx_http_write_request_body(r, rb->bufs) != NGX_OK) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; + rc = NGX_HTTP_INTERNAL_SERVER_ERROR; + goto done; } } @@ -175,7 +158,8 @@ ngx_http_read_client_request_body(ngx_http_request_t *r, r->read_event_handler = ngx_http_read_client_request_body_handler; - return ngx_http_do_read_client_request_body(r); + rc = ngx_http_do_read_client_request_body(r); + goto done; } next = &rb->bufs->next; @@ -205,12 +189,14 @@ ngx_http_read_client_request_body(ngx_http_request_t *r, rb->buf = ngx_create_temp_buf(r->pool, size); if (rb->buf == NULL) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; + rc = NGX_HTTP_INTERNAL_SERVER_ERROR; + goto done; } cl = ngx_alloc_chain_link(r->pool); if (cl == NULL) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; + rc = NGX_HTTP_INTERNAL_SERVER_ERROR; + goto done; } cl->buf = rb->buf; @@ -235,7 +221,15 @@ ngx_http_read_client_request_body(ngx_http_request_t *r, r->read_event_handler = ngx_http_read_client_request_body_handler; - return ngx_http_do_read_client_request_body(r); + rc = ngx_http_do_read_client_request_body(r); + +done: + + if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { + r->main->count--; + } + + return rc; } @@ -419,6 +413,19 @@ ngx_http_write_request_body(ngx_http_request_t *r, ngx_chain_t *body) } rb->temp_file = tf; + + if (body == NULL) { + /* empty body with r->request_body_in_file_only */ + + if (ngx_create_temp_file(&tf->file, tf->path, tf->pool, + tf->persistent, tf->clean, tf->access) + != NGX_OK) + { + return NGX_ERROR; + } + + return NGX_OK; + } } n = ngx_write_chain_to_temp_file(rb->temp_file, body); @@ -475,19 +482,21 @@ ngx_http_discard_request_body(ngx_http_request_t *r) } } + if (ngx_http_read_discarded_request_body(r) == NGX_OK) { + r->lingering_close = 0; + return NGX_OK; + } + + /* == NGX_AGAIN */ + r->read_event_handler = ngx_http_discarded_request_body_handler; if (ngx_handle_read_event(rev, 0) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } - if (ngx_http_read_discarded_request_body(r) == NGX_OK) { - r->lingering_close = 0; - - } else { - r->count++; - r->discard_body = 1; - } + r->count++; + r->discard_body = 1; return NGX_OK; } diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c index 77b3dd13f..be495f909 100644 --- a/src/http/ngx_http_special_response.c +++ b/src/http/ngx_http_special_response.c @@ -260,9 +260,9 @@ static char ngx_http_error_500_page[] = static char ngx_http_error_501_page[] = "" CRLF -"501 Method Not Implemented" CRLF +"501 Not Implemented" CRLF "" CRLF -"

501 Method Not Implemented

" CRLF +"

501 Not Implemented

" CRLF ; @@ -384,6 +384,7 @@ ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error) case NGX_HTTPS_CERT_ERROR: case NGX_HTTPS_NO_CERT: case NGX_HTTP_INTERNAL_SERVER_ERROR: + case NGX_HTTP_NOT_IMPLEMENTED: r->keepalive = 0; } } diff --git a/src/http/ngx_http_variables.c b/src/http/ngx_http_variables.c index 457476842..298064a81 100644 --- a/src/http/ngx_http_variables.c +++ b/src/http/ngx_http_variables.c @@ -1767,7 +1767,7 @@ ngx_http_variable_request_body(ngx_http_request_t *r, { u_char *p; size_t len; - ngx_buf_t *buf, *next; + ngx_buf_t *buf; ngx_chain_t *cl; if (r->request_body == NULL @@ -1792,8 +1792,13 @@ ngx_http_variable_request_body(ngx_http_request_t *r, return NGX_OK; } - next = cl->next->buf; - len = (buf->last - buf->pos) + (next->last - next->pos); + len = buf->last - buf->pos; + cl = cl->next; + + for ( /* void */ ; cl; cl = cl->next) { + buf = cl->buf; + len += buf->last - buf->pos; + } p = ngx_pnalloc(r->pool, len); if (p == NULL) { @@ -1801,9 +1806,12 @@ ngx_http_variable_request_body(ngx_http_request_t *r, } v->data = p; + cl = r->request_body->bufs; - p = ngx_cpymem(p, buf->pos, buf->last - buf->pos); - ngx_memcpy(p, next->pos, next->last - next->pos); + for ( /* void */ ; cl; cl = cl->next) { + buf = cl->buf; + p = ngx_cpymem(p, buf->pos, buf->last - buf->pos); + } v->len = len; v->valid = 1;