# HG changeset patch # User Igor Sysoev # Date 1159732800 -14400 # Node ID a528ae0fe90986556b3a731d3d041d1b21ed34f1 # Parent 302a8e8b4ae7bd264c9ac3c4a2d74980ba7efa00 nginx 0.4.4 *) Feature: the $scheme variable. *) Feature: the "expires" directive supports the "max" parameter. *) Feature: the "include" directive supports the "*" mask. Thanks to Jonathan Dance. *) Bugfix: the "return" directive always overrode the "error_page" response code redirected by the "error_page" directive. *) Bugfix: a segmentation fault occurred if zero-length body was in PUT method. *) Bugfix: the redirect was changed incorrectly if the variables were used in the "proxy_redirect" directive. diff --git a/CHANGES b/CHANGES --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,23 @@ +Changes with nginx 0.4.4 02 Oct 2006 + + *) Feature: the "scheme" variable. + + *) Feature: the "expires" directive supports the "max" parameter. + + *) Feature: the "include" directive supports the "*" mask. + Thanks to Jonathan Dance. + + *) Bugfix: the "return" directive always overrode the "error_page" + response code redirected by the "error_page" directive. + + *) Bugfix: a segmentation fault occurred if zero-length body was in PUT + method. + + *) Bugfix: the redirect was changed incorrectly if the variables were + used in the "proxy_redirect" directive. + + Changes with nginx 0.4.3 26 Sep 2006 *) Change: now the 499 error could not be redirected using an diff --git a/CHANGES.ru b/CHANGES.ru --- a/CHANGES.ru +++ b/CHANGES.ru @@ -1,4 +1,23 @@ +Изменения в nginx 0.4.4 02.10.2006 + + *) Добавление: переменная scheme. + + *) Добавление: директива expires поддерживает параметр max. + + *) Добавление: директива include поддерживает маску "*". + Спасибо Jonathan Dance. + + *) Исправление: директива return всегда изменяла код ответа, + перенаправленного директивой error_page. + + *) Исправление: происходил segmentation fault, если в методе PUT + передавалось тело нулевой длины. + + *) Исправление: при использовании переменных в директиве proxy_redirect + редирект изменялся неверно. + + Изменения в nginx 0.4.3 26.09.2006 *) Изменение: ошибку 499 теперь нельзя перенаправить с помощью diff --git a/auto/options b/auto/options --- a/auto/options +++ b/auto/options @@ -260,12 +260,14 @@ cat << END --without-http_auth_basic_module disable ngx_http_auth_basic_module --without-http_autoindex_module disable ngx_http_autoindex_module --without-http_geo_module disable ngx_http_geo_module + --without-http_map_module disable ngx_http_map_module --without-http_referer_module disable ngx_http_referer_module --without-http_rewrite_module disable ngx_http_rewrite_module --without-http_proxy_module disable ngx_http_proxy_module --without-http_fastcgi_module disable ngx_http_fastcgi_module --without-http_memcached_module disable ngx_http_memcached_module --without-http_empty_gif_module disable ngx_http_empty_gif_module + --without-http_browser_module disable ngx_http_browser_module --with-http_perl_module enable ngx_http_perl_module --with-perl_modules_path=PATH set path to the perl modules @@ -281,6 +283,7 @@ cat << END --without-http disable HTTP server --with-imap enable IMAP4/POP3 proxy module + --with-imap_ssl_module enable ngx_imap_ssl_module --with-cc=PATH set path to C compiler --with-cpp=PATH set path to C preprocessor 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_VER "nginx/0.4.3" +#define NGINX_VER "nginx/0.4.4" #define NGINX_VAR "NGINX" #define NGX_OLDPID_EXT ".oldbin" 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 @@ -650,18 +650,52 @@ ngx_conf_read_token(ngx_conf_t *cf) static char * ngx_conf_include(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { - ngx_str_t *value, file; + char *rv; + ngx_int_t n; + ngx_str_t *value, file; + ngx_glob_t gl; value = cf->args->elts; file = value[1]; + ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "include %s", file.data); + 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); + ngx_memzero(&gl, sizeof(ngx_glob_t)); + + gl.pattern = file.data; + gl.log = cf->log; + + if (ngx_open_glob(&gl) != NGX_OK) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno, + ngx_open_glob_n " \"%s\" failed", file.data); + return NGX_CONF_ERROR; + } + + rv = NGX_CONF_OK; + + for ( ;; ) { + n = ngx_read_glob(&gl, &file); - return ngx_conf_parse(cf, &file); + if (n != NGX_OK) { + break; + } + + ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "include %s", file.data); + + rv = ngx_conf_parse(cf, &file); + + if (rv != NGX_CONF_OK) { + break; + } + } + + ngx_close_glob(&gl); + + return rv; } diff --git a/src/http/modules/ngx_http_headers_filter_module.c b/src/http/modules/ngx_http_headers_filter_module.c --- a/src/http/modules/ngx_http_headers_filter_module.c +++ b/src/http/modules/ngx_http_headers_filter_module.c @@ -26,6 +26,7 @@ typedef struct { #define NGX_HTTP_EXPIRES_UNSET -2147483647 #define NGX_HTTP_EXPIRES_OFF -2147483646 #define NGX_HTTP_EXPIRES_EPOCH -2147483645 +#define NGX_HTTP_EXPIRES_MAX -2147483644 static void *ngx_http_headers_create_conf(ngx_conf_t *cf); @@ -177,6 +178,13 @@ ngx_http_headers_filter(ngx_http_request cc->value.len = sizeof("no-cache") - 1; cc->value.data = (u_char *) "no-cache"; + } else if (conf->expires == NGX_HTTP_EXPIRES_MAX) { + expires->value.data = (u_char *) "Thu, 31 Dec 2037 23:55:55 GMT"; + + /* 10 years */ + cc->value.len = sizeof("max-age=315360000") - 1; + cc->value.data = (u_char *) "max-age=315360000"; + } else { expires->value.data = ngx_palloc(r->pool, len); if (expires->value.data == NULL) { @@ -349,6 +357,11 @@ ngx_http_headers_expires(ngx_conf_t *cf, return NGX_CONF_OK; } + if (ngx_strcmp(value[1].data, "max") == 0) { + hcf->expires = NGX_HTTP_EXPIRES_MAX; + return NGX_CONF_OK; + } + if (ngx_strcmp(value[1].data, "off") == 0) { hcf->expires = NGX_HTTP_EXPIRES_OFF; return NGX_CONF_OK; diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -1397,8 +1397,11 @@ ngx_http_proxy_rewrite_redirect_vars(ngx e.ip = pr->replacement.vars.lengths; e.request = r; - for (len = prefix; *(uintptr_t *) e.ip; len += lcode(&e)) { + len = prefix + h->value.len - pr->redirect.len; + + while (*(uintptr_t *) e.ip) { lcode = *(ngx_http_script_len_code_pt *) e.ip; + len += lcode(&e); } data = ngx_palloc(r->pool, len); @@ -1418,6 +1421,9 @@ ngx_http_proxy_rewrite_redirect_vars(ngx code(&e); } + ngx_memcpy(e.pos, h->value.data + prefix + pr->redirect.len, + h->value.len - pr->redirect.len - prefix); + h->value.len = len; h->value.data = data; 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 @@ -178,7 +178,11 @@ ngx_http_rewrite_handler(ngx_http_reques code(e); } - return e->status; + if (r->err_status == 0) { + return e->status; + } + + return r->err_status; } 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 @@ -430,6 +430,7 @@ struct ngx_http_request_s { unsigned plain_http:1; unsigned chunked:1; unsigned header_only:1; + unsigned zero_body:1; unsigned keepalive:1; unsigned lingering_close:1; unsigned discard_body:1; diff --git a/src/http/ngx_http_request_body.c b/src/http/ngx_http_request_body.c --- a/src/http/ngx_http_request_body.c +++ b/src/http/ngx_http_request_body.c @@ -34,6 +34,7 @@ ngx_http_read_client_request_body(ngx_ht ssize_t size; ngx_buf_t *b; ngx_chain_t *cl, **next; + ngx_temp_file_t *tf; ngx_http_request_body_t *rb; ngx_http_core_loc_conf_t *clcf; @@ -49,7 +50,43 @@ ngx_http_read_client_request_body(ngx_ht r->request_body = rb; - if (r->headers_in.content_length_n <= 0) { + if (r->headers_in.content_length_n < 0) { + post_handler(r); + return NGX_OK; + } + + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + + if (r->headers_in.content_length_n == 0) { + + if (r->request_body_in_file_only) { + tf = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t)); + if (tf == NULL) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + tf->file.fd = NGX_INVALID_FILE; + tf->file.log = r->connection->log; + tf->path = clcf->client_body_temp_path; + tf->pool = r->pool; + tf->warn = "a client request body is buffered to a temporary file"; + tf->log_level = r->request_body_file_log_level; + tf->persistent = r->request_body_in_persistent_file; + + if (r->request_body_file_group_access) { + tf->mode = 0660; + } + + rb->temp_file = tf; + + if (ngx_create_temp_file(&tf->file, tf->path, tf->pool, + tf->persistent, tf->mode) + != NGX_OK) + { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + } + post_handler(r); return NGX_OK; } @@ -139,8 +176,6 @@ ngx_http_read_client_request_body(ngx_ht next = &rb->bufs; } - clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - size = clcf->client_body_buffer_size; size += size >> 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 @@ -841,6 +841,7 @@ ngx_http_script_return_code(ngx_http_scr if (code->status == NGX_HTTP_NO_CONTENT) { e->request->header_only = 1; + e->request->zero_body = 1; } e->ip += sizeof(ngx_http_script_return_code_t) - sizeof(uintptr_t); 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 @@ -455,25 +455,32 @@ ngx_http_special_response_handler(ngx_ht msie_padding = 0; - if (error_pages[err].len) { - r->headers_out.content_length_n = error_pages[err].len - + sizeof(error_tail) - 1; + if (!r->zero_body) { + if (error_pages[err].len) { + r->headers_out.content_length_n = error_pages[err].len + + sizeof(error_tail) - 1; - if (clcf->msie_padding - && r->headers_in.msie - && r->http_version >= NGX_HTTP_VERSION_10 - && error >= NGX_HTTP_BAD_REQUEST - && error != NGX_HTTP_REQUEST_URI_TOO_LARGE) - { - r->headers_out.content_length_n += sizeof(ngx_http_msie_stub) - 1; - msie_padding = 1; + if (clcf->msie_padding + && r->headers_in.msie + && r->http_version >= NGX_HTTP_VERSION_10 + && error >= NGX_HTTP_BAD_REQUEST + && error != NGX_HTTP_REQUEST_URI_TOO_LARGE) + { + r->headers_out.content_length_n += + sizeof(ngx_http_msie_stub) - 1; + msie_padding = 1; + } + + r->headers_out.content_type.len = sizeof("text/html") - 1; + r->headers_out.content_type.data = (u_char *) "text/html"; + + } else { + r->headers_out.content_length_n = -1; } - r->headers_out.content_type.len = sizeof("text/html") - 1; - r->headers_out.content_type.data = (u_char *) "text/html"; - } else { - r->headers_out.content_length_n = -1; + r->headers_out.content_length_n = 0; + err = 0; } if (r->headers_out.content_length) { 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 @@ -36,6 +36,8 @@ static ngx_int_t ngx_http_variable_serve ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_variable_server_port(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); +static ngx_int_t ngx_http_variable_scheme(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_variable_document_root(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_variable_request_filename(ngx_http_request_t *r, @@ -122,6 +124,8 @@ static ngx_http_variable_t ngx_http_cor { ngx_string("server_protocol"), NULL, ngx_http_variable_request, offsetof(ngx_http_request_t, http_protocol), 0, 0 }, + { ngx_string("scheme"), NULL, ngx_http_variable_scheme, 0, 0, 0 }, + { ngx_string("request_uri"), NULL, ngx_http_variable_request, offsetof(ngx_http_request_t, unparsed_uri), 0, 0 }, @@ -772,6 +776,34 @@ ngx_http_variable_server_port(ngx_http_r static ngx_int_t +ngx_http_variable_scheme(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) +{ +#if (NGX_HTTP_SSL) + + if (r->connection->ssl) { + v->len = sizeof("https") - 1; + v->valid = 1; + v->no_cachable = 0; + v->not_found = 0; + v->data = (u_char *) "https"; + + return NGX_OK; + } + +#endif + + v->len = sizeof("http") - 1; + v->valid = 1; + v->no_cachable = 0; + v->not_found = 0; + v->data = (u_char *) "http"; + + return NGX_OK; +} + + +static ngx_int_t ngx_http_variable_document_root(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { diff --git a/src/os/unix/ngx_files.c b/src/os/unix/ngx_files.c --- a/src/os/unix/ngx_files.c +++ b/src/os/unix/ngx_files.c @@ -253,6 +253,40 @@ ngx_open_dir(ngx_str_t *name, ngx_dir_t } +ngx_int_t +ngx_open_glob(ngx_glob_t *gl) +{ + if (glob((char *) gl->pattern, 0, NULL, &gl->pglob) == 0) { + return NGX_OK; + } + + return NGX_ERROR; +} + + +ngx_int_t +ngx_read_glob(ngx_glob_t *gl, ngx_str_t *name) +{ + if (gl->n < gl->pglob.gl_pathc) { + + name->len = (size_t) ngx_strlen(gl->pglob.gl_pathv[gl->n]); + name->data = (u_char *) gl->pglob.gl_pathv[gl->n]; + gl->n++; + + return NGX_OK; + } + + return NGX_DONE; +} + + +void +ngx_close_glob(ngx_glob_t *gl) +{ + globfree(&gl->pglob); +} + + ngx_err_t ngx_trylock_fd(ngx_fd_t fd) { diff --git a/src/os/unix/ngx_files.h b/src/os/unix/ngx_files.h --- a/src/os/unix/ngx_files.h +++ b/src/os/unix/ngx_files.h @@ -130,6 +130,20 @@ ngx_int_t ngx_open_dir(ngx_str_t *name, #define ngx_de_mtime(dir) (dir)->info.st_mtime +typedef struct { + int n; + glob_t pglob; + u_char *pattern; + ngx_log_t *log; +} ngx_glob_t; + + +ngx_int_t ngx_open_glob(ngx_glob_t *gl); +#define ngx_open_glob_n "glob()" +ngx_int_t ngx_read_glob(ngx_glob_t *gl, ngx_str_t *name); +void ngx_close_glob(ngx_glob_t *gl); + + ngx_err_t ngx_trylock_fd(ngx_fd_t fd); ngx_err_t ngx_lock_fd(ngx_fd_t fd); ngx_err_t ngx_unlock_fd(ngx_fd_t fd); diff --git a/src/os/unix/ngx_freebsd_config.h b/src/os/unix/ngx_freebsd_config.h --- a/src/os/unix/ngx_freebsd_config.h +++ b/src/os/unix/ngx_freebsd_config.h @@ -21,6 +21,7 @@ #include #include #include +#include #include /* FIONBIO */ #include diff --git a/src/os/unix/ngx_linux_config.h b/src/os/unix/ngx_linux_config.h --- a/src/os/unix/ngx_linux_config.h +++ b/src/os/unix/ngx_linux_config.h @@ -27,6 +27,7 @@ #include #include #include +#include #include #include diff --git a/src/os/unix/ngx_posix_config.h b/src/os/unix/ngx_posix_config.h --- a/src/os/unix/ngx_posix_config.h +++ b/src/os/unix/ngx_posix_config.h @@ -37,6 +37,7 @@ #include #include #include +#include #if (NGX_HAVE_SYS_FILIO_H) #include /* FIONBIO */ diff --git a/src/os/unix/ngx_solaris_config.h b/src/os/unix/ngx_solaris_config.h --- a/src/os/unix/ngx_solaris_config.h +++ b/src/os/unix/ngx_solaris_config.h @@ -25,6 +25,7 @@ #include #include #include +#include #include /* FIONBIO */ #include