diff src/http/ngx_http_request.c @ 324:7cf404023f50 NGINX_0_5_32

nginx 0.5.32 *) Change: now nginx tries to set the "worker_priority", "worker_rlimit_nofile", "worker_rlimit_core", and "worker_rlimit_sigpending" without super-user privileges. *) Change: now nginx escapes space and "%" in request to a mail proxy authentication server. *) Change: now nginx escapes "%" in $memcached_key variable. *) Change: the special make target "upgrade1" was defined for online upgrade of 0.1.x versions. *) Feature: the "add_header Last-Modified ..." directive changes the "Last-Modified" response header line. *) Feature: the mail proxy supports AUTHENTICATE in IMAP mode. Thanks to Maxim Dounin. *) Feature: the mail proxy supports STARTTLS in SMTP mode. Thanks to Maxim Dounin. *) Bugfix: nginx did not close directory file on HEAD request if autoindex was used. Thanks to Arkadiusz Patyk. *) Bugfix: the "proxy_hide_header" and "fastcgi_hide_header" directives did not hide response header lines whose name was longer than 32 characters. Thanks to Manlio Perillo. *) Bugfix: active connection counter always increased if mail proxy was used. *) Bugfix: if backend returned response header only using non-buffered proxy, then nginx closed backend connection on timeout. *) Bugfix: nginx did not support several "Connection" request header lines. *) Bugfix: a charset set by the "charset" directive was not appended to the "Content-Type" header set by $r->send_http_header(). *) Bugfix: a segmentation fault might occur in worker process if /dev/poll method was used. *) Bugfix: nginx did not work on FreeBSD/sparc64. *) Bugfix: a segmentation fault occurred in worker process if invalid address was set in the "auth_http" directive. *) Bugfix: now nginx uses default listen backlog value 511 on all platforms except FreeBSD. Thanks to Jiang Hong. *) Bugfix: now Solaris sendfilev() is not used to transfer the client request body to FastCGI-server via the unix domain socket. *) Bugfix: if the same host without specified port was used as backend for HTTP and HTTPS, then nginx used only one port - 80 or 443. *) Bugfix: the "proxy_ignore_client_abort" and "fastcgi_ignore_client_abort" directives did not work; bug appeared in 0.5.13.
author Igor Sysoev <http://sysoev.ru>
date Mon, 24 Sep 2007 00:00:00 +0400
parents 94e16de3c33f
children f70f2f565fe0
line wrap: on
line diff
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -21,6 +21,8 @@ static ngx_int_t ngx_http_process_header
     ngx_table_elt_t *h, ngx_uint_t offset);
 static ngx_int_t ngx_http_process_unique_header_line(ngx_http_request_t *r,
     ngx_table_elt_t *h, ngx_uint_t offset);
+static ngx_int_t ngx_http_process_connection(ngx_http_request_t *r,
+    ngx_table_elt_t *h, ngx_uint_t offset);
 static ngx_int_t ngx_http_process_cookie(ngx_http_request_t *r,
     ngx_table_elt_t *h, ngx_uint_t offset);
 
@@ -34,6 +36,7 @@ static ngx_int_t ngx_http_set_write_hand
 static void ngx_http_writer(ngx_http_request_t *r);
 
 static void ngx_http_block_read(ngx_http_request_t *r);
+static void ngx_http_test_read(ngx_http_request_t *r);
 static void ngx_http_set_keepalive(ngx_http_request_t *r);
 static void ngx_http_keepalive_handler(ngx_event_t *ev);
 static void ngx_http_set_lingering_close(ngx_http_request_t *r);
@@ -71,11 +74,11 @@ ngx_http_header_t  ngx_http_headers_in[]
                  ngx_http_process_unique_header_line },
 
     { ngx_string("Connection"), offsetof(ngx_http_headers_in_t, connection),
-                 ngx_http_process_unique_header_line },
+                 ngx_http_process_connection },
 
     { ngx_string("If-Modified-Since"),
                  offsetof(ngx_http_headers_in_t, if_modified_since),
-                 ngx_http_process_header_line },
+                 ngx_http_process_unique_header_line },
 
     { ngx_string("User-Agent"), offsetof(ngx_http_headers_in_t, user_agent),
                  ngx_http_process_header_line },
