changeset 308:94e16de3c33f NGINX_0_5_24

nginx 0.5.24 *) Security: the "ssl_verify_client" directive did not work if request was made using HTTP/0.9. *) Bugfix: a part of response body might be passed uncompressed if gzip was used; bug appeared in 0.5.23.
author Igor Sysoev <http://sysoev.ru>
date Wed, 06 Jun 2007 00:00:00 +0400
parents 0bcb7f864b94
children 638a3e67d37d
files CHANGES CHANGES.ru src/core/nginx.h src/core/ngx_conf_file.c src/core/ngx_output_chain.c src/http/modules/ngx_http_rewrite_module.c src/http/modules/perl/nginx.pm src/http/ngx_http.c src/http/ngx_http_core_module.c src/http/ngx_http_core_module.h src/http/ngx_http_request.c
diffstat 11 files changed, 150 insertions(+), 96 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,13 @@
 
+Changes with nginx 0.5.24                                        06 Jun 2007
+
+    *) Security: the "ssl_verify_client" directive did not work if request 
+       was made using HTTP/0.9.
+
+    *) Bugfix: a part of response body may be passed uncompressed if gzip 
+       was used; bug appeared in 0.5.23.
+
+
 Changes with nginx 0.5.23                                        04 Jun 2007
 
     *) Feature: the ngx_http_ssl_module supports Server Name Indication TLS 
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,13 @@
 
+Изменения в nginx 0.5.24                                          06.06.2007
+
+    *) Безопасность: директива ssl_verify_client не работала, если запрос 
+       выполнялся по протоколу HTTP/0.9.
+
+    *) Исправление: при использовании сжатия часть ответа могла 
+       передаваться несжатой; ошибка появилась в 0.5.23.
+
+
 Изменения в nginx 0.5.23                                          04.06.2007
 
     *) Добавление: модуль ngx_http_ssl_module поддерживает расширение TLS 
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
 #define _NGINX_H_INCLUDED_
 
 
-#define NGINX_VERSION      "0.5.23"
+#define NGINX_VERSION      "0.5.24"
 #define NGINX_VER          "nginx/" NGINX_VERSION
 
 #define NGINX_VAR          "NGINX"
--- a/src/core/ngx_conf_file.c
+++ b/src/core/ngx_conf_file.c
@@ -344,7 +344,7 @@ ngx_conf_handler(ngx_conf_t *cf, ngx_int
             }
 
             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-                               "the \"%s\" directive %s", name->data, rv);
+                               "\"%s\" directive %s", name->data, rv);
 
             return NGX_ERROR;
         }
@@ -360,13 +360,13 @@ ngx_conf_handler(ngx_conf_t *cf, ngx_int
 not_allowed:
 
     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-                       "directive \"%s\" is not allowed here", name->data);
+                       "\"%s\" directive is not allowed here", name->data);
     return NGX_ERROR;
 
 invalid:
 
     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-                       "invalid number arguments in directive \"%s\"",
+                       "invalid number arguments in \"%s\" directive",
                        name->data);
 
     return NGX_ERROR;
