diff options
| author | Igor Sysoev <igor@sysoev.ru> | 2010-11-29 15:29:38 +0000 |
|---|---|---|
| committer | Jonathan Kolb <jon@b0g.us> | 2010-11-29 15:29:38 +0000 |
| commit | 3f13cc6b2c2c6f71bcaa8b1e3a2e2190db6d852f (patch) | |
| tree | 2ee4bc413b131dd56b1849f26bcc489da97750c3 /src/http | |
| parent | df5fa5fcb16c6fd65657add97be5f056b58afa36 (diff) | |
| download | nginx-3f13cc6b2c2c6f71bcaa8b1e3a2e2190db6d852f.tar.gz | |
Changes with nginx 0.9.0 29 Nov 2010v0.9.0
*) Feature: the "keepalive_disable" directive.
*) Feature: the "map" directive supports variables as value of a
defined variable.
*) Feature: the "map" directive supports empty strings as value of the
first parameter.
*) Feature: the "map" directive supports expressions as the first
parameter.
*) Feature: nginx(8) manual page.
Thanks to Sergey Osokin.
*) Feature: Linux accept4() support.
Thanks to Simon Liu.
*) Workaround: elimination of Linux linker warning about "sys_errlist"
and "sys_nerr"; the warning had appeared in 0.8.35.
*) Bugfix: a segmentation fault might occur in a worker process, if the
"auth_basic" directive was used.
Thanks to Michail Laletin.
*) Bugfix: compatibility with ngx_http_eval_module; the bug had
appeared in 0.8.42.
Diffstat (limited to 'src/http')
| -rw-r--r-- | src/http/modules/ngx_http_degradation_module.c | 7 | ||||
| -rw-r--r-- | src/http/modules/ngx_http_map_module.c | 134 | ||||
| -rw-r--r-- | src/http/modules/perl/nginx.pm | 2 | ||||
| -rw-r--r-- | src/http/ngx_http_core_module.c | 72 | ||||
| -rw-r--r-- | src/http/ngx_http_core_module.h | 6 | ||||
| -rw-r--r-- | src/http/ngx_http_upstream.h | 2 |
6 files changed, 146 insertions, 77 deletions
diff --git a/src/http/modules/ngx_http_degradation_module.c b/src/http/modules/ngx_http_degradation_module.c index a35733f81..a5f83bb20 100644 --- a/src/http/modules/ngx_http_degradation_module.c +++ b/src/http/modules/ngx_http_degradation_module.c @@ -86,9 +86,6 @@ ngx_module_t ngx_http_degradation_module = { }; -static ngx_uint_t ngx_degraded; - - static ngx_int_t ngx_http_degradation_handler(ngx_http_request_t *r) { @@ -139,8 +136,6 @@ ngx_http_degraded(ngx_http_request_t *r) /* unlock mutex */ if (sbrk_size >= dmcf->sbrk_size) { - ngx_degraded = 1; - if (log) { ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, "degradation sbrk:%uzM", @@ -151,8 +146,6 @@ ngx_http_degraded(ngx_http_request_t *r) } } - ngx_degraded = 0; - return 0; } diff --git a/src/http/modules/ngx_http_map_module.c b/src/http/modules/ngx_http_map_module.c index fe3fa7751..5f263a55d 100644 --- a/src/http/modules/ngx_http_map_module.c +++ b/src/http/modules/ngx_http_map_module.c @@ -19,15 +19,17 @@ typedef struct { ngx_hash_keys_arrays_t keys; ngx_array_t *values_hash; + ngx_array_t var_values; ngx_http_variable_value_t *default_value; + ngx_conf_t *cf; ngx_uint_t hostnames; /* unsigned hostnames:1 */ } ngx_http_map_conf_ctx_t; typedef struct { ngx_hash_combined_t hash; - ngx_int_t index; + ngx_http_complex_value_t value; ngx_http_variable_value_t *default_value; ngx_uint_t hostnames; /* unsigned hostnames:1 */ } ngx_http_map_ctx_t; @@ -105,49 +107,43 @@ ngx_http_map_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, ngx_http_map_ctx_t *map = (ngx_http_map_ctx_t *) data; size_t len; - u_char *name; + ngx_str_t val; ngx_uint_t key; - ngx_http_variable_value_t *vv, *value; + ngx_http_variable_value_t *value; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http map started"); - vv = ngx_http_get_flushed_variable(r, map->index); - - if (vv == NULL || vv->not_found) { - *v = *map->default_value; - return NGX_OK; + if (ngx_http_complex_value(r, &map->value, &val) != NGX_OK) { + return NGX_ERROR; } - len = vv->len; + len = val.len; - if (len && map->hostnames && vv->data[len - 1] == '.') { + if (len && map->hostnames && val.data[len - 1] == '.') { len--; } - if (len == 0) { - *v = *map->default_value; - return NGX_OK; - } - - name = ngx_pnalloc(r->pool, len); - if (name == NULL) { - return NGX_ERROR; - } + key = ngx_hash_strlow(val.data, val.data, len); - key = ngx_hash_strlow(name, vv->data, len); + value = ngx_hash_find_combined(&map->hash, key, val.data, len); - value = ngx_hash_find_combined(&map->hash, key, name, len); + if (value == NULL) { + value = map->default_value; + } - if (value) { - *v = *value; + if (!value->valid) { + value = ngx_http_get_flushed_variable(r, (ngx_uint_t) value->data); - } else { - *v = *map->default_value; + if (value == NULL || value->not_found) { + value = &ngx_http_variable_null_value; + } } + *v = *value; + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http map: \"%v\" \"%v\"", vv, v); + "http map: \"%v\" \"%v\"", &val, v); return NGX_OK; } @@ -175,14 +171,15 @@ ngx_http_map_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_map_conf_t *mcf = conf; - char *rv; - ngx_str_t *value, name; - ngx_conf_t save; - ngx_pool_t *pool; - ngx_hash_init_t hash; - ngx_http_map_ctx_t *map; - ngx_http_variable_t *var; - ngx_http_map_conf_ctx_t ctx; + char *rv; + ngx_str_t *value, name; + ngx_conf_t save; + ngx_pool_t *pool; + ngx_hash_init_t hash; + ngx_http_map_ctx_t *map; + ngx_http_variable_t *var; + ngx_http_map_conf_ctx_t ctx; + ngx_http_compile_complex_value_t ccv; if (mcf->hash_max_size == NGX_CONF_UNSET_UINT) { mcf->hash_max_size = 2048; @@ -203,13 +200,13 @@ ngx_http_map_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) value = cf->args->elts; - name = value[1]; - name.len--; - name.data++; + ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); - map->index = ngx_http_get_variable_index(cf, &name); + ccv.cf = cf; + ccv.value = &value[1]; + ccv.complex_value = &map->value; - if (map->index == NGX_ERROR) { + if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { return NGX_CONF_ERROR; } @@ -244,7 +241,16 @@ ngx_http_map_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) return NGX_CONF_ERROR; } + if (ngx_array_init(&ctx.var_values, cf->pool, 2, + sizeof(ngx_http_variable_value_t)) + != NGX_OK) + { + ngx_destroy_pool(pool); + return NGX_CONF_ERROR; + } + ctx.default_value = NULL; + ctx.cf = &save; ctx.hostnames = 0; save = *cf; @@ -344,8 +350,8 @@ ngx_http_map_cmp_dns_wildcards(const void *one, const void *two) static char * ngx_http_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf) { - ngx_int_t rc; - ngx_str_t *value, file; + ngx_int_t rc, index; + ngx_str_t *value, file, name; ngx_uint_t i, key; ngx_http_map_conf_ctx_t *ctx; ngx_http_variable_value_t *var, **vp; @@ -364,11 +370,6 @@ ngx_http_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf) ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid number of the map parameters"); return NGX_CONF_ERROR; - - } else if (value[0].len == 0) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid first parameter"); - return NGX_CONF_ERROR; } if (ngx_strcmp(value[0].data, "include") == 0) { @@ -383,6 +384,45 @@ ngx_http_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf) return ngx_conf_parse(cf, &file); } + if (value[1].data[0] == '$') { + name = value[1]; + name.len--; + name.data++; + + index = ngx_http_get_variable_index(ctx->cf, &name); + if (index == NGX_ERROR) { + return NGX_CONF_ERROR; + } + + var = ctx->var_values.elts; + + for (i = 0; i < ctx->var_values.nelts; i++) { + if (index == (ngx_int_t) var[i].data) { + goto found; + } + } + + var = ngx_palloc(ctx->keys.pool, sizeof(ngx_http_variable_value_t)); + if (var == NULL) { + return NGX_CONF_ERROR; + } + + var->valid = 0; + var->no_cacheable = 0; + var->not_found = 0; + var->len = 0; + var->data = (u_char *) index; + + vp = ngx_array_push(&ctx->var_values); + if (vp == NULL) { + return NGX_CONF_ERROR; + } + + *vp = var; + + goto found; + } + key = 0; for (i = 0; i < value[1].len; i++) { @@ -451,7 +491,7 @@ found: return NGX_CONF_OK; } - if (value[0].len && value[0].data[0] == '!') { + if (value[0].len && value[0].data[0] == '\\') { value[0].len--; value[0].data++; } diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm index faff340e2..a2a0f7470 100644 --- 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.8.53'; +our $VERSION = '0.9.0'; require XSLoader; XSLoader::load('nginx', $VERSION); diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c index 0345be965..0e8d5a497 100644 --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -133,6 +133,14 @@ static ngx_conf_enum_t ngx_http_core_if_modified_since[] = { }; +static ngx_conf_enum_t ngx_http_core_keepalive_disable[] = { + { ngx_string("none"), NGX_HTTP_KEEPALIVE_DISABLE_NONE }, + { ngx_string("msie6"), NGX_HTTP_KEEPALIVE_DISABLE_MSIE6 }, + { ngx_string("safari"), NGX_HTTP_KEEPALIVE_DISABLE_SAFARI }, + { ngx_null_string, 0 } +}; + + static ngx_path_init_t ngx_http_client_temp_path = { ngx_string(NGX_HTTP_CLIENT_TEMP_PATH), { 0, 0, 0 } }; @@ -494,6 +502,13 @@ static ngx_command_t ngx_http_core_commands[] = { offsetof(ngx_http_core_loc_conf_t, keepalive_requests), NULL }, + { ngx_string("keepalive_disable"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_enum_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_core_loc_conf_t, keepalive_disable), + &ngx_http_core_keepalive_disable }, + { ngx_string("satisfy"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_enum_slot, @@ -790,26 +805,6 @@ ngx_http_handler(ngx_http_request_t *r) break; } - if (r->keepalive) { - - if (r->headers_in.msie6) { - if (r->method == NGX_HTTP_POST) { - /* - * MSIE may wait for some time if an response for - * a POST request was sent over a keepalive connection - */ - r->keepalive = 0; - } - - } else if (r->headers_in.safari) { - /* - * Safari may send a POST request to a closed keepalive - * connection and stalls for some time - */ - r->keepalive = 0; - } - } - if (r->headers_in.content_length_n > 0) { r->lingering_close = 1; @@ -905,12 +900,21 @@ ngx_http_core_rewrite_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph) rc = ph->handler(r); + if (rc == NGX_OK) { + r->phase_handler = ph->next; + return NGX_AGAIN; + } + if (rc == NGX_DECLINED) { r->phase_handler++; return NGX_AGAIN; } - /* rc == NGX_OK || rc == NGX_ERROR || rc == NGX_HTTP_... */ + if (rc == NGX_DONE) { + return NGX_OK; + } + + /* NGX_AGAIN || rc == NGX_ERROR || rc == NGX_HTTP_... */ ngx_http_finalize_request(r, rc); @@ -1432,6 +1436,28 @@ ngx_http_update_location_config(ngx_http_request_t *r) } else if (r->connection->requests >= clcf->keepalive_requests) { r->keepalive = 0; + + } else if (r->headers_in.msie6 + && r->method == NGX_HTTP_POST + && (clcf->keepalive_disable + & NGX_HTTP_KEEPALIVE_DISABLE_MSIE6)) + { + /* + * MSIE may wait for some time if an response for + * a POST request was sent over a keepalive connection + */ + r->keepalive = 0; + + } else if (r->headers_in.safari + && (clcf->keepalive_disable + & NGX_HTTP_KEEPALIVE_DISABLE_SAFARI)) + { + /* + * Safari may send a POST request to a closed keepalive + * connection and may stall for some time, see + * https://bugs.webkit.org/show_bug.cgi?id=5760 + */ + r->keepalive = 0; } } @@ -3061,6 +3087,7 @@ ngx_http_core_create_loc_conf(ngx_conf_t *cf) clcf->client_max_body_size = NGX_CONF_UNSET; clcf->client_body_buffer_size = NGX_CONF_UNSET_SIZE; clcf->client_body_timeout = NGX_CONF_UNSET_MSEC; + clcf->keepalive_disable = NGX_CONF_UNSET_UINT; clcf->satisfy = NGX_CONF_UNSET_UINT; clcf->if_modified_since = NGX_CONF_UNSET_UINT; clcf->client_body_in_file_only = NGX_CONF_UNSET_UINT; @@ -3261,6 +3288,9 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) ngx_conf_merge_msec_value(conf->client_body_timeout, prev->client_body_timeout, 60000); + ngx_conf_merge_uint_value(conf->keepalive_disable, prev->keepalive_disable, + NGX_HTTP_KEEPALIVE_DISABLE_MSIE6 + |NGX_HTTP_KEEPALIVE_DISABLE_SAFARI); ngx_conf_merge_uint_value(conf->satisfy, prev->satisfy, NGX_HTTP_SATISFY_ALL); ngx_conf_merge_uint_value(conf->if_modified_since, prev->if_modified_since, diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h index 273586b1c..729ef9721 100644 --- a/src/http/ngx_http_core_module.h +++ b/src/http/ngx_http_core_module.h @@ -38,6 +38,11 @@ #define NGX_HTTP_IMS_BEFORE 2 +#define NGX_HTTP_KEEPALIVE_DISABLE_NONE 0x0002 +#define NGX_HTTP_KEEPALIVE_DISABLE_MSIE6 0x0004 +#define NGX_HTTP_KEEPALIVE_DISABLE_SAFARI 0x0008 + + typedef struct ngx_http_location_tree_node_s ngx_http_location_tree_node_t; typedef struct ngx_http_core_loc_conf_s ngx_http_core_loc_conf_t; @@ -349,6 +354,7 @@ struct ngx_http_core_loc_conf_s { time_t keepalive_header; /* keepalive_timeout */ ngx_uint_t keepalive_requests; /* keepalive_requests */ + ngx_uint_t keepalive_disable; /* keepalive_disable */ ngx_uint_t satisfy; /* satisfy */ ngx_uint_t if_modified_since; /* if_modified_since */ ngx_uint_t client_body_in_file_only; /* client_body_in_file_only */ diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h index ef460a488..01e2e1e51 100644 --- a/src/http/ngx_http_upstream.h +++ b/src/http/ngx_http_upstream.h @@ -53,7 +53,7 @@ typedef struct { ngx_uint_t status; time_t response_sec; ngx_uint_t response_msec; - off_t response_length; + off_t response_length; ngx_str_t *peer; } ngx_http_upstream_state_t; |