@@ -836,7 +839,7 @@ ngx_http_process_request_headers(ngx_eve
                     ngx_log_error(NGX_LOG_INFO, c->log, 0,
                                   "client sent too long header line: \"%V\"",
                                   &header);
-                    ngx_http_close_request(r, NGX_HTTP_BAD_REQUEST);
+                    ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
                     return;
                 }
             }
@@ -948,7 +951,7 @@ ngx_http_process_request_headers(ngx_eve
         ngx_log_error(NGX_LOG_INFO, c->log, 0,
                       "client sent invalid header line: \"%V\\r...\"",
                       &header);
-        ngx_http_close_request(r, NGX_HTTP_BAD_REQUEST);
+        ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
         return;
     }
 }
@@ -1199,6 +1202,21 @@ ngx_http_process_unique_header_line(ngx_
 
 
 static ngx_int_t
+ngx_http_process_connection(ngx_http_request_t *r, ngx_table_elt_t *h,
+    ngx_uint_t offset)
+{
+    if (ngx_strstr(h->value.data, "close")) {
+        r->headers_in.connection_type = NGX_HTTP_CONNECTION_CLOSE;
+
+    } else if (ngx_strstr(h->value.data, "keep-alive")) {
+        r->headers_in.connection_type = NGX_HTTP_CONNECTION_KEEP_ALIVE;
+    }
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
 ngx_http_process_cookie(ngx_http_request_t *r, ngx_table_elt_t *h,
     ngx_uint_t offset)
 {
@@ -1294,7 +1312,7 @@ ngx_http_process_request_header(ngx_http
         return NGX_ERROR;
     }
 
-    if (r->method & (NGX_HTTP_TRACE)) {
+    if (r->method & NGX_HTTP_TRACE) {
         ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
                       "client sent TRACE method");
         ngx_http_finalize_request(r, NGX_HTTP_NOT_ALLOWED);
@@ -1317,26 +1335,11 @@ ngx_http_process_request_header(ngx_http
         return NGX_ERROR;
     }
 
-    if (r->headers_in.connection) {
-        if (r->headers_in.connection->value.len == 5
-            && ngx_strcasecmp(r->headers_in.connection->value.data,
-                              (u_char *) "close")
-               == 0)
-        {
-            r->headers_in.connection_type = NGX_HTTP_CONNECTION_CLOSE;
-
-        } else if (r->headers_in.connection->value.len == 10
-                   && ngx_strcasecmp(r->headers_in.connection->value.data,
-                                     (u_char *) "keep-alive")
-                      == 0)
-        {
-            r->headers_in.connection_type = NGX_HTTP_CONNECTION_KEEP_ALIVE;
-
-            if (r->headers_in.keep_alive) {
-                r->headers_in.keep_alive_n =
-                                ngx_atotm(r->headers_in.keep_alive->value.data,
-                                          r->headers_in.keep_alive->value.len);
-            }
+    if (r->headers_in.connection_type == NGX_HTTP_CONNECTION_KEEP_ALIVE) {
+        if (r->headers_in.keep_alive) {
+            r->headers_in.keep_alive_n =
+                            ngx_atotm(r->headers_in.keep_alive->value.data,
+                                      r->headers_in.keep_alive->value.len);
         }
     }
 
@@ -1710,7 +1713,7 @@ ngx_http_set_write_handler(ngx_http_requ
 
     r->http_state = NGX_HTTP_WRITING_REQUEST_STATE;
 
-    r->read_event_handler = ngx_http_block_read;
+    r->read_event_handler = ngx_http_test_read;
     r->write_event_handler = ngx_http_writer;
 
     wev = r->connection->write;
@@ -1823,6 +1826,26 @@ ngx_http_writer(ngx_http_request_t *r)
 static void
 ngx_http_block_read(ngx_http_request_t *r)
 {
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "http read blocked");
+
+    /* aio does not call this handler */
+
+    if ((ngx_event_flags & NGX_USE_LEVEL_EVENT)
+        && r->connection->read->active)
+    {
+        if (ngx_del_event(r->connection->read, NGX_READ_EVENT, 0)
+            == NGX_ERROR)
+        {
+            ngx_http_close_request(r, 0);
+        }
+    }
+}
+
+
+static void
+ngx_http_test_read(ngx_http_request_t *r)
+{
     int                n;
     char               buf[1];
     ngx_err_t          err;
@@ -1832,7 +1855,7 @@ ngx_http_block_read(ngx_http_request_t *
     c = r->connection;
     rev = c->read;
 
-    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http read blocked");
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http test read");
 
 #if (NGX_HAVE_KQUEUE)