# HG changeset patch # User Igor Sysoev # Date 1181073600 -14400 # Node ID 94e16de3c33fe6dec2954e7b1c88f9c97273f11b # Parent 0bcb7f864b94e6b0f86aaf83bfaa5d37c0d76369 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. diff --git a/CHANGES b/CHANGES --- 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 diff --git a/CHANGES.ru b/CHANGES.ru --- 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 diff --git a/src/core/nginx.h b/src/core/nginx.h --- 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" diff --git a/src/core/ngx_conf_file.c b/src/core/ngx_conf_file.c --- 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; diff --git a/src/core/ngx_output_chain.c b/src/core/ngx_output_chain.c --- 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; } diff --git a/src/http/modules/ngx_http_rewrite_module.c b/src/http/modules/ngx_http_rewrite_module.c --- 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; } diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm --- 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); diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c --- 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; diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c --- 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; } diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h --- 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 ; diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c --- 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; }