# HG changeset patch # User Igor Sysoev # Date 1248638400 -14400 # Node ID 24b676623d4fb72bb90fc2ad251e5c3220009a11 # Parent 41f4e459ace88399b69267a727dcea99789e2a16 nginx 0.8.7 *) Change: minimum supported OpenSSL version is 0.9.7. *) Change: the "ask" parameter of the "ssl_verify_client" directive was changed to the "optional" parameter and now it checks a client certificate if it was offered. Thanks to Brice Figureau. *) Feature: the $ssl_client_verify variable. Thanks to Brice Figureau. *) Feature: the "ssl_crl" directive. Thanks to Brice Figureau. *) Feature: the "proxy" parameter of the "geo" directive. *) Feature: the "image_filter" directive supports variables for setting size. *) Bugfix: the $ssl_client_cert variable usage corrupted memory; the bug had appeared in 0.7.7. Thanks to Sergey Zhuravlev. *) Bugfix: "proxy_pass_header" and "fastcgi_pass_header" directives did not pass to a client the "X-Accel-Redirect", "X-Accel-Limit-Rate", "X-Accel-Buffering", and "X-Accel-Charset" lines from backend response header. Thanks to Maxim Dounin. *) Bugfix: in handling "Last-Modified" and "Accept-Ranges" backend response header lines; the bug had appeared in 0.7.44. Thanks to Maxim Dounin. *) Bugfix: the "[alert] zero size buf" error if subrequest returns an empty response; the bug had appeared in 0.8.5. diff --git a/CHANGES b/CHANGES --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,42 @@ +Changes with nginx 0.8.7 27 Jul 2009 + + *) Change: minimum supported OpenSSL version is 0.9.7. + + *) Change: the "ask" parameter of the "ssl_verify_client" directive was + changed to the "optional" parameter and now it checks a client + certificate if it was offered. + Thanks to Brice Figureau. + + *) Feature: the $ssl_client_verify variable. + Thanks to Brice Figureau. + + *) Feature: the "ssl_crl" directive. + Thanks to Brice Figureau. + + *) Feature: the "proxy" parameter of the "geo" directive. + + *) Feature: the "image_filter" directive supports variables for setting + size. + + *) Bugfix: the $ssl_client_cert variable usage corrupted memory; the + bug had appeared in 0.7.7. + Thanks to Sergey Zhuravlev. + + *) Bugfix: "proxy_pass_header" and "fastcgi_pass_header" directives did + not pass to a client the "X-Accel-Redirect", "X-Accel-Limit-Rate", + "X-Accel-Buffering", and "X-Accel-Charset" lines from backend + response header. + Thanks to Maxim Dounin. + + *) Bugfix: in handling "Last-Modified" and "Accept-Ranges" backend + response header lines; the bug had appeared in 0.7.44. + Thanks to Maxim Dounin. + + *) Bugfix: the "[alert] zero size buf" error if subrequest returns an + empty response; the bug had appeared in 0.8.5. + + Changes with nginx 0.8.6 20 Jul 2009 *) Feature: the ngx_http_geoip_module. @@ -8,7 +46,7 @@ Changes with nginx 0.8.6 Thanks to Kuramoto Eiji. *) Bugfix: now in MacOSX, Cygwin, and nginx/Windows locations given by - a regular expression are always tested in case insensitive mode; + a regular expression are always tested in case insensitive mode. *) Bugfix: now nginx/Windows ignores trailing dots in URI. Thanks to Hugo Leisink. diff --git a/CHANGES.ru b/CHANGES.ru --- a/CHANGES.ru +++ b/CHANGES.ru @@ -1,4 +1,42 @@ +Изменения в nginx 0.8.7 27.07.2009 + + *) Изменение: минимальная поддерживаемая версия OpenSSL - 0.9.7. + + *) Изменение: параметр ask директивы ssl_verify_client изменён на + параметр optional и теперь он проверяет клиентский сертификат, если + он был предложен. + Спасибо Brice Figureau. + + *) Добавление: переменная $ssl_client_verify. + Спасибо Brice Figureau. + + *) Добавление: директива ssl_crl. + Спасибо Brice Figureau. + + *) Добавление: параметр proxy директивы geo. + + *) Добавление: директива image_filter поддерживает переменные для + задания размеров. + + *) Исправление: использование переменной $ssl_client_cert портило + память; ошибка появилась в 0.7.7. + Спасибо Сергею Журавлёву. + + *) Исправление: директивы proxy_pass_header и fastcgi_pass_header" не + передавали клиенту строки "X-Accel-Redirect", "X-Accel-Limit-Rate", + "X-Accel-Buffering" и "X-Accel-Charset" из заголовка ответа + бэкенда. + Спасибо Максиму Дунину. + + *) Исправление: в обработке строк "Last-Modified" и "Accept-Ranges" в + заголовке ответа бэкенда; ошибка появилась в 0.7.44 + Спасибо Максиму Дунину. + + *) Исправление: ошибки "[alert] zero size buf" при получении пустых + ответы в подзапросах; ошибка появилась в 0.8.5. + + Изменения в nginx 0.8.6 20.07.2009 *) Добавление: модуль ngx_http_geoip_module. diff --git a/auto/options b/auto/options --- a/auto/options +++ b/auto/options @@ -312,7 +312,7 @@ cat << END --with-http_addition_module enable ngx_http_addition_module --with-http_xslt_module enable ngx_http_xslt_module --with-http_image_filter_module enable ngx_http_image_filter_module - --with-http_geoip_module enable ngx_http_geoip_link_module + --with-http_geoip_module enable ngx_http_geoip_module --with-http_sub_module enable ngx_http_sub_module --with-http_dav_module enable ngx_http_dav_module --with-http_flv_module enable ngx_http_flv_module 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 8006 -#define NGINX_VERSION "0.8.6" +#define nginx_version 8007 +#define NGINX_VERSION "0.8.7" #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 @@ -97,16 +97,12 @@ int ngx_ssl_session_cache_index; ngx_int_t ngx_ssl_init(ngx_log_t *log) { -#if OPENSSL_VERSION_NUMBER >= 0x00907000 OPENSSL_config(NULL); -#endif SSL_library_init(); SSL_load_error_strings(); -#if (NGX_SSL_ENGINE) ENGINE_load_builtin_engines(); -#endif ngx_ssl_connection_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); @@ -169,9 +165,7 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_ SSL_CTX_set_options(ssl->ctx, SSL_OP_TLS_D5_BUG); SSL_CTX_set_options(ssl->ctx, SSL_OP_TLS_BLOCK_PADDING_BUG); -#ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS SSL_CTX_set_options(ssl->ctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS); -#endif SSL_CTX_set_options(ssl->ctx, SSL_OP_SINGLE_DH_USE); @@ -267,6 +261,51 @@ ngx_ssl_client_certificate(ngx_conf_t *c } +ngx_int_t +ngx_ssl_crl(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *crl) +{ + X509_STORE *store; + X509_LOOKUP *lookup; + + if (crl->len == 0) { + return NGX_OK; + } + + if (ngx_conf_full_name(cf->cycle, crl, 1) != NGX_OK) { + return NGX_ERROR; + } + + store = SSL_CTX_get_cert_store(ssl->ctx); + + if (store == NULL) { + ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, + "SSL_CTX_get_cert_store() failed"); + return NGX_ERROR; + } + + lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()); + + if (lookup == NULL) { + ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, + "X509_STORE_add_lookup() failed"); + return NGX_ERROR; + } + + if (X509_LOOKUP_load_file(lookup, (char *) crl->data, X509_FILETYPE_PEM) + == 0) + { + ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, + "X509_LOOKUP_load_file(\"%s\") failed", crl->data); + return NGX_ERROR; + } + + X509_STORE_set_flags(store, + X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL); + + return NGX_OK; +} + + static int ngx_http_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store) { @@ -1201,9 +1240,7 @@ ngx_ssl_connection_error(ngx_connection_ if (err == NGX_ECONNRESET || err == NGX_EPIPE || err == NGX_ENOTCONN -#if !(NGX_CRIT_ETIMEDOUT) || err == NGX_ETIMEDOUT -#endif || err == NGX_ECONNREFUSED || err == NGX_ENETDOWN || err == NGX_ENETUNREACH @@ -1974,7 +2011,7 @@ ngx_ssl_get_certificate(ngx_connection_t p = s->data; - for (i = 0; i < len; i++) { + for (i = 0; i < cert.len - 1; i++) { *p++ = cert.data[i]; if (cert.data[i] == LF) { *p++ = '\t'; @@ -2108,6 +2145,35 @@ ngx_ssl_get_serial_number(ngx_connection } +ngx_int_t +ngx_ssl_get_client_verify(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) +{ + X509 *cert; + + if (SSL_get_verify_result(c->ssl->connection) != X509_V_OK) { + s->len = sizeof("FAILED") - 1; + s->data = (u_char *) "FAILED"; + + return NGX_OK; + } + + cert = SSL_get_peer_certificate(c->ssl->connection); + + if (cert) { + s->len = sizeof("SUCCESS") - 1; + s->data = (u_char *) "SUCCESS"; + + } else { + s->len = sizeof("NONE") - 1; + s->data = (u_char *) "NONE"; + } + + X509_free(cert); + + return NGX_OK; +} + + static void * ngx_openssl_create_conf(ngx_cycle_t *cycle) { @@ -2131,7 +2197,6 @@ ngx_openssl_create_conf(ngx_cycle_t *cyc static char * ngx_openssl_engine(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { -#if (NGX_SSL_ENGINE) ngx_openssl_conf_t *oscf = conf; ENGINE *engine; @@ -2166,23 +2231,11 @@ ngx_openssl_engine(ngx_conf_t *cf, ngx_c ENGINE_free(engine); return NGX_CONF_OK; - -#else - - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "\"ssl_engine\" directive is available only in " - "OpenSSL 0.9.7 and higher,"); - - return NGX_CONF_ERROR; - -#endif } static void ngx_openssl_exit(ngx_cycle_t *cycle) { -#if (NGX_SSL_ENGINE) ENGINE_cleanup(); -#endif } diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h --- a/src/event/ngx_event_openssl.h +++ b/src/event/ngx_event_openssl.h @@ -13,12 +13,8 @@ #include #include - -#if OPENSSL_VERSION_NUMBER >= 0x00907000 #include #include -#define NGX_SSL_ENGINE 1 -#endif #define NGX_SSL_NAME "OpenSSL" @@ -100,6 +96,7 @@ ngx_int_t ngx_ssl_certificate(ngx_conf_t ngx_str_t *cert, ngx_str_t *key); ngx_int_t ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_int_t depth); +ngx_int_t ngx_ssl_crl(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *crl); ngx_int_t ngx_ssl_generate_rsa512_key(ngx_ssl_t *ssl); ngx_int_t ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file); ngx_int_t ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx, @@ -131,6 +128,8 @@ ngx_int_t ngx_ssl_get_issuer_dn(ngx_conn ngx_str_t *s); ngx_int_t ngx_ssl_get_serial_number(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s); +ngx_int_t ngx_ssl_get_client_verify(ngx_connection_t *c, ngx_pool_t *pool, + ngx_str_t *s); ngx_int_t ngx_ssl_handshake(ngx_connection_t *c); 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 @@ -543,20 +543,17 @@ ngx_http_fastcgi_handler(ngx_http_reques return NGX_HTTP_INTERNAL_SERVER_ERROR; } + if (ngx_http_upstream_create(r) != NGX_OK) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + f = ngx_pcalloc(r->pool, sizeof(ngx_http_fastcgi_ctx_t)); if (f == NULL) { - return NGX_ERROR; + return NGX_HTTP_INTERNAL_SERVER_ERROR; } ngx_http_set_ctx(r, f, ngx_http_fastcgi_module); - u = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_t)); - if (u == NULL) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; - } - - r->upstream = u; - flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module); if (flcf->fastcgi_lengths) { @@ -565,15 +562,11 @@ ngx_http_fastcgi_handler(ngx_http_reques } } + u = r->upstream; + u->schema.len = sizeof("fastcgi://") - 1; u->schema.data = (u_char *) "fastcgi://"; - u->peer.log = r->connection->log; - u->peer.log_error = NGX_ERROR_ERR; -#if (NGX_THREADS) - u->peer.lock = &r->connection->lock; -#endif - u->output.tag = (ngx_buf_tag_t) &ngx_http_fastcgi_module; u->conf = &flcf->upstream; @@ -2438,8 +2431,13 @@ ngx_http_fastcgi_pass(ngx_conf_t *cf, ng } clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); + clcf->handler = ngx_http_fastcgi_handler; + if (clcf->name.data[clcf->name.len - 1] == '/') { + clcf->auto_redirect = 1; + } + value = cf->args->elts; url = &value[1]; @@ -2475,10 +2473,6 @@ ngx_http_fastcgi_pass(ngx_conf_t *cf, ng return NGX_CONF_ERROR; } - if (clcf->name.data[clcf->name.len - 1] == '/') { - clcf->auto_redirect = 1; - } - return NGX_CONF_OK; } diff --git a/src/http/modules/ngx_http_geo_module.c b/src/http/modules/ngx_http_geo_module.c --- a/src/http/modules/ngx_http_geo_module.c +++ b/src/http/modules/ngx_http_geo_module.c @@ -35,6 +35,7 @@ typedef struct { ngx_radix_tree_t *tree; ngx_rbtree_t rbtree; ngx_rbtree_node_t sentinel; + ngx_array_t *proxies; ngx_pool_t *pool; ngx_pool_t *temp_pool; } ngx_http_geo_conf_ctx_t; @@ -46,12 +47,16 @@ typedef struct { ngx_http_geo_high_ranges_t *high; } u; + ngx_array_t *proxies; + ngx_int_t index; } ngx_http_geo_ctx_t; static in_addr_t ngx_http_geo_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx); +static in_addr_t ngx_http_geo_real_addr(ngx_http_request_t *r, + ngx_http_geo_ctx_t *ctx); static char *ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static char *ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf); static char *ngx_http_geo_range(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx, @@ -64,6 +69,10 @@ static char *ngx_http_geo_cidr(ngx_conf_ ngx_str_t *value); static ngx_http_variable_value_t *ngx_http_geo_value(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx, ngx_str_t *value); +static char *ngx_http_geo_add_proxy(ngx_conf_t *cf, + ngx_http_geo_conf_ctx_t *ctx, ngx_cidr_t *cidr); +static ngx_int_t ngx_http_geo_cidr_value(ngx_conf_t *cf, ngx_str_t *net, + ngx_cidr_t *cidr); static ngx_command_t ngx_http_geo_commands[] = { @@ -168,6 +177,50 @@ ngx_http_geo_range_variable(ngx_http_req static in_addr_t ngx_http_geo_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx) { + u_char *p, *ip; + size_t len; + in_addr_t addr; + ngx_uint_t i, n; + ngx_in_cidr_t *proxies; + ngx_table_elt_t *xfwd; + + addr = ngx_http_geo_real_addr(r, ctx); + + xfwd = r->headers_in.x_forwarded_for; + + if (xfwd == NULL || ctx->proxies == NULL) { + return addr; + } + + proxies = ctx->proxies->elts; + n = ctx->proxies->nelts; + + for (i = 0; i < n; i++) { + if ((addr & proxies[i].mask) == proxies[i].addr) { + + len = xfwd->value.len; + ip = xfwd->value.data; + + for (p = ip + len - 1; p > ip; p--) { + if (*p == ' ' || *p == ',') { + p++; + len -= p - ip; + ip = p; + break; + } + } + + return ntohl(ngx_inet_addr(ip, len)); + } + } + + return addr; +} + + +static in_addr_t +ngx_http_geo_real_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx) +{ struct sockaddr_in *sin; ngx_http_variable_value_t *v; @@ -259,6 +312,7 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_c ctx.high = NULL; ctx.tree = NULL; + ctx.proxies = NULL; ctx.pool = cf->pool; save = *cf; @@ -271,6 +325,8 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_c *cf = save; + geo->proxies = ctx.proxies; + if (ctx.high) { for (i = 0; i < 0x10000; i++) { @@ -341,6 +397,7 @@ ngx_http_geo(ngx_conf_t *cf, ngx_command { char *rv; ngx_str_t *value, file; + ngx_cidr_t cidr; ngx_http_geo_conf_ctx_t *ctx; ctx = cf->ctx; @@ -394,6 +451,16 @@ ngx_http_geo(ngx_conf_t *cf, ngx_command rv = ngx_conf_parse(cf, &file); goto done; + + } else if (ngx_strcmp(value[0].data, "proxy") == 0) { + + if (ngx_http_geo_cidr_value(cf, &value[1], &cidr) != NGX_OK) { + goto failed; + } + + rv = ngx_http_geo_add_proxy(cf, ctx, &cidr); + + goto done; } if (ctx->high) { @@ -803,33 +870,8 @@ ngx_http_geo_cidr(ngx_conf_t *cf, ngx_ht del = 0; } - if (ngx_strcmp(net->data, "255.255.255.255") == 0) { - cidr.u.in.addr = 0xffffffff; - cidr.u.in.mask = 0xffffffff; - - } else { - rc = ngx_ptocidr(net, &cidr); - - if (rc == NGX_ERROR) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid network \"%V\"", net); - return NGX_CONF_ERROR; - } - - if (cidr.family != AF_INET) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "\"geo\" supports IPv4 only"); - return NGX_CONF_ERROR; - } - - if (rc == NGX_DONE) { - ngx_conf_log_error(NGX_LOG_WARN, cf, 0, - "low address bits of %V are meaningless", - net); - } - - cidr.u.in.addr = ntohl(cidr.u.in.addr); - cidr.u.in.mask = ntohl(cidr.u.in.mask); + if (ngx_http_geo_cidr_value(cf, net, &cidr) != NGX_OK) { + return NGX_CONF_ERROR; } if (del) { @@ -927,3 +969,64 @@ ngx_http_geo_value(ngx_conf_t *cf, ngx_h return val; } + + +static char * +ngx_http_geo_add_proxy(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx, + ngx_cidr_t *cidr) +{ + ngx_in_cidr_t *c; + + if (ctx->proxies == NULL) { + ctx->proxies = ngx_array_create(ctx->pool, 4, sizeof(ngx_in_cidr_t)); + if (ctx->proxies == NULL) { + return NGX_CONF_ERROR; + } + } + + c = ngx_array_push(ctx->proxies); + if (c == NULL) { + return NGX_CONF_ERROR; + } + + c->addr = cidr->u.in.addr; + c->mask = cidr->u.in.mask; + + return NGX_CONF_OK; +} + + +static ngx_int_t +ngx_http_geo_cidr_value(ngx_conf_t *cf, ngx_str_t *net, ngx_cidr_t *cidr) +{ + ngx_int_t rc; + + if (ngx_strcmp(net->data, "255.255.255.255") == 0) { + cidr->u.in.addr = 0xffffffff; + cidr->u.in.mask = 0xffffffff; + + return NGX_OK; + } + + rc = ngx_ptocidr(net, cidr); + + if (rc == NGX_ERROR) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid network \"%V\"", net); + return NGX_ERROR; + } + + if (cidr->family != AF_INET) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"geo\" supports IPv4 only"); + return NGX_ERROR; + } + + if (rc == NGX_DONE) { + ngx_conf_log_error(NGX_LOG_WARN, cf, 0, + "low address bits of %V are meaningless", net); + } + + cidr->u.in.addr = ntohl(cidr->u.in.addr); + cidr->u.in.mask = ntohl(cidr->u.in.mask); + + return NGX_OK; +} diff --git a/src/http/modules/ngx_http_image_filter_module.c b/src/http/modules/ngx_http_image_filter_module.c --- a/src/http/modules/ngx_http_image_filter_module.c +++ b/src/http/modules/ngx_http_image_filter_module.c @@ -40,6 +40,9 @@ typedef struct { ngx_uint_t height; ngx_int_t jpeg_quality; + ngx_http_complex_value_t *wcv; + ngx_http_complex_value_t *hcv; + size_t buffer_size; } ngx_http_image_filter_conf_t; @@ -53,6 +56,9 @@ typedef struct { ngx_uint_t width; ngx_uint_t height; + ngx_uint_t max_width; + ngx_uint_t max_height; + ngx_uint_t phase; ngx_uint_t type; } ngx_http_image_filter_ctx_t; @@ -80,6 +86,9 @@ static gdImagePtr ngx_http_image_new(ngx static u_char *ngx_http_image_out(ngx_http_request_t *r, ngx_uint_t type, gdImagePtr img, int *size); static void ngx_http_image_cleanup(void *data); +static ngx_uint_t ngx_http_image_filter_get_value(ngx_http_request_t *r, + ngx_http_complex_value_t *cv, ngx_uint_t v); +static ngx_uint_t ngx_http_image_filter_value(ngx_str_t *value); static void *ngx_http_image_filter_create_conf(ngx_conf_t *cf); @@ -454,7 +463,6 @@ ngx_http_image_read(ngx_http_request_t * static ngx_buf_t * ngx_http_image_process(ngx_http_request_t *r) { - ngx_buf_t *b; ngx_int_t rc; ngx_http_image_filter_ctx_t *ctx; ngx_http_image_filter_conf_t *conf; @@ -468,20 +476,28 @@ ngx_http_image_process(ngx_http_request_ conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module); if (conf->filter == NGX_HTTP_IMAGE_SIZE) { - - b = ngx_http_image_json(r, rc == NGX_OK ? ctx : NULL); + return ngx_http_image_json(r, rc == NGX_OK ? ctx : NULL); + } - } else if (rc == NGX_OK - && ctx->width <= conf->width - && ctx->height <= conf->height) - { - b = ngx_http_image_asis(r, ctx); - - } else { - b = ngx_http_image_resize(r, ctx); + ctx->max_width = ngx_http_image_filter_get_value(r, conf->wcv, conf->width); + if (ctx->max_width == 0) { + return NULL; } - return b; + ctx->max_height = ngx_http_image_filter_get_value(r, conf->hcv, + conf->height); + if (ctx->max_height == 0) { + return NULL; + } + + if (rc == NGX_OK + && ctx->width <= ctx->max_width + && ctx->height <= ctx->max_height) + { + return ngx_http_image_asis(r, ctx); + } + + return ngx_http_image_resize(r, ctx); } @@ -682,7 +698,9 @@ ngx_http_image_resize(ngx_http_request_t conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module); - if ((ngx_uint_t) sx <= conf->width && (ngx_uint_t) sy <= conf->height) { + if ((ngx_uint_t) sx <= ctx->max_width + && (ngx_uint_t) sy <= ctx->max_height) + { gdImageDestroy(src); return ngx_http_image_asis(r, ctx); } @@ -695,16 +713,16 @@ ngx_http_image_resize(ngx_http_request_t if (conf->filter == NGX_HTTP_IMAGE_RESIZE) { - if ((ngx_uint_t) dx > conf->width) { - dy = dy * conf->width / dx; + if ((ngx_uint_t) dx > ctx->max_width) { + dy = dy * ctx->max_width / dx; dy = dy ? dy : 1; - dx = conf->width; + dx = ctx->max_width; } - if ((ngx_uint_t) dy > conf->height) { - dx = dx * conf->height / dy; + if ((ngx_uint_t) dy > ctx->max_height) { + dx = dx * ctx->max_height / dy; dx = dx ? dx : 1; - dy = conf->height; + dy = ctx->max_height; } resize = 1; @@ -713,20 +731,21 @@ ngx_http_image_resize(ngx_http_request_t resize = 0; - if ((ngx_uint_t) (dx * 100 / dy) < conf->width * 100 / conf->height) { - - if ((ngx_uint_t) dx > conf->width) { - dy = dy * conf->width / dx; + if ((ngx_uint_t) (dx * 100 / dy) + < ctx->max_width * 100 / ctx->max_height) + { + if ((ngx_uint_t) dx > ctx->max_width) { + dy = dy * ctx->max_width / dx; dy = dy ? dy : 1; - dx = conf->width; + dx = ctx->max_width; resize = 1; } } else { - if ((ngx_uint_t) dy > conf->height) { - dx = dx * conf->height / dy; + if ((ngx_uint_t) dy > ctx->max_height) { + dx = dx * ctx->max_height / dy; dx = dx ? dx : 1; - dy = conf->height; + dy = ctx->max_height; resize = 1; } } @@ -751,15 +770,15 @@ ngx_http_image_resize(ngx_http_request_t src = dst; - if ((ngx_uint_t) dx > conf->width) { - ox = dx - conf->width; + if ((ngx_uint_t) dx > ctx->max_width) { + ox = dx - ctx->max_width; } else { ox = 0; } - if ((ngx_uint_t) dy > conf->height) { - oy = dy - conf->height; + if ((ngx_uint_t) dy > ctx->max_height) { + oy = dy - ctx->max_height; } else { oy = 0; @@ -941,6 +960,43 @@ ngx_http_image_cleanup(void *data) } +static ngx_uint_t +ngx_http_image_filter_get_value(ngx_http_request_t *r, + ngx_http_complex_value_t *cv, ngx_uint_t v) +{ + ngx_str_t val; + + if (cv == NULL) { + return v; + } + + if (ngx_http_complex_value(r, cv, &val) != NGX_OK) { + return 0; + } + + return ngx_http_image_filter_value(&val); +} + + +static ngx_uint_t +ngx_http_image_filter_value(ngx_str_t *value) +{ + ngx_int_t n; + + if (value->len == 1 && value->data[0] == '-') { + return (ngx_uint_t) -1; + } + + n = ngx_atoi(value->data, value->len); + + if (n > 0) { + return (ngx_uint_t) n; + } + + return 0; +} + + static void * ngx_http_image_filter_create_conf(ngx_conf_t *cf) { @@ -974,6 +1030,8 @@ ngx_http_image_filter_merge_conf(ngx_con conf->filter = prev->filter; conf->width = prev->width; conf->height = prev->height; + conf->wcv = prev->wcv; + conf->hcv = prev->hcv; } } @@ -992,9 +1050,11 @@ ngx_http_image_filter(ngx_conf_t *cf, ng { ngx_http_image_filter_conf_t *imcf = conf; - ngx_str_t *value; - ngx_int_t n; - ngx_uint_t i; + ngx_str_t *value; + ngx_int_t n; + ngx_uint_t i; + ngx_http_complex_value_t cv; + ngx_http_compile_complex_value_t ccv; value = cf->args->elts; @@ -1027,32 +1087,60 @@ ngx_http_image_filter(ngx_conf_t *cf, ng goto failed; } - i++; + ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); + + ccv.cf = cf; + ccv.value = &value[++i]; + ccv.complex_value = &cv; - if (value[i].len == 1 && value[i].data[0] == '-') { - imcf->width = (ngx_uint_t) -1; + if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { + return NGX_CONF_ERROR; + } - } else { - n = ngx_atoi(value[i].data, value[i].len); - if (n == NGX_ERROR) { + if (cv.lengths == NULL) { + n = ngx_http_image_filter_value(&value[i]); + + if (n == 0) { goto failed; } imcf->width = (ngx_uint_t) n; + + } else { + imcf->wcv = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t)); + if (imcf->wcv == NULL) { + return NGX_CONF_ERROR; + } + + *imcf->wcv = cv; } - i++; + ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); + + ccv.cf = cf; + ccv.value = &value[++i]; + ccv.complex_value = &cv; - if (value[i].len == 1 && value[i].data[0] == '-') { - imcf->height = (ngx_uint_t) -1; + if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { + return NGX_CONF_ERROR; + } - } else { - n = ngx_atoi(value[i].data, value[i].len); - if (n == NGX_ERROR) { + if (cv.lengths == NULL) { + n = ngx_http_image_filter_value(&value[i]); + + if (n == 0) { goto failed; } imcf->height = (ngx_uint_t) n; + + } else { + imcf->hcv = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t)); + if (imcf->hcv == NULL) { + return NGX_CONF_ERROR; + } + + *imcf->hcv = cv; } return NGX_CONF_OK; diff --git a/src/http/modules/ngx_http_memcached_module.c b/src/http/modules/ngx_http_memcached_module.c --- a/src/http/modules/ngx_http_memcached_module.c +++ b/src/http/modules/ngx_http_memcached_module.c @@ -176,23 +176,18 @@ ngx_http_memcached_handler(ngx_http_requ return NGX_HTTP_INTERNAL_SERVER_ERROR; } - mlcf = ngx_http_get_module_loc_conf(r, ngx_http_memcached_module); - - u = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_t)); - if (u == NULL) { + if (ngx_http_upstream_create(r) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } + u = r->upstream; + u->schema.len = sizeof("memcached://") - 1; u->schema.data = (u_char *) "memcached://"; - u->peer.log = r->connection->log; - u->peer.log_error = NGX_ERROR_ERR; -#if (NGX_THREADS) - u->peer.lock = &r->connection->lock; -#endif + u->output.tag = (ngx_buf_tag_t) &ngx_http_memcached_module; - u->output.tag = (ngx_buf_tag_t) &ngx_http_memcached_module; + mlcf = ngx_http_get_module_loc_conf(r, ngx_http_memcached_module); u->conf = &mlcf->upstream; @@ -202,8 +197,6 @@ ngx_http_memcached_handler(ngx_http_requ u->abort_request = ngx_http_memcached_abort_request; u->finalize_request = ngx_http_memcached_finalize_request; - r->upstream = u; - ctx = ngx_palloc(r->pool, sizeof(ngx_http_memcached_ctx_t)); if (ctx == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; 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 @@ -590,13 +590,10 @@ ngx_http_proxy_handler(ngx_http_request_ ngx_http_proxy_ctx_t *ctx; ngx_http_proxy_loc_conf_t *plcf; - u = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_t)); - if (u == NULL) { + if (ngx_http_upstream_create(r) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } - r->upstream = u; - ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_proxy_ctx_t)); if (ctx == NULL) { return NGX_ERROR; @@ -606,6 +603,8 @@ ngx_http_proxy_handler(ngx_http_request_ plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module); + u = r->upstream; + if (plcf->proxy_lengths == 0) { ctx->vars = plcf->vars; u->schema = plcf->vars.schema; @@ -619,12 +618,6 @@ ngx_http_proxy_handler(ngx_http_request_ } } - u->peer.log = r->connection->log; - u->peer.log_error = NGX_ERROR_ERR; -#if (NGX_THREADS) - u->peer.lock = &r->connection->lock; -#endif - u->output.tag = (ngx_buf_tag_t) &ngx_http_proxy_module; u->conf = &plcf->upstream; @@ -2592,6 +2585,12 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_ clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); + clcf->handler = ngx_http_proxy_handler; + + if (clcf->name.data[clcf->name.len - 1] == '/') { + clcf->auto_redirect = 1; + } + value = cf->args->elts; url = &value[1]; @@ -2620,8 +2619,6 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_ } #endif - clcf->handler = ngx_http_proxy_handler; - return NGX_CONF_OK; } @@ -2668,8 +2665,6 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_ ngx_http_proxy_set_vars(&u, &plcf->vars); - clcf->handler = ngx_http_proxy_handler; - plcf->location = clcf->name; if (clcf->named @@ -2693,10 +2688,6 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_ plcf->url = *url; - if (clcf->name.data[clcf->name.len - 1] == '/') { - clcf->auto_redirect = 1; - } - return NGX_CONF_OK; } 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 @@ -568,7 +568,7 @@ ngx_http_rewrite_if(ngx_conf_t *cf, ngx_ if_code = ngx_array_push_n(lcf->codes, sizeof(ngx_http_script_if_code_t)); if (if_code == NULL) { - return NULL; + return NGX_CONF_ERROR; } if_code->code = ngx_http_script_if_code; diff --git a/src/http/modules/ngx_http_ssi_filter_module.c b/src/http/modules/ngx_http_ssi_filter_module.c --- a/src/http/modules/ngx_http_ssi_filter_module.c +++ b/src/http/modules/ngx_http_ssi_filter_module.c @@ -360,6 +360,7 @@ ngx_http_ssi_header_filter(ngx_http_requ if (r == r->main) { ngx_http_clear_content_length(r); ngx_http_clear_last_modified(r); + ngx_http_clear_accept_ranges(r); } return ngx_http_next_header_filter(r); diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c --- a/src/http/modules/ngx_http_ssl_module.c +++ b/src/http/modules/ngx_http_ssl_module.c @@ -31,15 +31,6 @@ static char *ngx_http_ssl_enable(ngx_con static char *ngx_http_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); -#if !defined (SSL_OP_CIPHER_SERVER_PREFERENCE) - -static char *ngx_http_ssl_nosupported(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); - -static char ngx_http_ssl_openssl097[] = "OpenSSL 0.9.7 and higher"; - -#endif - static ngx_conf_bitmask_t ngx_http_ssl_protocols[] = { { ngx_string("SSLv2"), NGX_SSL_SSLv2 }, @@ -52,7 +43,7 @@ static ngx_conf_bitmask_t ngx_http_ssl_ static ngx_conf_enum_t ngx_http_ssl_verify[] = { { ngx_string("off"), 0 }, { ngx_string("on"), 1 }, - { ngx_string("ask"), 2 }, + { ngx_string("optional"), 2 }, { ngx_null_string, 0 } }; @@ -124,14 +115,10 @@ static ngx_command_t ngx_http_ssl_comma { ngx_string("ssl_prefer_server_ciphers"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG, -#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE ngx_conf_set_flag_slot, NGX_HTTP_SRV_CONF_OFFSET, offsetof(ngx_http_ssl_srv_conf_t, prefer_server_ciphers), NULL }, -#else - ngx_http_ssl_nosupported, 0, 0, ngx_http_ssl_openssl097 }, -#endif { ngx_string("ssl_session_cache"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE12, @@ -147,6 +134,13 @@ static ngx_command_t ngx_http_ssl_comma offsetof(ngx_http_ssl_srv_conf_t, session_timeout), NULL }, + { ngx_string("ssl_crl"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, + ngx_conf_set_str_slot, + NGX_HTTP_SRV_CONF_OFFSET, + offsetof(ngx_http_ssl_srv_conf_t, crl), + NULL }, + ngx_null_command }; @@ -206,6 +200,9 @@ static ngx_http_variable_t ngx_http_ssl { ngx_string("ssl_client_serial"), NULL, ngx_http_ssl_variable, (uintptr_t) ngx_ssl_get_serial_number, NGX_HTTP_VAR_CHANGEABLE, 0 }, + { ngx_string("ssl_client_verify"), NULL, ngx_http_ssl_variable, + (uintptr_t) ngx_ssl_get_client_verify, NGX_HTTP_VAR_CHANGEABLE, 0 }, + { ngx_null_string, NULL, NULL, 0, 0, 0 } }; @@ -313,6 +310,7 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t * sscf->certificate_key = { 0, NULL }; * sscf->dhparam = { 0, NULL }; * sscf->client_certificate = { 0, NULL }; + * sscf->crl = { 0, NULL }; * sscf->ciphers.len = 0; * sscf->ciphers.data = NULL; * sscf->shm_zone = NULL; @@ -359,6 +357,7 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t * ngx_conf_merge_str_value(conf->client_certificate, prev->client_certificate, ""); + ngx_conf_merge_str_value(conf->crl, prev->crl, ""); ngx_conf_merge_str_value(conf->ciphers, prev->ciphers, NGX_DEFAULT_CIPHERS); @@ -453,16 +452,16 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t * { return NGX_CONF_ERROR; } + + if (ngx_ssl_crl(cf, &conf->ssl, &conf->crl) != NGX_OK) { + return NGX_CONF_ERROR; + } } -#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE - if (conf->prefer_server_ciphers) { SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); } -#endif - /* a temporary 512-bit RSA key is required for export versions of MSIE */ if (ngx_ssl_generate_rsa512_key(&conf->ssl) != NGX_OK) { return NGX_CONF_ERROR; @@ -620,18 +619,3 @@ invalid: return NGX_CONF_ERROR; } - - -#if !defined (SSL_OP_CIPHER_SERVER_PREFERENCE) - -static char * -ngx_http_ssl_nosupported(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) -{ - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "\"%V\" directive is available only in %s,", - &cmd->name, cmd->post); - - return NGX_CONF_ERROR; -} - -#endif diff --git a/src/http/modules/ngx_http_ssl_module.h b/src/http/modules/ngx_http_ssl_module.h --- a/src/http/modules/ngx_http_ssl_module.h +++ b/src/http/modules/ngx_http_ssl_module.h @@ -33,6 +33,7 @@ typedef struct { ngx_str_t certificate_key; ngx_str_t dhparam; ngx_str_t client_certificate; + ngx_str_t crl; ngx_str_t ciphers; diff --git a/src/http/modules/ngx_http_xslt_filter_module.c b/src/http/modules/ngx_http_xslt_filter_module.c --- a/src/http/modules/ngx_http_xslt_filter_module.c +++ b/src/http/modules/ngx_http_xslt_filter_module.c @@ -720,7 +720,7 @@ ngx_http_xslt_sax_error(void *data, cons while (--n && (buf[n] == CR || buf[n] == LF)) { /* void */ } ngx_log_error(NGX_LOG_ERR, ctx->request->connection->log, 0, - "libxml2 error: \"%*s\"", n, buf); + "libxml2 error: \"%*s\"", n + 1, buf); } 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.8.6'; +our $VERSION = '0.8.7'; require XSLoader; XSLoader::load('nginx', $VERSION); 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 @@ -950,9 +950,6 @@ ngx_http_parse_complex_uri(ngx_http_requ sw_slash, sw_dot, sw_dot_dot, -#if (NGX_WIN32) - sw_dot_dot_dot, -#endif sw_quoted, sw_quoted_second } state, quoted_state; @@ -1154,12 +1151,6 @@ ngx_http_parse_complex_uri(ngx_http_requ goto args; case '#': goto done; -#if (NGX_WIN32) - case '.': - state = sw_dot_dot_dot; - *u++ = ch; - break; -#endif case '+': r->plus_in_uri = 1; default: @@ -1171,55 +1162,6 @@ ngx_http_parse_complex_uri(ngx_http_requ ch = *p++; break; -#if (NGX_WIN32) - case sw_dot_dot_dot: - - if (usual[ch >> 5] & (1 << (ch & 0x1f))) { - state = sw_usual; - *u++ = ch; - ch = *p++; - break; - } - - switch(ch) { - case '\\': - case '/': - state = sw_slash; - u -= 5; - if (u < r->uri.data) { - return NGX_HTTP_PARSE_INVALID_REQUEST; - } - while (*u != '/') { - u--; - } - if (u < r->uri.data) { - return NGX_HTTP_PARSE_INVALID_REQUEST; - } - while (*(u - 1) != '/') { - u--; - } - break; - case '%': - quoted_state = state; - state = sw_quoted; - break; - case '?': - r->args_start = p; - goto args; - case '#': - goto done; - case '+': - r->plus_in_uri = 1; - default: - state = sw_usual; - *u++ = ch; - break; - } - - ch = *p++; - break; -#endif - case sw_quoted: r->quoted_uri = 1; @@ -1369,20 +1311,6 @@ ngx_http_parse_unsafe_uri(ngx_http_reque if (p[0] == '.' && p[1] == '.' && ngx_path_separator(p[2])) { goto unsafe; } - -#if (NGX_WIN32) - - if (len > 3) { - - /* detect "/.../" */ - - if (p[0] == '.' && p[1] == '.' && p[2] == '.' - && ngx_path_separator(p[3])) - { - goto unsafe; - } - } -#endif } } 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 @@ -129,7 +129,7 @@ ngx_http_header_t ngx_http_headers_in[] { ngx_string("Keep-Alive"), offsetof(ngx_http_headers_in_t, keep_alive), ngx_http_process_header_line }, -#if (NGX_HTTP_PROXY || NGX_HTTP_REALIP) +#if (NGX_HTTP_PROXY || NGX_HTTP_REALIP || NGX_HTTP_GEO) { ngx_string("X-Forwarded-For"), offsetof(ngx_http_headers_in_t, x_forwarded_for), ngx_http_process_header_line }, @@ -384,6 +384,7 @@ ngx_http_init_request(ngx_event_t *rev) r->loc_conf = cscf->ctx->loc_conf; rev->handler = ngx_http_process_request_line; + r->read_event_handler = ngx_http_block_reading; #if (NGX_HTTP_SSL) @@ -1524,7 +1525,7 @@ ngx_http_process_request(ngx_http_reques sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module); - if (sscf->verify == 1) { + if (sscf->verify) { rc = SSL_get_verify_result(c->ssl->connection); if (rc != X509_V_OK) { @@ -1539,20 +1540,22 @@ ngx_http_process_request(ngx_http_reques return; } - cert = SSL_get_peer_certificate(c->ssl->connection); - - if (cert == NULL) { - ngx_log_error(NGX_LOG_INFO, c->log, 0, - "client sent no required SSL certificate"); - - ngx_ssl_remove_cached_session(sscf->ssl.ctx, + if (sscf->verify == 1) { + cert = SSL_get_peer_certificate(c->ssl->connection); + + if (cert == NULL) { + ngx_log_error(NGX_LOG_INFO, c->log, 0, + "client sent no required SSL certificate"); + + ngx_ssl_remove_cached_session(sscf->ssl.ctx, (SSL_get0_session(c->ssl->connection))); - ngx_http_finalize_request(r, NGX_HTTPS_NO_CERT); - return; + ngx_http_finalize_request(r, NGX_HTTPS_NO_CERT); + return; + } + + X509_free(cert); } - - X509_free(cert); } } @@ -2715,6 +2718,7 @@ ngx_http_send_special(ngx_http_request_t b->last_buf = 1; } else { + b->sync = 1; b->last_in_chain = 1; } } 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 @@ -184,7 +184,7 @@ typedef struct { ngx_table_elt_t *keep_alive; -#if (NGX_HTTP_PROXY || NGX_HTTP_REALIP) +#if (NGX_HTTP_PROXY || NGX_HTTP_REALIP || NGX_HTTP_GEO) ngx_table_elt_t *x_forwarded_for; #endif 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 @@ -224,19 +224,19 @@ ngx_http_upstream_header_t ngx_http_ups { ngx_string("X-Accel-Redirect"), ngx_http_upstream_process_header_line, offsetof(ngx_http_upstream_headers_in_t, x_accel_redirect), - ngx_http_upstream_ignore_header_line, 0, 0 }, + ngx_http_upstream_copy_header_line, 0, 0 }, { ngx_string("X-Accel-Limit-Rate"), ngx_http_upstream_process_limit_rate, 0, - ngx_http_upstream_ignore_header_line, 0, 0 }, + ngx_http_upstream_copy_header_line, 0, 0 }, { ngx_string("X-Accel-Buffering"), ngx_http_upstream_process_buffering, 0, - ngx_http_upstream_ignore_header_line, 0, 0 }, + ngx_http_upstream_copy_header_line, 0, 0 }, { ngx_string("X-Accel-Charset"), ngx_http_upstream_process_charset, 0, - ngx_http_upstream_ignore_header_line, 0, 0 }, + ngx_http_upstream_copy_header_line, 0, 0 }, #if (NGX_HTTP_GZIP) { ngx_string("Content-Encoding"), @@ -348,6 +348,35 @@ ngx_conf_bitmask_t ngx_http_upstream_ca }; +ngx_int_t +ngx_http_upstream_create(ngx_http_request_t *r) +{ + ngx_http_upstream_t *u; + + u = r->upstream; + + if (u && u->cleanup) { + ngx_http_upstream_cleanup(r); + *u->cleanup = NULL; + } + + u = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_t)); + if (u == NULL) { + return NGX_ERROR; + } + + r->upstream = u; + + u->peer.log = r->connection->log; + u->peer.log_error = NGX_ERROR_ERR; +#if (NGX_THREADS) + u->peer.lock = &r->connection->lock; +#endif + + return NGX_OK; +} + + void ngx_http_upstream_init(ngx_http_request_t *r) { @@ -3301,10 +3330,11 @@ ngx_http_upstream_copy_last_modified(ngx *ho = *h; + r->headers_out.last_modified = ho; + #if (NGX_HTTP_CACHE) if (r->upstream->cacheable) { - r->headers_out.last_modified = ho; r->headers_out.last_modified_time = ngx_http_parse_time(h->value.data, h->value.len); } @@ -3428,6 +3458,8 @@ ngx_http_upstream_copy_allow_ranges(ngx_ *ho = *h; + r->headers_out.accept_ranges = ho; + return NGX_OK; } diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h --- a/src/http/ngx_http_upstream.h +++ b/src/http/ngx_http_upstream.h @@ -317,6 +317,7 @@ typedef struct { ngx_int_t ngx_http_upstream_header_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); +ngx_int_t ngx_http_upstream_create(ngx_http_request_t *r); void ngx_http_upstream_init(ngx_http_request_t *r); ngx_http_upstream_srv_conf_t *ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags); diff --git a/src/mail/ngx_mail_ssl_module.c b/src/mail/ngx_mail_ssl_module.c --- a/src/mail/ngx_mail_ssl_module.c +++ b/src/mail/ngx_mail_ssl_module.c @@ -22,15 +22,6 @@ static char *ngx_mail_ssl_starttls(ngx_c static char *ngx_mail_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); -#if !defined (SSL_OP_CIPHER_SERVER_PREFERENCE) - -static char *ngx_mail_ssl_nosupported(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); - -static char ngx_mail_ssl_openssl097[] = "OpenSSL 0.9.7 and higher"; - -#endif - static ngx_conf_enum_t ngx_http_starttls_state[] = { { ngx_string("off"), NGX_MAIL_STARTTLS_OFF }, @@ -102,14 +93,10 @@ static ngx_command_t ngx_mail_ssl_comma { ngx_string("ssl_prefer_server_ciphers"), NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG, -#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE ngx_conf_set_flag_slot, NGX_MAIL_SRV_CONF_OFFSET, offsetof(ngx_mail_ssl_conf_t, prefer_server_ciphers), NULL }, -#else - ngx_mail_ssl_nosupported, 0, 0, ngx_mail_ssl_openssl097 }, -#endif { ngx_string("ssl_session_cache"), NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE12, @@ -297,14 +284,10 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, } } -#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE - if (conf->prefer_server_ciphers) { SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); } -#endif - if (ngx_ssl_generate_rsa512_key(&conf->ssl) != NGX_OK) { return NGX_CONF_ERROR; } @@ -492,18 +475,3 @@ invalid: return NGX_CONF_ERROR; } - - -#if !defined (SSL_OP_CIPHER_SERVER_PREFERENCE) - -static char * -ngx_mail_ssl_nosupported(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) -{ - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "\"%V\" directive is available only in %s,", - &cmd->name, cmd->post); - - return NGX_CONF_ERROR; -} - -#endif