[nginx] svn commit: r5102 - trunk/src/http
vbart at nginx.com
vbart at nginx.com
Thu Mar 7 17:21:51 UTC 2013
Author: vbart
Date: 2013-03-07 17:21:50 +0000 (Thu, 07 Mar 2013)
New Revision: 5102
URL: http://trac.nginx.org/nginx/changeset/5102/nginx
Log:
Create request object only after the first byte was received.
Previously, we always created an object and logged 400 (Bad Request)
in access log if a client closed connection without sending any data.
Such a connection was counted as "reading".
Since it's common for modern browsers to behave like this, it's no
longer considered an error if a client closes connection without
sending any data, and such a connection will be counted as "waiting".
Now, we do not log 400 (Bad Request) and keep memory footprint as
small as possible.
Modified:
trunk/src/http/ngx_http_request.c
Modified: trunk/src/http/ngx_http_request.c
===================================================================
--- trunk/src/http/ngx_http_request.c 2013-03-07 17:07:04 UTC (rev 5101)
+++ trunk/src/http/ngx_http_request.c 2013-03-07 17:21:50 UTC (rev 5102)
@@ -10,6 +10,7 @@
#include <ngx_http.h>
+static void ngx_http_wait_request_handler(ngx_event_t *ev);
static void ngx_http_init_request(ngx_event_t *ev);
static void ngx_http_process_request_line(ngx_event_t *rev);
static void ngx_http_process_request_headers(ngx_event_t *rev);
@@ -308,12 +309,12 @@
c->log->connection = c->number;
c->log->handler = ngx_http_log_error;
c->log->data = ctx;
- c->log->action = "reading client request line";
+ c->log->action = "waiting for request";
c->log_error = NGX_ERROR_INFO;
rev = c->read;
- rev->handler = ngx_http_init_request;
+ rev->handler = ngx_http_wait_request_handler;
c->write->handler = ngx_http_empty_handler;
#if (NGX_HTTP_SSL)
@@ -363,6 +364,99 @@
static void
+ngx_http_wait_request_handler(ngx_event_t *rev)
+{
+ size_t size;
+ ssize_t n;
+ ngx_buf_t *b;
+ ngx_connection_t *c;
+ ngx_http_connection_t *hc;
+ ngx_http_core_srv_conf_t *cscf;
+
+ c = rev->data;
+
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http wait request handler");
+
+ if (rev->timedout) {
+ ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
+ ngx_http_close_connection(c);
+ return;
+ }
+
+ hc = c->data;
+ cscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_core_module);
+
+ size = cscf->client_header_buffer_size;
+
+ b = c->buffer;
+
+ if (b == NULL) {
+ b = ngx_create_temp_buf(c->pool, size);
+ if (b == NULL) {
+ ngx_http_close_connection(c);
+ return;
+ }
+
+ c->buffer = b;
+
+ } else if (b->start == NULL) {
+
+ b->start = ngx_palloc(c->pool, size);
+ if (b->start == NULL) {
+ ngx_http_close_connection(c);
+ return;
+ }
+
+ b->pos = b->start;
+ b->last = b->start;
+ b->end = b->last + size;
+ }
+
+ n = c->recv(c, b->last, size);
+
+ if (n == NGX_AGAIN) {
+
+ if (!rev->timer_set) {
+ ngx_add_timer(rev, c->listening->post_accept_timeout);
+ }
+
+ if (ngx_handle_read_event(rev, 0) != NGX_OK) {
+ ngx_http_close_connection(c);
+ return;
+ }
+
+ /*
+ * We are trying to not hold c->buffer's memory for an idle connection.
+ */
+
+ if (ngx_pfree(c->pool, b->start) == NGX_OK) {
+ b->start = NULL;
+ }
+
+ return;
+ }
+
+ if (n == NGX_ERROR) {
+ ngx_http_close_connection(c);
+ return;
+ }
+
+ if (n == 0) {
+ ngx_log_error(NGX_LOG_INFO, c->log, ngx_socket_errno,
+ "client closed connection");
+ ngx_http_close_connection(c);
+ return;
+ }
+
+ b->last += n;
+
+ c->log->action = "reading client request line";
+
+ ngx_http_init_request(rev);
+}
+
+
+static void
ngx_http_init_request(ngx_event_t *rev)
{
ngx_pool_t *pool;
@@ -377,13 +471,6 @@
c = rev->data;
- if (rev->timedout) {
- ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
-
- ngx_http_close_connection(c);
- return;
- }
-
c->requests++;
hc = c->data;
@@ -425,16 +512,6 @@
ngx_http_set_connection_log(r->connection, clcf->error_log);
- if (c->buffer == NULL) {
- c->buffer = ngx_create_temp_buf(c->pool,
- cscf->client_header_buffer_size);
- if (c->buffer == NULL) {
- ngx_destroy_pool(r->pool);
- ngx_http_close_connection(c);
- return;
- }
- }
-
r->header_in = hc->nbusy ? hc->busy[0] : c->buffer;
if (ngx_list_init(&r->headers_out.headers, r->pool, 20,
@@ -592,10 +669,10 @@
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "plain http");
- c->log->action = "reading client request line";
+ c->log->action = "waiting for request";
- rev->handler = ngx_http_init_request;
- ngx_http_init_request(rev);
+ rev->handler = ngx_http_wait_request_handler;
+ ngx_http_wait_request_handler(rev);
return;
}
@@ -620,12 +697,12 @@
c->ssl->no_wait_shutdown = 1;
- c->log->action = "reading client request line";
+ c->log->action = "waiting for request";
- c->read->handler = ngx_http_init_request;
+ c->read->handler = ngx_http_wait_request_handler;
/* STUB: epoll edge */ c->write->handler = ngx_http_empty_handler;
- ngx_http_init_request(c->read);
+ ngx_http_wait_request_handler(c->read);
return;
}
More information about the nginx-devel
mailing list