# HG changeset patch # User Igor Sysoev # Date 1295557200 -10800 # Node ID ce857f6b74a730b814b13b64f205017721d2ff24 # Parent f02ddde4a240628b002b3fc85aa19bb38e7c5d85 nginx 0.9.4 *) Feature: the "server_name" directive supports the $hostname variable. *) Feature: 494 code for "Request Header Too Large" error. diff --git a/CHANGES b/CHANGES --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,11 @@ +Changes with nginx 0.9.4 21 Jan 2011 + + *) Feature: the "server_name" directive supports the $hostname variable. + + *) Feature: 494 code for "Request Header Too Large" error. + + Changes with nginx 0.9.3 13 Dec 2010 *) Bugfix: if there was a single server for given IPv6 address:port @@ -5028,7 +5035,7 @@ Changes with nginx 0.1.11 Changes with nginx 0.1.10 26 Nov 2004 *) Bugfix: if the request without arguments contains "//", "/./", - "/../" or "%XX" then the lost character in the request line was + "/../" or "%XX" then the last character in the request line was lost; the bug had appeared in 0.1.9. *) Bugfix: the fix in 0.1.9 for the files bigger than 2G on Linux did diff --git a/CHANGES.ru b/CHANGES.ru --- a/CHANGES.ru +++ b/CHANGES.ru @@ -1,9 +1,16 @@ +Изменения в nginx 0.9.4 21.01.2011 + + *) Добавление: директива server_name поддерживает переменную $hostname. + + *) Добавление: 494 код для ошибки "Request Header Too Large". + + Изменения в nginx 0.9.3 13.12.2010 - *) Исправление: если для пары адрес:порт описан только один сервер, то - выделения в регулярных выражениях в директиве server_name не - работали. + *) Исправление: если для пары IPv6-адрес:порт описан только один + сервер, то выделения в регулярных выражениях в директиве server_name + не работали. *) Исправление: nginx не собирался под Solaris; ошибка появилась в 0.9.0. diff --git a/LICENSE b/LICENSE --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2010 Igor Sysoev + * Copyright (C) 2002-2011 Igor Sysoev * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/src/core/nginx.h b/src/core/nginx.h --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -8,8 +8,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 9003 -#define NGINX_VERSION "0.9.3" +#define nginx_version 9004 +#define NGINX_VERSION "0.9.4" #define NGINX_VER "nginx/" NGINX_VERSION #define NGINX_VAR "NGINX" 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 @@ -560,7 +560,7 @@ ngx_ssl_handshake(ngx_connection_t *c) #if (NGX_DEBUG) { char buf[129], *s, *d; -#if OPENSSL_VERSION_NUMBER >= 0x1000000fL +#if OPENSSL_VERSION_NUMBER >= 0x10000000L const #endif SSL_CIPHER *cipher; diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c --- a/src/http/modules/ngx_http_fastcgi_module.c +++ b/src/http/modules/ngx_http_fastcgi_module.c @@ -1280,8 +1280,9 @@ ngx_http_fastcgi_process_header(ngx_http } else { u->buffer.pos = u->buffer.start; } +#else + u->buffer.pos = u->buffer.start; #endif - u->buffer.last = u->buffer.pos; f->large_stderr = 1; } diff --git a/src/http/modules/ngx_http_not_modified_filter_module.c b/src/http/modules/ngx_http_not_modified_filter_module.c --- a/src/http/modules/ngx_http_not_modified_filter_module.c +++ b/src/http/modules/ngx_http_not_modified_filter_module.c @@ -57,11 +57,11 @@ ngx_http_not_modified_header_filter(ngx_ { return ngx_http_next_header_filter(r); } - + if (r->headers_in.if_unmodified_since) { return ngx_http_test_precondition(r); } - + if (r->headers_in.if_modified_since) { return ngx_http_test_not_modified(r); } 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 @@ -48,7 +48,7 @@ our @EXPORT = qw( HTTP_INSUFFICIENT_STORAGE ); -our $VERSION = '0.9.3'; +our $VERSION = '0.9.4'; 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 @@ -789,11 +789,7 @@ ngx_http_handler(ngx_http_request_t *r) if (!r->internal) { switch (r->headers_in.connection_type) { case 0: - if (r->http_version > NGX_HTTP_VERSION_10) { - r->keepalive = 1; - } else { - r->keepalive = 0; - } + r->keepalive = (r->http_version > NGX_HTTP_VERSION_10); break; case NGX_HTTP_CONNECTION_CLOSE: @@ -805,13 +801,7 @@ ngx_http_handler(ngx_http_request_t *r) break; } - if (r->headers_in.content_length_n > 0) { - r->lingering_close = 1; - - } else { - r->lingering_close = 0; - } - + r->lingering_close = (r->headers_in.content_length_n > 0); r->phase_handler = 0; } else { @@ -3000,6 +2990,7 @@ ngx_http_core_merge_srv_conf(ngx_conf_t ngx_http_core_srv_conf_t *prev = parent; ngx_http_core_srv_conf_t *conf = child; + ngx_str_t name; ngx_http_server_name_t *sn; /* TODO: it does not merge, it inits only */ @@ -3031,14 +3022,9 @@ ngx_http_core_merge_srv_conf(ngx_conf_t ngx_conf_merge_value(conf->underscores_in_headers, prev->underscores_in_headers, 0); - if (conf->server_name.data == NULL) { - ngx_str_set(&conf->server_name, ""); - + if (conf->server_names.nelts == 0) { + /* the array has 4 empty preallocated elements, so push can not fail */ sn = ngx_array_push(&conf->server_names); - if (sn == NULL) { - return NGX_CONF_ERROR; - } - #if (NGX_PCRE) sn->regex = NULL; #endif @@ -3046,6 +3032,27 @@ ngx_http_core_merge_srv_conf(ngx_conf_t ngx_str_set(&sn->name, ""); } + sn = conf->server_names.elts; + name = sn[0].name; + +#if (NGX_PCRE) + if (sn->regex) { + name.len++; + name.data--; + } else +#endif + + if (name.data[0] == '.') { + name.len--; + name.data++; + } + + conf->server_name.len = name.len; + conf->server_name.data = ngx_pstrdup(cf->pool, &name); + if (conf->server_name.data == NULL) { + return NGX_CONF_ERROR; + } + return NGX_CONF_OK; } @@ -3635,29 +3642,12 @@ ngx_http_core_server_name(ngx_conf_t *cf ngx_http_core_srv_conf_t *cscf = conf; u_char ch; - ngx_str_t *value, name; + ngx_str_t *value; ngx_uint_t i; ngx_http_server_name_t *sn; value = cf->args->elts; - ch = value[1].data[0]; - - if (cscf->server_name.data == NULL) { - name = value[1]; - - if (ch == '.') { - name.len--; - name.data++; - } - - cscf->server_name.len = name.len; - cscf->server_name.data = ngx_pstrdup(cf->pool, &name); - if (cscf->server_name.data == NULL) { - return NGX_CONF_ERROR; - } - } - for (i = 1; i < cf->args->nelts; i++) { ch = value[i].data[0]; @@ -3692,7 +3682,13 @@ ngx_http_core_server_name(ngx_conf_t *cf sn->regex = NULL; #endif sn->server = cscf; - sn->name = value[i]; + + if (ngx_strcasecmp(value[i].data, (u_char *) "$hostname") == 0) { + sn->name = cf->cycle->hostname; + + } else { + sn->name = value[i]; + } if (value[i].data[0] != '~') { ngx_strlow(sn->name.data, sn->name.data, sn->name.len); 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 @@ -978,10 +978,13 @@ ngx_http_process_request_headers(ngx_eve if (rv == NGX_DECLINED) { p = r->header_name_start; + r->lingering_close = 1; + if (p == NULL) { ngx_log_error(NGX_LOG_INFO, c->log, 0, "client sent too large request"); - ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); + ngx_http_finalize_request(r, + NGX_HTTP_REQUEST_HEADER_TOO_LARGE); return; } @@ -995,7 +998,9 @@ ngx_http_process_request_headers(ngx_eve ngx_log_error(NGX_LOG_INFO, c->log, 0, "client sent too long header line: \"%*s\"", len, r->header_name_start); - ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); + + ngx_http_finalize_request(r, + NGX_HTTP_REQUEST_HEADER_TOO_LARGE); return; } } 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 @@ -95,7 +95,9 @@ /* The special code to close connection without any response */ #define NGX_HTTP_CLOSE 444 -#define NGX_HTTP_OWN_CODES 495 +#define NGX_HTTP_NGINX_CODES 494 + +#define NGX_HTTP_REQUEST_HEADER_TOO_LARGE 494 #define NGX_HTTPS_CERT_ERROR 495 #define NGX_HTTPS_NO_CERT 496 diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c --- a/src/http/ngx_http_special_response.c +++ b/src/http/ngx_http_special_response.c @@ -201,6 +201,16 @@ static char ngx_http_error_416_page[] = ; +static char ngx_http_error_494_page[] = +"" CRLF +"400 Request Header Or Cookie Too Large" +CRLF +"" CRLF +"