--- a/src/core/ngx_output_chain.c
+++ b/src/core/ngx_output_chain.c
@@ -418,7 +418,7 @@ ngx_output_chain_copy_buf(ngx_buf_t *dst
 
         src->file_pos += n;
 
-        if (src->pos == src->last) {
+        if (src->file_pos == src->file_last) {
             dst->flush = src->flush;
             dst->last_buf = src->last_buf;
         }
--- a/src/http/modules/ngx_http_rewrite_module.c
+++ b/src/http/modules/ngx_http_rewrite_module.c
@@ -567,15 +567,14 @@ ngx_http_rewrite_if(ngx_conf_t *cf, ngx_
     clcf->name = pclcf->name;
     clcf->noname = 1;
 
-    if (pclcf->locations.elts == NULL) {
-        if (ngx_array_init(&pclcf->locations, cf->pool, 4, sizeof(void *))
-            == NGX_ERROR)
-        {
+    if (pclcf->locations == NULL) {
+        pclcf->locations = ngx_array_create(cf->pool, 2, sizeof(void *));
+        if (pclcf->locations == NULL) {
             return NGX_CONF_ERROR;
         }
     }
 
-    clcfp = ngx_array_push(&pclcf->locations);
+    clcfp = ngx_array_push(pclcf->locations);
     if (clcfp == NULL) {
         return NGX_CONF_ERROR;
     }
--- a/src/http/modules/perl/nginx.pm
+++ b/src/http/modules/perl/nginx.pm
@@ -47,7 +47,7 @@ our @EXPORT = qw(
     HTTP_INSUFFICIENT_STORAGE
 );
 
-our $VERSION = '0.5.23';
+our $VERSION = '0.5.24';
 
 require XSLoader;
 XSLoader::load('nginx', $VERSION);
--- a/src/http/ngx_http.c
+++ b/src/http/ngx_http.c
@@ -1015,7 +1015,11 @@ ngx_http_merge_locations(ngx_conf_t *cf,
             return rv;
         }
 
-        rv = ngx_http_merge_locations(cf, &clcfp[i]->locations,
+        if (clcfp[i]->locations == NULL) {
+            continue;
+        }
+
+        rv = ngx_http_merge_locations(cf, clcfp[i]->locations,
                                       clcfp[i]->loc_conf, module, ctx_index);
         if (rv != NGX_CONF_OK) {
             return rv;
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -29,7 +29,7 @@ typedef struct {
 
 
 static ngx_int_t ngx_http_core_find_location(ngx_http_request_t *r,
-    ngx_array_t *locations, size_t len);
+    ngx_array_t *locations, ngx_uint_t regex_start, size_t len);
 
 static ngx_int_t ngx_http_core_preconfiguration(ngx_conf_t *cf);
 static void *ngx_http_core_create_main_conf(ngx_conf_t *cf);
@@ -629,7 +629,7 @@ ngx_http_core_find_config_phase(ngx_http
 
     cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
 
-    rc = ngx_http_core_find_location(r, &cscf->locations, 0);
+    rc = ngx_http_core_find_location(r, &cscf->locations, cscf->regex_start, 0);
 
     if (rc == NGX_HTTP_INTERNAL_SERVER_ERROR) {
         ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
@@ -930,7 +930,7 @@ ngx_http_update_location_config(ngx_http
 
 static ngx_int_t
 ngx_http_core_find_location(ngx_http_request_t *r,
-    ngx_array_t *locations, size_t len)
+    ngx_array_t *locations, ngx_uint_t regex_start, size_t len)
 {
     ngx_int_t                  n, rc;
     ngx_uint_t                 i, found, noregex;
@@ -1008,8 +1008,9 @@ ngx_http_core_find_location(ngx_http_req
     if (found) {
         clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
 
-        if (clcf->locations.nelts) {
-            rc = ngx_http_core_find_location(r, &clcf->locations, len);
+        if (clcf->locations) {
+            rc = ngx_http_core_find_location(r, clcf->locations,
+                                             clcf->regex_start, len);
 
             if (rc != NGX_OK) {
                 return rc;
@@ -1025,11 +1026,7 @@ ngx_http_core_find_location(ngx_http_req
 
     /* regex matches */
 
-    for (/* void */; i < locations->nelts; i++) {
-
-        if (!clcfp[i]->regex) {
-            continue;
-        }
+    for (i = regex_start; i < locations->nelts; i++) {
 
         if (clcfp[i]->noname) {
             break;
@@ -1553,14 +1550,15 @@ ngx_http_cleanup_add(ngx_http_request_t 
 static char *
 ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
 {
-    char                       *rv;
-    void                       *mconf;
-    ngx_uint_t                  m;
-    ngx_conf_t                  pcf;
-    ngx_http_module_t          *module;
-    ngx_http_conf_ctx_t        *ctx, *http_ctx;
-    ngx_http_core_srv_conf_t   *cscf, **cscfp;
-    ngx_http_core_main_conf_t  *cmcf;
+    char                        *rv;
+    void                        *mconf;
+    ngx_uint_t                   i, m;
+    ngx_conf_t                   pcf;
+    ngx_http_module_t           *module;
+    ngx_http_conf_ctx_t         *ctx, *http_ctx;
+    ngx_http_core_srv_conf_t    *cscf, **cscfp;
+    ngx_http_core_loc_conf_t   **clcfp;
+    ngx_http_core_main_conf_t   *cmcf;
 
     ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
     if (ctx == NULL) {
@@ -1644,6 +1642,16 @@ ngx_http_core_server(ngx_conf_t *cf, ngx
     ngx_sort(cscf->locations.elts, (size_t) cscf->locations.nelts,
              sizeof(ngx_http_core_loc_conf_t *), ngx_http_core_cmp_locations);
 
+    cscf->regex_start = cscf->locations.nelts;
+    clcfp = cscf->locations.elts;
+
+    for (i = 0; i < cscf->locations.nelts; i++) {
+        if (clcfp[i]->regex) {
+            cscf->regex_start = i;
+            break;
+        }
+    }
+
     return rv;
 }
 
@@ -1652,7 +1660,7 @@ static char *
 ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
 {
     char                      *rv;
-    ngx_int_t                  m;
+    ngx_uint_t                 i, m;
     ngx_str_t                 *value;
     ngx_conf_t                 save;
     ngx_http_module_t         *module;
@@ -1785,15 +1793,15 @@ ngx_http_core_location(ngx_conf_t *cf, n
             return NGX_CONF_ERROR;
         }
 
-        if (pclcf->locations.elts == NULL) {
-            if (ngx_array_init(&pclcf->locations, cf->pool, 4, sizeof(void *))
-                != NGX_OK)
-            {
+        if (pclcf->locations == NULL) {
+            pclcf->locations = ngx_array_create(cf->pool, 2, sizeof(void *));
+
+            if (pclcf->locations == NULL) {
                 return NGX_CONF_ERROR;
             }
         }
 
-        clcfp = ngx_array_push(&pclcf->locations);
+        clcfp = ngx_array_push(pclcf->locations);
         if (clcfp == NULL) {
             return NGX_CONF_ERROR;
         }
@@ -1813,9 +1821,23 @@ ngx_http_core_location(ngx_conf_t *cf, n
         return rv;
     }
 
-    ngx_sort(clcf->locations.elts, (size_t) clcf->locations.nelts,
+    if (clcf->locations == NULL) {
+        return rv;
+    }
+
+    ngx_sort(clcf->locations->elts, (size_t) clcf->locations->nelts,
              sizeof(ngx_http_core_loc_conf_t *), ngx_http_core_cmp_locations);
 
+    clcf->regex_start = clcf->locations->nelts;
+    clcfp = clcf->locations->elts;
+
+    for (i = 0; i < clcf->locations->nelts; i++) {
+        if (clcfp[i]->regex) {
+            clcf->regex_start = i;
+            break;
+        }
+    }
+
     return rv;
 }
 
@@ -2674,6 +2696,18 @@ ngx_http_core_root(ngx_conf_t *cf, ngx_c
         return NGX_CONF_ERROR;
     }
 
+#if (NGX_PCRE)
+
+    if (lcf->regex && alias) {
+        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                           "the \"alias\" directive may not be used "
+                           "inside location given by regular expression");
+
+        return NGX_CONF_ERROR;
+    }
+
+#endif
+
     value = cf->args->elts;
 
     if (ngx_strstr(value[1].data, "$document_root")
@@ -2825,15 +2859,14 @@ ngx_http_core_limit_except(ngx_conf_t *c
     lcf->name = clcf->name;
     lcf->noname = 1;
 
-    if (clcf->locations.elts == NULL) {
-        if (ngx_array_init(&clcf->locations, cf->pool, 4, sizeof(void *))
-            == NGX_ERROR)
-        {
+    if (clcf->locations == NULL) {
+        clcf->locations = ngx_array_create(cf->pool, 2, sizeof(void *));
+        if (clcf->locations == NULL) {
             return NGX_CONF_ERROR;
         }
     }
 
-    clcfp = ngx_array_push(&clcf->locations);
+    clcfp = ngx_array_push(clcf->locations);
     if (clcfp == NULL) {
         return NGX_CONF_ERROR;
     }
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -117,6 +117,9 @@ typedef struct {
      */
     ngx_array_t                locations;
 
+    unsigned                   regex_start:16;
+    unsigned                   wildcard:1;
+
     /* array of the ngx_http_listen_t, "listen" directive */
     ngx_array_t                listen;
 
@@ -138,8 +141,6 @@ typedef struct {
 
     ngx_flag_t                 optimize_server_names;
     ngx_flag_t                 ignore_invalid_headers;
-
-    ngx_uint_t                 wildcard;  /* unsigned  wildcard:1 */
 } ngx_http_core_srv_conf_t;
 
 
@@ -172,7 +173,7 @@ typedef struct {
     in_addr_t                  addr;
 
     ngx_hash_t                 hash;
-    ngx_hash_wildcard_t        *dns_wildcards;
+    ngx_hash_wildcard_t       *dns_wildcards;
 
     ngx_array_t                names;      /* array of ngx_http_server_name_t */
 
@@ -210,6 +211,8 @@ struct ngx_http_core_loc_conf_s {
     ngx_regex_t  *regex;
 #endif
 
+    unsigned      regex_start:16;
+
     unsigned      noname:1;   /* "if () {}" block */
 
     unsigned      exact_match:1;
@@ -219,7 +222,7 @@ struct ngx_http_core_loc_conf_s {
     unsigned      alias:1;
 
     /* array of inclusive ngx_http_core_loc_conf_t */
-    ngx_array_t   locations;
+    ngx_array_t  *locations;
 
     /* pointer to the modules' loc_conf */
     void        **loc_conf ;
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -25,6 +25,7 @@ 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_process_request(ngx_http_request_t *r);
 static void ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host,
     size_t len, ngx_uint_t hash);
 
@@ -711,24 +712,7 @@ ngx_http_process_request_line(ngx_event_
                            "http exten: \"%V\"", &r->exten);
 
             if (r->http_version < NGX_HTTP_VERSION_10) {
-
-                if (rev->timer_set) {
-                    ngx_del_timer(rev);
-                }
-
-#if (NGX_STAT_STUB)
-                ngx_atomic_fetch_add(ngx_stat_reading, -1);
-                r->stat_reading = 0;
-                ngx_atomic_fetch_add(ngx_stat_writing, 1);
-                r->stat_writing = 1;
-#endif
-
-                rev->handler = ngx_http_request_handler;
-                c->write->handler = ngx_http_request_handler;
-                r->read_event_handler = ngx_http_block_read;
-
-                ngx_http_handler(r);
-
+                ngx_http_process_request(r);
                 return;
             }
 
@@ -945,22 +929,7 @@ ngx_http_process_request_headers(ngx_eve
                 return;
             }
 
-            if (rev->timer_set) {
-                ngx_del_timer(rev);
-            }
-
-#if (NGX_STAT_STUB)
-            ngx_atomic_fetch_add(ngx_stat_reading, -1);
-            r->stat_reading = 0;
-            ngx_atomic_fetch_add(ngx_stat_writing, 1);
-            r->stat_writing = 1;
-#endif
-
-            rev->handler = ngx_http_request_handler;
-            c->write->handler = ngx_http_request_handler;
-            r->read_event_handler = ngx_http_block_read;
-
-            ngx_http_handler(r);
+            ngx_http_process_request(r);
 
             return;
         }
@@ -1250,13 +1219,9 @@ ngx_http_process_cookie(ngx_http_request
 static ngx_int_t
 ngx_http_process_request_header(ngx_http_request_t *r)
 {
-    size_t                    len;
-    u_char                   *host, *ua, *user_agent, ch;
-    ngx_uint_t                hash;
-#if (NGX_HTTP_SSL)
-    long                      rc;
-    ngx_http_ssl_srv_conf_t  *sscf;
-#endif
+    size_t       len;
+    u_char      *host, *ua, *user_agent, ch;
+    ngx_uint_t   hash;
 
     if (r->headers_in.host) {
 
@@ -1419,36 +1384,68 @@ ngx_http_process_request_header(ngx_http
         }
     }
 
+    return NGX_OK;
+}
+
+
+static void
+ngx_http_process_request(ngx_http_request_t *r)
+{
+    ngx_connection_t         *c;
 #if (NGX_HTTP_SSL)
-
-    if (r->connection->ssl) {
+    long                      rc;
+    ngx_http_ssl_srv_conf_t  *sscf;
+#endif
+
+    c = r->connection;
+
+#if (NGX_HTTP_SSL)
+
+    if (c->ssl) {
         sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module);
 
         if (sscf->verify) {
-            rc = SSL_get_verify_result(r->connection->ssl->connection);
+            rc = SSL_get_verify_result(c->ssl->connection);
 
             if (rc != X509_V_OK) {
-                ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                ngx_log_error(NGX_LOG_INFO, c->log, 0,
                               "client SSL certificate verify error: (%l:%s)",
                               rc, X509_verify_cert_error_string(rc));
                 ngx_http_finalize_request(r, NGX_HTTPS_CERT_ERROR);
-                return NGX_ERROR;
+                return;
             }
 
-            if (SSL_get_peer_certificate(r->connection->ssl->connection)
+            if (SSL_get_peer_certificate(c->ssl->connection)
                 == NULL)
             {
-                ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                ngx_log_error(NGX_LOG_INFO, c->log, 0,
                               "client sent no required SSL certificate");
                 ngx_http_finalize_request(r, NGX_HTTPS_NO_CERT);
-                return NGX_ERROR;
+                return;
             }
         }
     }
 
 #endif
 
-    return NGX_OK;
+    if (c->read->timer_set) {
+        ngx_del_timer(c->read);
+    }
+
+#if (NGX_STAT_STUB)
+    ngx_atomic_fetch_add(ngx_stat_reading, -1);
+    r->stat_reading = 0;
+    ngx_atomic_fetch_add(ngx_stat_writing, 1);
+    r->stat_writing = 1;
+#endif
+
+    c->read->handler = ngx_http_request_handler;
+    c->write->handler = ngx_http_request_handler;
+    r->read_event_handler = ngx_http_block_read;
+
+    ngx_http_handler(r);
+
+    return;
 }