diff src/http/ngx_http_request.c @ 198:e6da4931e0e0 NGINX_0_3_46

nginx 0.3.46 *) Feature: the "proxy_hide_header", "proxy_pass_header", "fastcgi_hide_header", and "fastcgi_pass_header" directives. *) Change: the "proxy_pass_x_powered_by", "fastcgi_x_powered_by", and "proxy_pass_server" directives were canceled. *) Feature: the "X-Accel-Buffering" response header line is supported in proxy mode. *) Bugfix: the reconfiguration bug and memory leaks in the ngx_http_perl_module.
author Igor Sysoev <http://sysoev.ru>
date Thu, 11 May 2006 00:00:00 +0400
parents 8759b346e431
children d2ae1c9f1fd3
line wrap: on
line diff
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -25,7 +25,8 @@ static ngx_int_t ngx_http_process_cookie
     ngx_table_elt_t *h, ngx_uint_t offset);
 
 static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r);
-static void ngx_http_find_virtual_server(ngx_http_request_t *r);
+static void ngx_http_find_virtual_server(ngx_http_request_t *r,
+    ngx_http_virtual_names_t *vn, ngx_uint_t hash);
 
 static void ngx_http_request_handler(ngx_event_t *ev);
 static ngx_int_t ngx_http_set_write_handler(ngx_http_request_t *r);
@@ -739,8 +740,8 @@ ngx_http_process_request_headers(ngx_eve
 {
     ssize_t                     n;
     ngx_int_t                   rc, rv;
-    ngx_uint_t                  key;
     ngx_str_t                   header;
+    ngx_uint_t                  i;
     ngx_table_elt_t            *h;
     ngx_connection_t           *c;
     ngx_http_header_t          *hh;
@@ -763,7 +764,6 @@ ngx_http_process_request_headers(ngx_eve
 
     cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
     cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
-    hh = (ngx_http_header_t *) cmcf->headers_in_hash.buckets;
 
     rc = NGX_AGAIN;
 
@@ -841,16 +841,28 @@ ngx_http_process_request_headers(ngx_eve
             h->value.data = r->header_start;
             h->value.data[h->value.len] = '\0';
 
-            key = h->hash % cmcf->headers_in_hash.hash_size;
-
-            if (hh[key].name.len == h->key.len
-                && ngx_strcasecmp(hh[key].name.data, h->key.data) == 0)
-            {
-                if (hh[key].handler(r, h, hh[key].offset) != NGX_OK) {
-                    return;
+            h->lowcase_key = ngx_palloc(r->pool, h->key.len);
+            if (h->lowcase_key == NULL) {
+                ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+                return;
+            }
+
+            if (h->key.len == r->lowcase_index) {
+                ngx_memcpy(h->lowcase_key, r->lowcase_header, h->key.len);
+
+            } else {
+                for (i = 0; i < h->key.len; i++) {
+                    h->lowcase_key[i] = ngx_tolower(h->lowcase_key[i]);
                 }
             }
 
+            hh = ngx_hash_find(&cmcf->headers_in_hash, h->hash,
+                               h->lowcase_key, h->key.len);
+
+            if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {
+                return;
+            }
+
             ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                            "http header: \"%V: %V\"",
                            &h->key, &h->value);
@@ -1174,12 +1186,16 @@ ngx_http_process_request_header(ngx_http
 {
     size_t                    len;
     u_char                   *ua, *user_agent, ch;
+    ngx_uint_t                hash;
 #if (NGX_HTTP_SSL)
     long                      rc;
     ngx_http_ssl_srv_conf_t  *sscf;
 #endif
 
     if (r->headers_in.host) {
+
+        hash = 0;
+
         for (len = 0; len < r->headers_in.host->value.len; len++) {
             ch = r->headers_in.host->value.data[len];
 
@@ -1187,16 +1203,21 @@ ngx_http_process_request_header(ngx_http
                 break;
             }
 
-            r->headers_in.host->value.data[len] = ngx_tolower(ch);
+            ch = ngx_tolower(ch);
+            r->headers_in.host->value.data[len] = ch;
+            hash = ngx_hash(hash, ch);
         }
 
-        if (r->headers_in.host->value.data[len - 1] == '.') {
+        if (len && r->headers_in.host->value.data[len - 1] == '.') {
             len--;
+            hash = ngx_hash_key(r->headers_in.host->value.data, len);
         }
 
         r->headers_in.host_name_len = len;
 
-        ngx_http_find_virtual_server(r);
+        if (r->virtual_names) {
+            ngx_http_find_virtual_server(r, r->virtual_names, hash);
+        }
 
     } else {
         if (r->http_version > NGX_HTTP_VERSION_10) {
@@ -1345,27 +1366,19 @@ ngx_http_process_request_header(ngx_http
 
 
 static void
-ngx_http_find_virtual_server(ngx_http_request_t *r)
+ngx_http_find_virtual_server(ngx_http_request_t *r,
+    ngx_http_virtual_names_t *vn, ngx_uint_t hash)
 {
     size_t                     len;
     u_char                    *host;
-    ngx_http_virtual_names_t  *vn;
     ngx_http_core_loc_conf_t  *clcf;
     ngx_http_core_srv_conf_t  *cscf;
 
-    vn = r->virtual_names;
-
-    if (vn == NULL) {
-        return;
-    }
-
     host = r->headers_in.host->value.data;
     len = r->headers_in.host_name_len;
 
-    /* STUB: ngx_hash_key() here is STUB */
-
     if (vn->hash.buckets) {
-        cscf = ngx_hash_find(&vn->hash, ngx_hash_key(host, len), host, len);
+        cscf = ngx_hash_find(&vn->hash, hash, host, len);
         if (cscf) {
             goto found;
         }