# HG changeset patch # User Igor Sysoev # Date 1175457600 -14400 # Node ID 27d9d1f26b383e54dbe402d51f72d58d70aded51 # Parent 30378812e3afff5afa21736651b0409114b856c3 nginx 0.5.17 *) Change: now nginx always returns the 405 status for the TRACE method. *) Feature: now nginx supports the "include" directive inside the "types" block. *) Bugfix: the $document_root variable usage in the "root" and "alias" directives is disabled: this caused recursive stack overflow. *) Bugfix: in the HTTPS protocol in the "proxy_pass" directive. *) Bugfix: in some cases non-cachable variables (such as $uri variable) returned old cached value. diff --git a/CHANGES b/CHANGES --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,20 @@ +Changes with nginx 0.5.17 02 Apr 2007 + + *) Change: now nginx always returns the 405 status for the TRACE method. + + *) Feature: now nginx supports the "include" directive inside the + "types" block. + + *) Bugfix: the $document_root variable usage in the "root" and "alias" + directives is disabled: this caused recursive stack overflow. + + *) Bugfix: in the HTTPS protocol in the "proxy_pass" directive. + + *) Bugfix: in some cases non-cachable variables (such as $uri variable) + returned old cached value. + + Changes with nginx 0.5.16 26 Mar 2007 *) Bugfix: the C-class network was not used as hash key in the @@ -978,7 +994,7 @@ Changes with nginx 0.3.31 various addresses inside one server, then server names like "*.domain.tld" worked for first address only; bug appeared in 0.3.18. - *) Bugfix: if the HTTP protocol was used in the "proxy_pass" directive + *) Bugfix: if the HTTPS protocol was used in the "proxy_pass" directive and the request body was in temporarily file then the request was not transferred. @@ -1053,7 +1069,7 @@ Changes with nginx 0.3.27 *) Feature: the "lock_file" directive and the --with-lock-path=PATH autoconfiguration directive. - *) Bugfix: if the HTTP protocol was used in the "proxy_pass" directive + *) Bugfix: if the HTTPS protocol was used in the "proxy_pass" directive then the requests with the body was not transferred. @@ -1180,9 +1196,9 @@ Changes with nginx 0.3.17 *) Bugfix: the timeouts were not used in SSL handshake; bug appeared in 0.2.4. - *) Bugfix: in the HTTP protocol in the "proxy_pass" directive. - - *) Bugfix: when the HTTP protocol was used in the "proxy_pass" + *) Bugfix: in the HTTPS protocol in the "proxy_pass" directive. + + *) Bugfix: when the HTTPS protocol was used in the "proxy_pass" directive the port 80 was used by default. diff --git a/CHANGES.ru b/CHANGES.ru --- a/CHANGES.ru +++ b/CHANGES.ru @@ -1,4 +1,20 @@ +Изменения в nginx 0.5.17 02.04.2007 + + *) Изменение: теперь nginx для метода TRACE всегда возвращает код 405. + + *) Добавление: теперь nginx поддерживает директиву include внутри блока + types. + + *) Исправление: использование переменной $document_root в директиве + root и alias запрещено: оно вызывало рекурсивное переполнение стека. + + *) Исправление: в использовании протокола HTTPS в директиве proxy_pass. + + *) Исправление: в некоторых случаях некэшируемые переменные (такие, как + $uri) возвращали старое закэшированное значение. + + Изменения в nginx 0.5.16 26.03.2007 *) Исправление: в качестве ключа для хэша в директиве ip_hash не 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.16" +#define NGINX_VERSION "0.5.17" #define NGINX_VER "nginx/" NGINX_VERSION #define NGINX_VAR "NGINX" diff --git a/src/core/ngx_string.h b/src/core/ngx_string.h --- a/src/core/ngx_string.h +++ b/src/core/ngx_string.h @@ -40,6 +40,7 @@ typedef struct { #define ngx_strstr(s1, s2) strstr((const char *) s1, (const char *) s2) +#define ngx_strchr(s1, c) strchr((const char *) s1, (int) c) #define ngx_strlen(s) strlen((const char *) s) diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -547,22 +547,32 @@ ngx_ssl_handshake_handler(ngx_event_t *e ssize_t ngx_ssl_recv_chain(ngx_connection_t *c, ngx_chain_t *cl) { + u_char *last; ssize_t n, bytes; ngx_buf_t *b; bytes = 0; - while (cl) { - b = cl->buf; - - n = ngx_ssl_recv(c, b->last, b->end - b->last); + b = cl->buf; + last = b->last; + + for ( ;; ) { + + n = ngx_ssl_recv(c, last, b->end - last); if (n > 0) { - b->last += n; + last += n; bytes += n; - if (b->last == b->end) { + if (last == b->end) { cl = cl->next; + + if (cl == NULL) { + return bytes; + } + + b = cl->buf; + last = b->last; } continue; @@ -574,8 +584,6 @@ ngx_ssl_recv_chain(ngx_connection_t *c, return n; } - - return bytes; } 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.16'; +our $VERSION = '0.5.17'; require XSLoader; XSLoader::load('nginx', $VERSION); 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 @@ -874,7 +874,8 @@ ngx_http_update_location_config(ngx_http } if (r == r->main) { - r->connection->log->file = clcf->err_log->file; + r->connection->log->file = clcf->err_log->file; + if (!(r->connection->log->log_level & NGX_LOG_DEBUG_CONNECTION)) { r->connection->log->log_level = clcf->err_log->log_level; } @@ -1897,16 +1898,29 @@ ngx_http_core_type(ngx_conf_t *cf, ngx_c { ngx_http_core_loc_conf_t *lcf = conf; - ngx_str_t *value, *content_type, *old; + ngx_str_t *value, *content_type, *old, file; ngx_uint_t i, n; ngx_hash_key_t *type; + value = cf->args->elts; + + if (ngx_strcmp(value[0].data, "include") == 0) { + file = value[1]; + + if (ngx_conf_full_name(cf->cycle, &file) == NGX_ERROR){ + return NGX_CONF_ERROR; + } + + ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "include %s", file.data); + + return ngx_conf_parse(cf, &file); + } + content_type = ngx_palloc(cf->pool, sizeof(ngx_str_t)); if (content_type == NULL) { return NGX_CONF_ERROR; } - value = cf->args->elts; *content_type = value[0]; for (i = 1; i < cf->args->nelts; i++) { @@ -2600,6 +2614,12 @@ ngx_http_core_server_name(ngx_conf_t *cf return NGX_CONF_ERROR; } + if (ngx_strchr(value[i].data, '/')) { + ngx_conf_log_error(NGX_LOG_WARN, cf, 0, + "server name \"%V\" has strange symbols", + &value[i]); + } + sn = ngx_array_push(&cscf->server_names); if (sn == NULL) { return NGX_CONF_ERROR; @@ -2645,6 +2665,17 @@ ngx_http_core_root(ngx_conf_t *cf, ngx_c value = cf->args->elts; + if (ngx_strstr(value[1].data, "$document_root") + || ngx_strstr(value[1].data, "${document_root}")) + { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "the $document_root variable may not be used " + "in the \"%V\" directive", + &cmd->name); + + return NGX_CONF_ERROR; + } + lcf->alias = alias; lcf->root = value[1]; diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c --- a/src/http/ngx_http_parse.c +++ b/src/http/ngx_http_parse.c @@ -146,6 +146,12 @@ ngx_http_parse_request_line(ngx_http_req r->method = NGX_HTTP_MKCOL; } + if (m[0] == 'T' && m[1] == 'R' + && m[2] == 'A' && m[3] == 'C' && m[4] == 'E') + { + r->method = NGX_HTTP_TRACE; + } + break; case 6: 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 @@ -1267,6 +1267,13 @@ ngx_http_process_request_header(ngx_http return NGX_ERROR; } + 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); + return NGX_ERROR; + } + if (r->headers_in.transfer_encoding && ngx_strstr(r->headers_in.transfer_encoding->value.data, "chunked")) { diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h --- a/src/http/ngx_http_request.h +++ b/src/http/ngx_http_request.h @@ -37,6 +37,7 @@ #define NGX_HTTP_PROPPATCH 0x0800 #define NGX_HTTP_LOCK 0x1000 #define NGX_HTTP_UNLOCK 0x2000 +#define NGX_HTTP_TRACE 0x4000 #define NGX_HTTP_CONNECTION_CLOSE 1 #define NGX_HTTP_CONNECTION_KEEP_ALIVE 2 diff --git a/src/http/ngx_http_script.c b/src/http/ngx_http_script.c --- a/src/http/ngx_http_script.c +++ b/src/http/ngx_http_script.c @@ -305,9 +305,20 @@ u_char * ngx_http_script_run(ngx_http_request_t *r, ngx_str_t *value, void *code_lengths, size_t len, void *code_values) { - ngx_http_script_code_pt code; - ngx_http_script_len_code_pt lcode; - ngx_http_script_engine_t e; + ngx_uint_t i; + ngx_http_script_code_pt code; + ngx_http_script_len_code_pt lcode; + ngx_http_script_engine_t e; + ngx_http_core_main_conf_t *cmcf; + + cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); + + for (i = 0; i < cmcf->variables.nelts; i++) { + if (r->variables[i].no_cachable) { + r->variables[i].valid = 0; + r->variables[i].not_found = 0; + } + } ngx_memzero(&e, sizeof(ngx_http_script_engine_t)); diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -21,6 +21,7 @@ static void ngx_http_upstream_send_reque ngx_http_upstream_t *u); static void ngx_http_upstream_send_request_handler(ngx_event_t *wev); static void ngx_http_upstream_process_header(ngx_event_t *rev); +static ngx_int_t ngx_http_upstream_test_connect(ngx_connection_t *c); static void ngx_http_upstream_process_body_in_memory(ngx_event_t *rev); static void ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u); @@ -757,8 +758,7 @@ ngx_http_upstream_reinit(ngx_http_reques static void ngx_http_upstream_send_request(ngx_http_request_t *r, ngx_http_upstream_t *u) { - int rc, err; - socklen_t len; + ngx_int_t rc; ngx_connection_t *c; c = u->peer.connection; @@ -766,41 +766,9 @@ ngx_http_upstream_send_request(ngx_http_ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http upstream send request"); - if (!u->request_sent) { - -#if (NGX_HAVE_KQUEUE) - - if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { - if (c->write->pending_eof) { - (void) ngx_connection_error(c, c->write->kq_errno, - "kevent() reported that connect() failed"); - ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR); - return; - } - - } else -#endif - { - err = 0; - len = sizeof(int); - - /* - * BSDs and Linux return 0 and set a pending error in err - * Solaris returns -1 and sets errno - */ - - if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len) - == -1) - { - err = ngx_errno; - } - - if (err) { - (void) ngx_connection_error(c, err, "connect() failed"); - ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR); - return; - } - } + if (!u->request_sent && ngx_http_upstream_test_connect(c) != NGX_OK) { + ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR); + return; } c->log->action = "sending request to upstream"; @@ -945,6 +913,11 @@ ngx_http_upstream_process_header(ngx_eve return; } + if (!u->request_sent && ngx_http_upstream_test_connect(c) != NGX_OK) { + ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR); + return; + } + if (u->buffer.start == NULL) { u->buffer.start = ngx_palloc(r->pool, u->conf->buffer_size); if (u->buffer.start == NULL) { @@ -1277,6 +1250,48 @@ ngx_http_upstream_process_header(ngx_eve } +static ngx_int_t +ngx_http_upstream_test_connect(ngx_connection_t *c) +{ + int err; + socklen_t len; + +#if (NGX_HAVE_KQUEUE) + + if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { + if (c->write->pending_eof) { + (void) ngx_connection_error(c, c->write->kq_errno, + "kevent() reported that connect() failed"); + return NGX_ERROR; + } + + } else +#endif + { + err = 0; + len = sizeof(int); + + /* + * BSDs and Linux return 0 and set a pending error in err + * Solaris returns -1 and sets errno + */ + + if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len) + == -1) + { + err = ngx_errno; + } + + if (err) { + (void) ngx_connection_error(c, err, "connect() failed"); + return NGX_ERROR; + } + } + + return NGX_OK; +} + + static void ngx_http_upstream_process_body_in_memory(ngx_event_t *rev) { diff --git a/src/http/ngx_http_variables.c b/src/http/ngx_http_variables.c --- a/src/http/ngx_http_variables.c +++ b/src/http/ngx_http_variables.c @@ -379,7 +379,7 @@ ngx_http_get_indexed_variable(ngx_http_r ngx_http_variable_value_t * ngx_http_get_flushed_variable(ngx_http_request_t *r, ngx_uint_t index) { - ngx_http_variable_value_t *v; + ngx_http_variable_value_t *v; v = &r->variables[index];