offsetof(ngx_http_core_loc_conf_t, client_body_in_single_buffer),
NULL },
+ { ngx_string("client_body_early_read"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_1MORE,
+ ngx_http_set_predicate_slot,
+ NGX_HTTP_SRV_CONF_OFFSET,
+ offsetof(ngx_http_core_srv_conf_t, client_body_early_read),
+ NULL },
+
{ ngx_string("sendfile"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|NGX_CONF_FLAG,
cscf->ignore_invalid_headers = NGX_CONF_UNSET;
cscf->merge_slashes = NGX_CONF_UNSET;
cscf->underscores_in_headers = NGX_CONF_UNSET;
+ cscf->client_body_early_read = NGX_CONF_UNSET_PTR;
cscf->file_name = cf->conf_file->file.name.data;
cscf->line = cf->conf_file->line;
ngx_conf_merge_value(conf->underscores_in_headers,
prev->underscores_in_headers, 0);
+ ngx_conf_merge_ptr_value(conf->client_body_early_read,
+ prev->client_body_early_read, NULL);
+
if (conf->server_names.nelts == 0) {
/* the array has 4 empty preallocated elements, so push cannot fail */
sn = ngx_array_push(&conf->server_names);
ngx_table_elt_t *h, ngx_uint_t offset);
static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r);
+static ngx_int_t ngx_http_read_early_body(ngx_http_request_t *r);
static ngx_int_t ngx_http_find_virtual_server(ngx_connection_t *c,
ngx_http_virtual_names_t *virtual_names, ngx_str_t *host,
ngx_http_request_t *r, ngx_http_core_srv_conf_t **cscfp);
c->write->handler = ngx_http_request_handler;
r->read_event_handler = ngx_http_block_reading;
+ if (ngx_http_read_early_body(r) != NGX_OK) {
+ return;
+ }
+
ngx_http_handler(r);
}
+static ngx_int_t
+ngx_http_read_early_body(ngx_http_request_t *r)
+{
+ ngx_int_t rc;
+ ngx_http_core_loc_conf_t *clcf;
+ ngx_http_core_srv_conf_t *cscf;
+
+ cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
+
+ rc = ngx_http_test_predicates(r, cscf->client_body_early_read);
+
+ if (rc == NGX_ERROR) {
+ ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+ return NGX_DONE;
+ }
+
+ if (rc == NGX_OK) {
+ return NGX_OK;
+ }
+
+ /* rc == NGX_DECLINED */
+
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "http client request body early read");
+
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+ if (r->headers_in.content_length_n != -1
+ && !r->discard_body
+ && clcf->client_max_body_size
+ && clcf->client_max_body_size < r->headers_in.content_length_n)
+ {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "client intended to send too large body: %O bytes",
+ r->headers_in.content_length_n);
+
+ r->expect_tested = 1;
+ (void) ngx_http_discard_request_body(r);
+ ngx_http_finalize_request(r, NGX_HTTP_REQUEST_ENTITY_TOO_LARGE);
+ return NGX_DONE;
+ }
+
+ rc = ngx_http_read_client_request_body(r, ngx_http_handler);
+
+ if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
+ ngx_http_finalize_request(r, rc);
+ return NGX_DONE;
+ }
+
+ ngx_http_finalize_request(r, NGX_DONE);
+
+ return NGX_DONE;
+}
+
+
ngx_int_t
ngx_http_validate_host(ngx_str_t *host, in_port_t *portp, ngx_pool_t *pool,
ngx_uint_t alloc)