400 Bad Request

" CRLF +"
Request Header Or Cookie Too Large
" CRLF +; + + static char ngx_http_error_495_page[] = "" CRLF "400 The SSL certificate error" @@ -315,6 +325,7 @@ static ngx_str_t ngx_http_error_pages[] #define NGX_HTTP_LAST_LEVEL_400 417 #define NGX_HTTP_LEVEL_400 (NGX_HTTP_LAST_LEVEL_400 - 400) + ngx_string(ngx_http_error_494_page), /* 494, request header too large */ ngx_string(ngx_http_error_495_page), /* 495, https certificate error */ ngx_string(ngx_http_error_496_page), /* 496, https no certificate */ ngx_string(ngx_http_error_497_page), /* 497, http to https */ @@ -429,17 +440,18 @@ ngx_http_special_response_handler(ngx_ht err = error - NGX_HTTP_BAD_REQUEST + NGX_HTTP_LEVEL_200 + NGX_HTTP_LEVEL_300; - } else if (error >= NGX_HTTP_OWN_CODES + } else if (error >= NGX_HTTP_NGINX_CODES && error < NGX_HTTP_LAST_LEVEL_500) { /* 49X, 5XX */ - err = error - NGX_HTTP_OWN_CODES + NGX_HTTP_LEVEL_200 - + NGX_HTTP_LEVEL_300 - + NGX_HTTP_LEVEL_400; + err = error - NGX_HTTP_NGINX_CODES + NGX_HTTP_LEVEL_200 + + NGX_HTTP_LEVEL_300 + + NGX_HTTP_LEVEL_400; switch (error) { case NGX_HTTP_TO_HTTPS: case NGX_HTTPS_CERT_ERROR: case NGX_HTTPS_NO_CERT: + case NGX_HTTP_REQUEST_HEADER_TOO_LARGE: r->err_status = NGX_HTTP_BAD_REQUEST; break; }