diff options
author | Robert Nagy <robert@cvs.openbsd.org> | 2012-07-07 16:01:49 +0000 |
---|---|---|
committer | Robert Nagy <robert@cvs.openbsd.org> | 2012-07-07 16:01:49 +0000 |
commit | e1ed4ee6ef44c1dfb042327336a494dbbc9acc8b (patch) | |
tree | 803018c9917f41405cba7cead6b57495df82cc4e /usr.sbin | |
parent | 69f390c8fc881100a77e71328187534dc813f397 (diff) |
update to 1.2.2 and start using /var/www/cache instead of /var/www/tmp
Diffstat (limited to 'usr.sbin')
40 files changed, 860 insertions, 153 deletions
diff --git a/usr.sbin/nginx/CHANGES b/usr.sbin/nginx/CHANGES index 20954221640..f113116b2a3 100644 --- a/usr.sbin/nginx/CHANGES +++ b/usr.sbin/nginx/CHANGES @@ -1,4 +1,64 @@ +Changes with nginx 1.2.2 03 Jul 2012 + + *) Change: the "single" parameter of the "keepalive" directive is now + ignored. + + *) Change: SSL compression is now disabled when using all versions of + OpenSSL, including ones prior to 1.0.0. + + *) Feature: the "proxy_pass", "fastcgi_pass", "scgi_pass", "uwsgi_pass" + directives, and the "server" directive inside the "upstream" block, + now support IPv6 addresses. + + *) Feature: the "resolver" directive now support IPv6 addresses and an + optional port specification. + + *) Feature: the "least_conn" directive inside the "upstream" block. + + *) Feature: it is now possible to specify a weight for servers while + using the "ip_hash" directive. + + *) Feature: it is now possible to use the "ip_hash" directive to balance + IPv6 clients. + + *) Feature: the $status variable can now be used not only in the + "log_format" directive. + + *) Bugfix: nginx could not be built with ngx_cpp_test_module; the bug + had appeared in 1.1.12. + + *) Bugfix: access to variables from SSI and embedded perl module might + not work after reconfiguration. + Thanks to Yichun Zhang. + + *) Bugfix: in the ngx_http_xslt_filter_module. + Thanks to Kuramoto Eiji. + + *) Bugfix: memory leak if $geoip_org variable was used. + Thanks to Denis F. Latypoff. + + *) Bugfix: in the "proxy_cookie_domain" and "proxy_cookie_path" + directives. + + *) Bugfix: a segmentation fault might occur in a worker process on + shutdown if the "resolver" directive was used. + + *) Bugfix: a segmentation fault might occur in a worker process if the + ngx_http_mp4_module was used. + + *) Bugfix: in the ngx_http_mp4_module. + + *) Bugfix: a segmentation fault might occur in a worker process if + conflicting wildcard server names were used. + + *) Bugfix: nginx might be terminated abnormally on a SIGBUS signal on + ARM platform. + + *) Bugfix: an alert "sendmsg() failed (9: Bad file number)" on HP-UX + while reconfiguration. + + Changes with nginx 1.2.1 05 Jun 2012 *) Security: now nginx/Windows ignores trailing dot in URI path diff --git a/usr.sbin/nginx/CHANGES.ru b/usr.sbin/nginx/CHANGES.ru index 63ac53e3c5e..5ae0817b539 100644 --- a/usr.sbin/nginx/CHANGES.ru +++ b/usr.sbin/nginx/CHANGES.ru @@ -1,4 +1,61 @@ +Изменения в nginx 1.2.2 03.07.2012 + + *) Изменение: параметр single директивы keepalive теперь игнорируется. + + *) Изменение: сжатие SSL теперь отключено в том числе при использовании + OpenSSL cтарее 1.0.0. + + *) Добавление: директивы proxy_pass, fastcgi_pass, scgi_pass, uwsgi_pass + и директива server в блоке upstream теперь поддерживают IPv6-адреса. + + *) Добавление: в директиве resolver теперь можно указывать порт и + задавать IPv6-адреса DNS-серверов. + + *) Добавление: директива least_conn в блоке upstream. + + *) Добавление: при использовании директивы ip_hash теперь можно задавать + веса серверов. + + *) Добавление: директиву "ip_hash" теперь можно использовать для + балансировки IPv6 клиентов. + + *) Добавление: переменную $status теперь можно использовать не только в + директиве log_format. + + *) Исправление: nginx не собирался с модулем ngx_cpp_test_module; ошибка + появилась в 1.1.12. + + *) Исправление: доступ к переменным из SSI и встроенного перла мог не + работать после переконфигурации. + Спасибо Yichun Zhang. + + *) Исправление: в модуле ngx_http_xslt_filter_module. + Спасибо Kuramoto Eiji. + + *) Исправление: утечки памяти при использовании переменной $geoip_org. + Спасибо Денису Латыпову. + + *) Исправление: в директивах proxy_cookie_domain и proxy_cookie_path. + + *) Исправление: при завершении рабочего процесса мог произойти + segmentation fault, если использовалась директива resolver. + + *) Исправление: в рабочем процессе мог произойти segmentation fault, + если использовался модуль ngx_http_mp4_module. + + *) Исправление: в модуле ngx_http_mp4_module. + + *) Исправление: в рабочем процессе мог произойти segmentation fault, + если использовались конфликтующие имена серверов с масками. + + *) Исправление: на платформе ARM nginx мог аварийно завершаться по + сигналу SIGBUS. + + *) Исправление: во время переконфигурации на HP-UX в лог записывался + alert "sendmsg() failed (9: Bad file number)". + + Изменения в nginx 1.2.1 05.06.2012 *) Безопасность: теперь nginx/Windows игнорирует точку в конце diff --git a/usr.sbin/nginx/Makefile.bsd-wrapper b/usr.sbin/nginx/Makefile.bsd-wrapper index 8c740c62560..60c9de7ff82 100644 --- a/usr.sbin/nginx/Makefile.bsd-wrapper +++ b/usr.sbin/nginx/Makefile.bsd-wrapper @@ -1,5 +1,5 @@ # Build wrapper for Nginx -# $OpenBSD: Makefile.bsd-wrapper,v 1.6 2012/06/26 10:03:41 robert Exp $ +# $OpenBSD: Makefile.bsd-wrapper,v 1.7 2012/07/07 16:01:48 robert Exp $ LNDIR= /usr/bin/lndir @@ -16,11 +16,11 @@ CONFIGURE_ARGS= --prefix=/var/www \ --lock-path=/var/run/nginx.lock \ --http-log-path=logs/access.log \ --error-log-path=logs/error.log \ - --http-client-body-temp-path=/var/www/tmp/client_body_temp \ - --http-proxy-temp-path=/var/www/tmp/proxy_temp \ - --http-fastcgi-temp-path=/var/www/tmp/fastcgi_temp \ - --http-scgi-temp-path=/var/www/tmp/scgi_temp \ - --http-uwsgi-temp-path=/var/www/tmp/uwsgi_temp \ + --http-client-body-temp-path=/var/www/cache/client_body_temp \ + --http-proxy-temp-path=/var/www/cache/proxy_temp \ + --http-fastcgi-temp-path=/var/www/cache/fastcgi_temp \ + --http-scgi-temp-path=/var/www/cache/scgi_temp \ + --http-uwsgi-temp-path=/var/www/cache/uwsgi_temp \ --user=www \ --group=www \ --with-http_gzip_static_module \ diff --git a/usr.sbin/nginx/auto/endianess b/usr.sbin/nginx/auto/endianness index 452dd7c1268..87311a0f16e 100644 --- a/usr.sbin/nginx/auto/endianess +++ b/usr.sbin/nginx/auto/endianness @@ -3,9 +3,9 @@ # Copyright (C) Nginx, Inc. -echo $ngx_n "checking for system endianess ...$ngx_c" +echo $ngx_n "checking for system byte ordering ...$ngx_c" echo >> $NGX_ERR -echo "checking for system endianess" >> $NGX_ERR +echo "checking for system byte ordering" >> $NGX_ERR cat << END > $NGX_AUTOTEST.c @@ -28,10 +28,10 @@ eval "$ngx_test >> $NGX_AUTOCONF_ERR 2>&1" if [ -x $NGX_AUTOTEST ]; then if $NGX_AUTOTEST >/dev/null 2>&1; then - echo " little endianess" + echo " little endian" have=NGX_HAVE_LITTLE_ENDIAN . auto/have else - echo " big endianess" + echo " big endian" fi rm $NGX_AUTOTEST* @@ -40,6 +40,6 @@ else rm $NGX_AUTOTEST* echo - echo "$0: error: can not detect system endianess" + echo "$0: error: cannot detect system byte ordering" exit 1 fi diff --git a/usr.sbin/nginx/auto/lib/google-perftools/conf b/usr.sbin/nginx/auto/lib/google-perftools/conf index 398ddd05e02..7a9de30020b 100644 --- a/usr.sbin/nginx/auto/lib/google-perftools/conf +++ b/usr.sbin/nginx/auto/lib/google-perftools/conf @@ -29,6 +29,22 @@ if [ $ngx_found = no ]; then fi +if [ $ngx_found = no ]; then + + # MacPorts + + ngx_feature="Google perftools in /opt/local/" + + if [ $NGX_RPATH = YES ]; then + ngx_feature_libs="-R/opt/local/lib -L/opt/local/lib -lprofiler" + else + ngx_feature_libs="-L/opt/local/lib -lprofiler" + fi + + . auto/feature +fi + + if [ $ngx_found = yes ]; then CORE_LIBS="$CORE_LIBS $ngx_feature_libs" diff --git a/usr.sbin/nginx/auto/modules b/usr.sbin/nginx/auto/modules index dab660f8733..d872c4e392c 100644 --- a/usr.sbin/nginx/auto/modules +++ b/usr.sbin/nginx/auto/modules @@ -223,6 +223,7 @@ fi if [ $HTTP_REALIP = YES ]; then have=NGX_HTTP_REALIP . auto/have + have=NGX_HTTP_X_FORWARDED_FOR . auto/have HTTP_MODULES="$HTTP_MODULES $HTTP_REALIP_MODULE" HTTP_SRCS="$HTTP_SRCS $HTTP_REALIP_SRCS" fi @@ -234,11 +235,13 @@ fi if [ $HTTP_GEO = YES ]; then have=NGX_HTTP_GEO . auto/have + have=NGX_HTTP_X_FORWARDED_FOR . auto/have HTTP_MODULES="$HTTP_MODULES $HTTP_GEO_MODULE" HTTP_SRCS="$HTTP_SRCS $HTTP_GEO_SRCS" fi if [ $HTTP_GEOIP = YES ]; then + have=NGX_HTTP_X_FORWARDED_FOR . auto/have HTTP_MODULES="$HTTP_MODULES $HTTP_GEOIP_MODULE" HTTP_SRCS="$HTTP_SRCS $HTTP_GEOIP_SRCS" fi @@ -274,6 +277,7 @@ fi if [ $HTTP_PROXY = YES ]; then have=NGX_HTTP_PROXY . auto/have + have=NGX_HTTP_X_FORWARDED_FOR . auto/have #USE_MD5=YES HTTP_MODULES="$HTTP_MODULES $HTTP_PROXY_MODULE" HTTP_DEPS="$HTTP_DEPS $HTTP_PROXY_DEPS" @@ -345,6 +349,11 @@ if [ $HTTP_UPSTREAM_IP_HASH = YES ]; then HTTP_SRCS="$HTTP_SRCS $HTTP_UPSTREAM_IP_HASH_SRCS" fi +if [ $HTTP_UPSTREAM_LEAST_CONN = YES ]; then + HTTP_MODULES="$HTTP_MODULES $HTTP_UPSTREAM_LEAST_CONN_MODULE" + HTTP_SRCS="$HTTP_SRCS $HTTP_UPSTREAM_LEAST_CONN_SRCS" +fi + if [ $HTTP_UPSTREAM_KEEPALIVE = YES ]; then HTTP_MODULES="$HTTP_MODULES $HTTP_UPSTREAM_KEEPALIVE_MODULE" HTTP_SRCS="$HTTP_SRCS $HTTP_UPSTREAM_KEEPALIVE_SRCS" @@ -458,6 +467,7 @@ fi if [ $NGX_CPP_TEST = YES ]; then NGX_MISC_SRCS="$NGX_MISC_SRCS $NGX_CPP_TEST_SRCS" + CORE_LIBS="$CORE_LIBS -lstdc++" fi diff --git a/usr.sbin/nginx/auto/options b/usr.sbin/nginx/auto/options index 393be406616..11f23c6d64c 100644 --- a/usr.sbin/nginx/auto/options +++ b/usr.sbin/nginx/auto/options @@ -96,6 +96,7 @@ HTTP_FLV=NO HTTP_MP4=NO HTTP_GZIP_STATIC=NO HTTP_UPSTREAM_IP_HASH=YES +HTTP_UPSTREAM_LEAST_CONN=YES HTTP_UPSTREAM_KEEPALIVE=YES # STUB @@ -243,6 +244,8 @@ use the \"--without-http_limit_conn_module\" option instead" --without-http_empty_gif_module) HTTP_EMPTY_GIF=NO ;; --without-http_browser_module) HTTP_BROWSER=NO ;; --without-http_upstream_ip_hash_module) HTTP_UPSTREAM_IP_HASH=NO ;; + --without-http_upstream_least_conn_module) + HTTP_UPSTREAM_LEAST_CONN=NO ;; --without-http_upstream_keepalive_module) HTTP_UPSTREAM_KEEPALIVE=NO ;; --with-http_perl_module) HTTP_PERL=YES ;; diff --git a/usr.sbin/nginx/auto/os/conf b/usr.sbin/nginx/auto/os/conf index 8c18a63fc4b..fe720160ada 100644 --- a/usr.sbin/nginx/auto/os/conf +++ b/usr.sbin/nginx/auto/os/conf @@ -48,6 +48,7 @@ case "$NGX_PLATFORM" in CORE_DEPS="$UNIX_DEPS $POSIX_DEPS" CORE_SRCS="$UNIX_SRCS" CC_AUX_FLAGS="$CC_AUX_FLAGS -D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED=1" + CC_AUX_FLAGS="$CC_AUX_FLAGS -D_HPUX_ALT_XOPEN_SOCKET_API" ;; OSF1:*) @@ -93,6 +94,7 @@ case "$NGX_MACHINE" in ;; *) + have=NGX_ALIGNMENT value=16 . auto/define NGX_MACH_CACHE_LINE=32 ;; diff --git a/usr.sbin/nginx/auto/sources b/usr.sbin/nginx/auto/sources index d95f3badffe..7a1b4adcf6e 100644 --- a/usr.sbin/nginx/auto/sources +++ b/usr.sbin/nginx/auto/sources @@ -491,6 +491,11 @@ HTTP_UPSTREAM_IP_HASH_MODULE=ngx_http_upstream_ip_hash_module HTTP_UPSTREAM_IP_HASH_SRCS=src/http/modules/ngx_http_upstream_ip_hash_module.c +HTTP_UPSTREAM_LEAST_CONN_MODULE=ngx_http_upstream_least_conn_module +HTTP_UPSTREAM_LEAST_CONN_SRCS=" \ + src/http/modules/ngx_http_upstream_least_conn_module.c" + + HTTP_UPSTREAM_KEEPALIVE_MODULE=ngx_http_upstream_keepalive_module HTTP_UPSTREAM_KEEPALIVE_SRCS=" \ src/http/modules/ngx_http_upstream_keepalive_module.c" diff --git a/usr.sbin/nginx/auto/unix b/usr.sbin/nginx/auto/unix index 783219e2db7..b0a0e4c8895 100755 --- a/usr.sbin/nginx/auto/unix +++ b/usr.sbin/nginx/auto/unix @@ -464,7 +464,7 @@ ngx_type="rlim_t"; ngx_types="int"; . auto/types/typedef . auto/types/uintptr_t -. auto/endianess +. auto/endianness ngx_type="size_t"; . auto/types/sizeof ngx_param=NGX_MAX_SIZE_T_VALUE; ngx_value=$ngx_max_value; . auto/types/value diff --git a/usr.sbin/nginx/src/core/nginx.h b/usr.sbin/nginx/src/core/nginx.h index df7ab91e6e1..8d626b52a29 100644 --- a/usr.sbin/nginx/src/core/nginx.h +++ b/usr.sbin/nginx/src/core/nginx.h @@ -9,8 +9,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 1002001 -#define NGINX_VERSION "1.2.1" +#define nginx_version 1002002 +#define NGINX_VERSION "1.2.2" #define NGINX_VER "nginx/" NGINX_VERSION #define NGINX_VAR "NGINX" diff --git a/usr.sbin/nginx/src/core/ngx_hash.c b/usr.sbin/nginx/src/core/ngx_hash.c index 7d04f7484f9..b532945027c 100644 --- a/usr.sbin/nginx/src/core/ngx_hash.c +++ b/usr.sbin/nginx/src/core/ngx_hash.c @@ -924,17 +924,6 @@ wildcard: } - hk = ngx_array_push(hwc); - if (hk == NULL) { - return NGX_ERROR; - } - - hk->key.len = last - 1; - hk->key.data = p; - hk->key_hash = 0; - hk->value = value; - - /* check conflicts in wildcard hash */ name = keys->elts; @@ -972,5 +961,18 @@ wildcard: ngx_memcpy(name->data, key->data + skip, name->len); + + /* add to wildcard hash */ + + hk = ngx_array_push(hwc); + if (hk == NULL) { + return NGX_ERROR; + } + + hk->key.len = last - 1; + hk->key.data = p; + hk->key_hash = 0; + hk->value = value; + return NGX_OK; } diff --git a/usr.sbin/nginx/src/core/ngx_inet.c b/usr.sbin/nginx/src/core/ngx_inet.c index d2bbbfb58bb..3db0136e5d6 100644 --- a/usr.sbin/nginx/src/core/ngx_inet.c +++ b/usr.sbin/nginx/src/core/ngx_inet.c @@ -522,11 +522,6 @@ ngx_parse_url(ngx_pool_t *pool, ngx_url_t *u) return ngx_parse_unix_domain_url(pool, u); } - if ((p[0] == ':' || p[0] == '/') && !u->listen) { - u->err = "invalid host"; - return NGX_ERROR; - } - if (p[0] == '[') { return ngx_parse_inet6_url(pool, u); } @@ -639,10 +634,7 @@ ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u) args = ngx_strlchr(host, last, '?'); if (args) { - if (uri == NULL) { - uri = args; - - } else if (args < uri) { + if (uri == NULL || args < uri) { uri = args; } } @@ -668,11 +660,6 @@ ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u) len = last - port; - if (len == 0) { - u->err = "invalid port"; - return NGX_ERROR; - } - n = ngx_atoi(port, len); if (n < 1 || n > 65535) { @@ -779,11 +766,7 @@ ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u) return NGX_OK; } - if (ngx_inet_resolve_host(pool, u) != NGX_OK) { - return NGX_ERROR; - } - - return NGX_OK; + return ngx_inet_resolve_host(pool, u); } @@ -825,6 +808,8 @@ ngx_parse_inet6_url(ngx_pool_t *pool, ngx_url_t *u) u->uri.len = last - uri; u->uri.data = uri; + + last = uri; } if (*port == ':') { @@ -832,11 +817,6 @@ ngx_parse_inet6_url(ngx_pool_t *pool, ngx_url_t *u) len = last - port; - if (len == 0) { - u->err = "invalid port"; - return NGX_ERROR; - } - n = ngx_atoi(port, len); if (n < 1 || n > 65535) { @@ -862,8 +842,8 @@ ngx_parse_inet6_url(ngx_pool_t *pool, ngx_url_t *u) return NGX_ERROR; } - u->host.len = len; - u->host.data = host; + u->host.len = len + 2; + u->host.data = host - 1; if (ngx_inet6_addr(host, len, sin6->sin6_addr.s6_addr) != NGX_OK) { u->err = "invalid IPv6 address"; @@ -874,17 +854,38 @@ ngx_parse_inet6_url(ngx_pool_t *pool, ngx_url_t *u) u->wildcard = 1; } + if (u->no_port) { + u->port = u->default_port; + sin6->sin6_port = htons(u->default_port); + } + u->family = AF_INET6; + u->naddrs = 1; - if (u->no_resolve) { - return NGX_OK; + u->addrs = ngx_pcalloc(pool, sizeof(ngx_addr_t)); + if (u->addrs == NULL) { + return NGX_ERROR; } - if (u->no_port) { - u->port = u->default_port; - sin6->sin6_port = htons(u->default_port); + sin6 = ngx_pcalloc(pool, sizeof(struct sockaddr_in6)); + if (sin6 == NULL) { + return NGX_ERROR; } + ngx_memcpy(sin6, u->sockaddr, sizeof(struct sockaddr_in6)); + + u->addrs[0].sockaddr = (struct sockaddr *) sin6; + u->addrs[0].socklen = sizeof(struct sockaddr_in6); + + p = ngx_pnalloc(pool, u->host.len + sizeof(":65535") - 1); + if (p == NULL) { + return NGX_ERROR; + } + + u->addrs[0].name.len = ngx_sprintf(p, "%V:%d", + &u->host, u->port) - p; + u->addrs[0].name.data = p; + return NGX_OK; #else diff --git a/usr.sbin/nginx/src/core/ngx_regex.c b/usr.sbin/nginx/src/core/ngx_regex.c index 677f862bf17..3771aab8ee7 100644 --- a/usr.sbin/nginx/src/core/ngx_regex.c +++ b/usr.sbin/nginx/src/core/ngx_regex.c @@ -152,7 +152,7 @@ ngx_regex_compile(ngx_regex_compile_t *rc) return NGX_ERROR; } - rc->regex->pcre = re; + rc->regex->code = re; /* do not study at runtime */ @@ -367,7 +367,7 @@ ngx_regex_module_init(ngx_cycle_t *cycle) i = 0; } - elts[i].regex->extra = pcre_study(elts[i].regex->pcre, opt, &errstr); + elts[i].regex->extra = pcre_study(elts[i].regex->code, opt, &errstr); if (errstr != NULL) { ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, @@ -380,7 +380,7 @@ ngx_regex_module_init(ngx_cycle_t *cycle) int jit, n; jit = 0; - n = pcre_fullinfo(elts[i].regex->pcre, elts[i].regex->extra, + n = pcre_fullinfo(elts[i].regex->code, elts[i].regex->extra, PCRE_INFO_JIT, &jit); if (n != 0 || jit != 1) { diff --git a/usr.sbin/nginx/src/core/ngx_regex.h b/usr.sbin/nginx/src/core/ngx_regex.h index 55bd331bb69..680486c816f 100644 --- a/usr.sbin/nginx/src/core/ngx_regex.h +++ b/usr.sbin/nginx/src/core/ngx_regex.h @@ -21,7 +21,7 @@ typedef struct { - pcre *pcre; + pcre *code; pcre_extra *extra; } ngx_regex_t; @@ -50,7 +50,7 @@ void ngx_regex_init(void); ngx_int_t ngx_regex_compile(ngx_regex_compile_t *rc); #define ngx_regex_exec(re, s, captures, size) \ - pcre_exec(re->pcre, re->extra, (const char *) (s)->data, (s)->len, 0, 0, \ + pcre_exec(re->code, re->extra, (const char *) (s)->data, (s)->len, 0, 0, \ captures, size) #define ngx_regex_exec_n "pcre_exec()" diff --git a/usr.sbin/nginx/src/core/ngx_resolver.c b/usr.sbin/nginx/src/core/ngx_resolver.c index edc43dce219..3e75e05a378 100644 --- a/usr.sbin/nginx/src/core/ngx_resolver.c +++ b/usr.sbin/nginx/src/core/ngx_resolver.c @@ -96,7 +96,7 @@ ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names, ngx_uint_t n) { ngx_str_t s; ngx_url_t u; - ngx_uint_t i; + ngx_uint_t i, j; ngx_resolver_t *r; ngx_pool_cleanup_t *cln; ngx_udp_connection_t *uc; @@ -171,24 +171,31 @@ ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names, ngx_uint_t n) ngx_memzero(&u, sizeof(ngx_url_t)); - u.host = names[i]; - u.port = 53; + u.url = names[i]; + u.default_port = 53; + + if (ngx_parse_url(cf->pool, &u) != NGX_OK) { + if (u.err) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "%s in resolver \"%V\"", + u.err, &u.url); + } - if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V: %s", &u.host, u.err); return NULL; } - uc = ngx_array_push(&r->udp_connections); + uc = ngx_array_push_n(&r->udp_connections, u.naddrs); if (uc == NULL) { return NULL; } - ngx_memzero(uc, sizeof(ngx_udp_connection_t)); + ngx_memzero(uc, u.naddrs * sizeof(ngx_udp_connection_t)); - uc->sockaddr = u.addrs->sockaddr; - uc->socklen = u.addrs->socklen; - uc->server = u.addrs->name; + for (j = 0; j < u.naddrs; j++) { + uc[j].sockaddr = u.addrs[j].sockaddr; + uc[j].socklen = u.addrs[j].socklen; + uc[j].server = u.addrs[j].name; + } } return r; @@ -972,12 +979,11 @@ ngx_resolver_resend(ngx_resolver_t *r, ngx_rbtree_t *tree, ngx_queue_t *queue) if (rn->waiting) { - if (ngx_resolver_send_query(r, rn) == NGX_OK) { + (void) ngx_resolver_send_query(r, rn); - rn->expire = now + r->resend_timeout; + rn->expire = now + r->resend_timeout; - ngx_queue_insert_head(queue, &rn->queue); - } + ngx_queue_insert_head(queue, q); continue; } @@ -1035,7 +1041,7 @@ ngx_resolver_process_response(ngx_resolver_t *r, u_char *buf, size_t n) nan = (query->nan_hi << 8) + query->nan_lo; ngx_log_debug6(NGX_LOG_DEBUG_CORE, r->log, 0, - "resolver DNS response %ui fl:%04Xui %ui/%ui/%ui/%ui", + "resolver DNS response %ui fl:%04Xui %ui/%ui/%ud/%ud", ident, flags, nqs, nan, (query->nns_hi << 8) + query->nns_lo, (query->nar_hi << 8) + query->nar_lo); @@ -2184,7 +2190,7 @@ ngx_udp_connect(ngx_udp_connection_t *uc) ngx_socket_t s; ngx_connection_t *c; - s = ngx_socket(AF_INET, SOCK_DGRAM, 0); + s = ngx_socket(uc->sockaddr->sa_family, SOCK_DGRAM, 0); ngx_log_debug1(NGX_LOG_DEBUG_EVENT, &uc->log, 0, "UDP socket %d", s); diff --git a/usr.sbin/nginx/src/event/ngx_event_openssl.c b/usr.sbin/nginx/src/event/ngx_event_openssl.c index 7903eb64c6e..4356a05ef66 100644 --- a/usr.sbin/nginx/src/event/ngx_event_openssl.c +++ b/usr.sbin/nginx/src/event/ngx_event_openssl.c @@ -94,6 +94,24 @@ ngx_ssl_init(ngx_log_t *log) OpenSSL_add_all_algorithms(); +#ifndef SSL_OP_NO_COMPRESSION + { + /* + * Disable gzip compression in OpenSSL prior to 1.0.0 version, + * this saves about 522K per connection. + */ + int i, n; + STACK_OF(SSL_COMP) *ssl_comp_methods; + + ssl_comp_methods = SSL_COMP_get_compression_methods(); + n = sk_SSL_COMP_num(ssl_comp_methods); + + for (i = 0; i < n; i++) { + (void) sk_SSL_COMP_delete(ssl_comp_methods, i); + } + } +#endif + ngx_ssl_connection_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); if (ngx_ssl_connection_index == -1) { @@ -990,7 +1008,6 @@ ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit) } if (n == NGX_AGAIN) { - c->buffered |= NGX_SSL_BUFFERED; return in; } diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_geo_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_geo_module.c index e792cdb6655..189d8ed508f 100644 --- a/usr.sbin/nginx/src/http/modules/ngx_http_geo_module.c +++ b/usr.sbin/nginx/src/http/modules/ngx_http_geo_module.c @@ -145,7 +145,7 @@ typedef struct { u_char GEORNG[6]; u_char version; u_char ptr_size; - uint32_t endianess; + uint32_t endianness; uint32_t crc32; } ngx_http_geo_header_t; diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_geoip_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_geoip_module.c index abc79cdfeeb..0ce3bf1e59b 100644 --- a/usr.sbin/nginx/src/http/modules/ngx_http_geoip_module.c +++ b/usr.sbin/nginx/src/http/modules/ngx_http_geoip_module.c @@ -28,7 +28,7 @@ typedef struct { } ngx_http_geoip_var_t; -typedef const char *(*ngx_http_geoip_variable_handler_pt)(GeoIP *, u_long addr); +typedef char *(*ngx_http_geoip_variable_handler_pt)(GeoIP *, u_long addr); static u_long ngx_http_geoip_addr(ngx_http_request_t *r, ngx_http_geoip_conf_t *gcf); @@ -291,7 +291,8 @@ ngx_http_geoip_org_variable(ngx_http_request_t *r, ngx_http_geoip_variable_handler_pt handler = (ngx_http_geoip_variable_handler_pt) data; - const char *val; + size_t len; + char *val; ngx_http_geoip_conf_t *gcf; gcf = ngx_http_get_module_main_conf(r, ngx_http_geoip_module); @@ -306,11 +307,21 @@ ngx_http_geoip_org_variable(ngx_http_request_t *r, goto not_found; } - v->len = ngx_strlen(val); + len = ngx_strlen(val); + v->data = ngx_pnalloc(r->pool, len); + if (v->data == NULL) { + ngx_free(val); + return NGX_ERROR; + } + + ngx_memcpy(v->data, val, len); + + v->len = len; v->valid = 1; v->no_cacheable = 0; v->not_found = 0; - v->data = (u_char *) val; + + ngx_free(val); return NGX_OK; diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_log_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_log_module.c index 2d412853bd9..edb145992a6 100644 --- a/usr.sbin/nginx/src/http/modules/ngx_http_log_module.c +++ b/usr.sbin/nginx/src/http/modules/ngx_http_log_module.c @@ -205,7 +205,7 @@ static ngx_http_log_var_t ngx_http_log_vars[] = { { ngx_string("msec"), NGX_TIME_T_LEN + 4, ngx_http_log_msec }, { ngx_string("request_time"), NGX_TIME_T_LEN + 4, ngx_http_log_request_time }, - { ngx_string("status"), 3, ngx_http_log_status }, + { ngx_string("status"), NGX_INT_T_LEN, ngx_http_log_status }, { ngx_string("bytes_sent"), NGX_OFF_T_LEN, ngx_http_log_bytes_sent }, { ngx_string("body_bytes_sent"), NGX_OFF_T_LEN, ngx_http_log_body_bytes_sent }, @@ -584,16 +584,13 @@ ngx_http_log_status(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op) status = r->headers_out.status; } else if (r->http_version == NGX_HTTP_VERSION_9) { - *buf++ = '0'; - *buf++ = '0'; - *buf++ = '9'; - return buf; + status = 9; } else { status = 0; } - return ngx_sprintf(buf, "%ui", status); + return ngx_sprintf(buf, "%03ui", status); } diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_mp4_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_mp4_module.c index 2c8cfd171ad..d3be23420e6 100644 --- a/usr.sbin/nginx/src/http/modules/ngx_http_mp4_module.c +++ b/usr.sbin/nginx/src/http/modules/ngx_http_mp4_module.c @@ -1024,6 +1024,10 @@ ngx_http_mp4_read_moov_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) + NGX_HTTP_MP4_MOOV_BUFFER_EXCESS * no_mdat; } + if (ngx_http_mp4_read(mp4, (size_t) atom_data_size) != NGX_OK) { + return NGX_ERROR; + } + mp4->trak.elts = &mp4->traks; mp4->trak.size = sizeof(ngx_http_mp4_trak_t); mp4->trak.nalloc = 2; @@ -1044,6 +1048,12 @@ ngx_http_mp4_read_moov_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) mp4->buffer_start = mp4->buffer_pos; mp4->buffer_size = NGX_HTTP_MP4_MOOV_BUFFER_EXCESS; + if (mp4->buffer_start + mp4->buffer_size > mp4->buffer_end) { + mp4->buffer = NULL; + mp4->buffer_pos = NULL; + mp4->buffer_end = NULL; + } + } else { /* skip atoms after moov atom */ mp4->offset = mp4->end; @@ -2488,7 +2498,13 @@ found: ngx_mp4_set_32value(entry->chunk, 1); - if (trak->chunk_samples) { + if (trak->chunk_samples && next_chunk - trak->start_chunk == 2) { + + /* last chunk in the entry */ + + ngx_mp4_set_32value(entry->samples, samples - trak->chunk_samples); + + } else if (trak->chunk_samples) { first = &trak->stsc_chunk_entry; ngx_mp4_set_32value(first->chunk, 1); @@ -2504,6 +2520,7 @@ found: ngx_mp4_set_32value(entry->chunk, 2); + entries++; atom_size += sizeof(ngx_mp4_stsc_entry_t); } diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_rewrite_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_rewrite_module.c index 74d26e524f4..4081f877433 100644 --- a/usr.sbin/nginx/src/http/modules/ngx_http_rewrite_module.c +++ b/usr.sbin/nginx/src/http/modules/ngx_http_rewrite_module.c @@ -485,6 +485,12 @@ ngx_http_rewrite_return(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) } else { + if (ret->status > 999) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid return code \"%V\"", &value[1]); + return NGX_CONF_ERROR; + } + if (cf->args->nelts == 2) { return NGX_CONF_OK; } diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_split_clients_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_split_clients_module.c index 726269c3c73..33a2fe73ee7 100644 --- a/usr.sbin/nginx/src/http/modules/ngx_http_split_clients_module.c +++ b/usr.sbin/nginx/src/http/modules/ngx_http_split_clients_module.c @@ -138,6 +138,13 @@ ngx_conf_split_clients_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) } name = value[2]; + + if (name.len < 2 || name.data[0] != '$') { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid variable name \"%V\"", &name); + return NGX_CONF_ERROR; + } + name.len--; name.data++; diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_upstream_ip_hash_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_upstream_ip_hash_module.c index 100ea34dd04..89ccc2b858f 100644 --- a/usr.sbin/nginx/src/http/modules/ngx_http_upstream_ip_hash_module.c +++ b/usr.sbin/nginx/src/http/modules/ngx_http_upstream_ip_hash_module.c @@ -16,7 +16,8 @@ typedef struct { ngx_uint_t hash; - u_char addr[3]; + u_char addrlen; + u_char *addr; u_char tries; @@ -76,7 +77,10 @@ ngx_module_t ngx_http_upstream_ip_hash_module = { }; -ngx_int_t +static u_char ngx_http_upstream_ip_hash_pseudo_addr[3]; + + +static ngx_int_t ngx_http_upstream_init_ip_hash(ngx_conf_t *cf, ngx_http_upstream_srv_conf_t *us) { if (ngx_http_upstream_init_round_robin(cf, us) != NGX_OK) { @@ -93,8 +97,10 @@ static ngx_int_t ngx_http_upstream_init_ip_hash_peer(ngx_http_request_t *r, ngx_http_upstream_srv_conf_t *us) { - u_char *p; struct sockaddr_in *sin; +#if (NGX_HAVE_INET6) + struct sockaddr_in6 *sin6; +#endif ngx_http_upstream_ip_hash_peer_data_t *iphp; iphp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_ip_hash_peer_data_t)); @@ -110,20 +116,25 @@ ngx_http_upstream_init_ip_hash_peer(ngx_http_request_t *r, r->upstream->peer.get = ngx_http_upstream_get_ip_hash_peer; - /* AF_INET only */ - - if (r->connection->sockaddr->sa_family == AF_INET) { + switch (r->connection->sockaddr->sa_family) { + case AF_INET: sin = (struct sockaddr_in *) r->connection->sockaddr; - p = (u_char *) &sin->sin_addr.s_addr; - iphp->addr[0] = p[0]; - iphp->addr[1] = p[1]; - iphp->addr[2] = p[2]; - - } else { - iphp->addr[0] = 0; - iphp->addr[1] = 0; - iphp->addr[2] = 0; + iphp->addr = (u_char *) &sin->sin_addr.s_addr; + iphp->addrlen = 3; + break; + +#if (NGX_HAVE_INET6) + case AF_INET6: + sin6 = (struct sockaddr_in6 *) r->connection->sockaddr; + iphp->addr = (u_char *) &sin6->sin6_addr.s6_addr; + iphp->addrlen = 16; + break; +#endif + + default: + iphp->addr = ngx_http_upstream_ip_hash_pseudo_addr; + iphp->addrlen = 3; } iphp->hash = 89; @@ -140,6 +151,7 @@ ngx_http_upstream_get_ip_hash_peer(ngx_peer_connection_t *pc, void *data) ngx_http_upstream_ip_hash_peer_data_t *iphp = data; time_t now; + ngx_int_t w; uintptr_t m; ngx_uint_t i, n, p, hash; ngx_http_upstream_rr_peer_t *peer; @@ -162,11 +174,25 @@ ngx_http_upstream_get_ip_hash_peer(ngx_peer_connection_t *pc, void *data) for ( ;; ) { - for (i = 0; i < 3; i++) { + for (i = 0; i < iphp->addrlen; i++) { hash = (hash * 113 + iphp->addr[i]) % 6271; } - p = hash % iphp->rrp.peers->number; + if (!iphp->rrp.peers->weighted) { + p = hash % iphp->rrp.peers->number; + + } else { + w = hash % iphp->rrp.peers->total_weight; + + for (i = 0; i < iphp->rrp.peers->number; i++) { + w -= iphp->rrp.peers->peer[i].weight; + if (w < 0) { + break; + } + } + + p = i; + } n = p / (8 * sizeof(uintptr_t)); m = (uintptr_t) 1 << p % (8 * sizeof(uintptr_t)); @@ -229,6 +255,7 @@ ngx_http_upstream_ip_hash(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) uscf->peer.init_upstream = ngx_http_upstream_init_ip_hash; uscf->flags = NGX_HTTP_UPSTREAM_CREATE + |NGX_HTTP_UPSTREAM_WEIGHT |NGX_HTTP_UPSTREAM_MAX_FAILS |NGX_HTTP_UPSTREAM_FAIL_TIMEOUT |NGX_HTTP_UPSTREAM_DOWN; diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_upstream_keepalive_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_upstream_keepalive_module.c index 6fd9ac70a34..d10e3d016cb 100644 --- a/usr.sbin/nginx/src/http/modules/ngx_http_upstream_keepalive_module.c +++ b/usr.sbin/nginx/src/http/modules/ngx_http_upstream_keepalive_module.c @@ -12,7 +12,6 @@ typedef struct { ngx_uint_t max_cached; - ngx_uint_t single; /* unsigned:1 */ ngx_queue_t cache; ngx_queue_t free; @@ -223,36 +222,11 @@ ngx_http_upstream_get_keepalive_peer(ngx_peer_connection_t *pc, void *data) kp->failed = 0; - /* single pool of cached connections */ - - if (kp->conf->single && !ngx_queue_empty(&kp->conf->cache)) { - - q = ngx_queue_head(&kp->conf->cache); - - item = ngx_queue_data(q, ngx_http_upstream_keepalive_cache_t, queue); - c = item->connection; - - ngx_queue_remove(q); - ngx_queue_insert_head(&kp->conf->free, q); - - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0, - "get keepalive peer: using connection %p", c); - - c->idle = 0; - c->log = pc->log; - c->read->log = pc->log; - c->write->log = pc->log; - c->pool->log = pc->log; - - pc->connection = c; - pc->cached = 1; - - return NGX_DONE; - } + /* ask balancer */ rc = kp->original_get_peer(pc, kp->data); - if (kp->conf->single || rc != NGX_OK) { + if (rc != NGX_OK) { return rc; } @@ -552,7 +526,8 @@ ngx_http_upstream_keepalive(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) for (i = 2; i < cf->args->nelts; i++) { if (ngx_strcmp(value[i].data, "single") == 0) { - kcf->single = 1; + ngx_conf_log_error(NGX_LOG_WARN, cf, 0, + "the \"single\" parameter is deprecated"); continue; } diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_upstream_least_conn_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_upstream_least_conn_module.c new file mode 100644 index 00000000000..50e68b21b90 --- /dev/null +++ b/usr.sbin/nginx/src/http/modules/ngx_http_upstream_least_conn_module.c @@ -0,0 +1,402 @@ + +/* + * Copyright (C) Maxim Dounin + * Copyright (C) Nginx, Inc. + */ + + +#include <ngx_config.h> +#include <ngx_core.h> +#include <ngx_http.h> + + +typedef struct { + ngx_uint_t *conns; +} ngx_http_upstream_least_conn_conf_t; + + +typedef struct { + /* the round robin data must be first */ + ngx_http_upstream_rr_peer_data_t rrp; + + ngx_uint_t *conns; + + ngx_event_get_peer_pt get_rr_peer; + ngx_event_free_peer_pt free_rr_peer; +} ngx_http_upstream_lc_peer_data_t; + + +static ngx_int_t ngx_http_upstream_init_least_conn_peer(ngx_http_request_t *r, + ngx_http_upstream_srv_conf_t *us); +static ngx_int_t ngx_http_upstream_get_least_conn_peer( + ngx_peer_connection_t *pc, void *data); +static void ngx_http_upstream_free_least_conn_peer(ngx_peer_connection_t *pc, + void *data, ngx_uint_t state); +static void *ngx_http_upstream_least_conn_create_conf(ngx_conf_t *cf); +static char *ngx_http_upstream_least_conn(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf); + + +static ngx_command_t ngx_http_upstream_least_conn_commands[] = { + + { ngx_string("least_conn"), + NGX_HTTP_UPS_CONF|NGX_CONF_NOARGS, + ngx_http_upstream_least_conn, + 0, + 0, + NULL }, + + ngx_null_command +}; + + +static ngx_http_module_t ngx_http_upstream_least_conn_module_ctx = { + NULL, /* preconfiguration */ + NULL, /* postconfiguration */ + + NULL, /* create main configuration */ + NULL, /* init main configuration */ + + ngx_http_upstream_least_conn_create_conf, /* create server configuration */ + NULL, /* merge server configuration */ + + NULL, /* create location configuration */ + NULL /* merge location configuration */ +}; + + +ngx_module_t ngx_http_upstream_least_conn_module = { + NGX_MODULE_V1, + &ngx_http_upstream_least_conn_module_ctx, /* module context */ + ngx_http_upstream_least_conn_commands, /* module directives */ + NGX_HTTP_MODULE, /* module type */ + NULL, /* init master */ + NULL, /* init module */ + NULL, /* init process */ + NULL, /* init thread */ + NULL, /* exit thread */ + NULL, /* exit process */ + NULL, /* exit master */ + NGX_MODULE_V1_PADDING +}; + + +ngx_int_t +ngx_http_upstream_init_least_conn(ngx_conf_t *cf, + ngx_http_upstream_srv_conf_t *us) +{ + ngx_uint_t n; + ngx_http_upstream_rr_peers_t *peers; + ngx_http_upstream_least_conn_conf_t *lcf; + + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cf->log, 0, + "init least conn"); + + if (ngx_http_upstream_init_round_robin(cf, us) != NGX_OK) { + return NGX_ERROR; + } + + peers = us->peer.data; + + n = peers->number; + + if (peers->next) { + n += peers->next->number; + } + + lcf = ngx_http_conf_upstream_srv_conf(us, + ngx_http_upstream_least_conn_module); + + lcf->conns = ngx_pcalloc(cf->pool, sizeof(ngx_uint_t) * n); + if (lcf->conns == NULL) { + return NGX_ERROR; + } + + us->peer.init = ngx_http_upstream_init_least_conn_peer; + + return NGX_OK; +} + + +static ngx_int_t +ngx_http_upstream_init_least_conn_peer(ngx_http_request_t *r, + ngx_http_upstream_srv_conf_t *us) +{ + ngx_http_upstream_lc_peer_data_t *lcp; + ngx_http_upstream_least_conn_conf_t *lcf; + + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "init least conn peer"); + + lcf = ngx_http_conf_upstream_srv_conf(us, + ngx_http_upstream_least_conn_module); + + lcp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_lc_peer_data_t)); + if (lcp == NULL) { + return NGX_ERROR; + } + + lcp->conns = lcf->conns; + + r->upstream->peer.data = &lcp->rrp; + + if (ngx_http_upstream_init_round_robin_peer(r, us) != NGX_OK) { + return NGX_ERROR; + } + + r->upstream->peer.get = ngx_http_upstream_get_least_conn_peer; + r->upstream->peer.free = ngx_http_upstream_free_least_conn_peer; + + lcp->get_rr_peer = ngx_http_upstream_get_round_robin_peer; + lcp->free_rr_peer = ngx_http_upstream_free_round_robin_peer; + + return NGX_OK; +} + + +static ngx_int_t +ngx_http_upstream_get_least_conn_peer(ngx_peer_connection_t *pc, void *data) +{ + ngx_http_upstream_lc_peer_data_t *lcp = data; + + time_t now; + uintptr_t m; + ngx_int_t rc, total; + ngx_uint_t i, n, p, many; + ngx_http_upstream_rr_peer_t *peer, *best; + ngx_http_upstream_rr_peers_t *peers; + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0, + "get least conn peer, try: %ui", pc->tries); + + if (lcp->rrp.peers->single) { + return lcp->get_rr_peer(pc, &lcp->rrp); + } + + pc->cached = 0; + pc->connection = NULL; + + now = ngx_time(); + + peers = lcp->rrp.peers; + + best = NULL; + total = 0; + +#if (NGX_SUPPRESS_WARN) + many = 0; + p = 0; +#endif + + for (i = 0; i < peers->number; i++) { + + n = i / (8 * sizeof(uintptr_t)); + m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t)); + + if (lcp->rrp.tried[n] & m) { + continue; + } + + peer = &peers->peer[i]; + + if (peer->down) { + continue; + } + + if (peer->max_fails + && peer->fails >= peer->max_fails + && now - peer->checked <= peer->fail_timeout) + { + continue; + } + + /* + * select peer with least number of connections; if there are + * multiple peers with the same number of connections, select + * based on round-robin + */ + + if (best == NULL + || lcp->conns[i] * best->weight < lcp->conns[p] * peer->weight) + { + best = peer; + many = 0; + p = i; + + } else if (lcp->conns[i] * best->weight + == lcp->conns[p] * peer->weight) + { + many = 1; + } + } + + if (best == NULL) { + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0, + "get least conn peer, no peer found"); + + goto failed; + } + + if (many) { + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0, + "get least conn peer, many"); + + for (i = p; i < peers->number; i++) { + + n = i / (8 * sizeof(uintptr_t)); + m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t)); + + if (lcp->rrp.tried[n] & m) { + continue; + } + + peer = &peers->peer[i]; + + if (peer->down) { + continue; + } + + if (lcp->conns[i] * best->weight != lcp->conns[p] * peer->weight) { + continue; + } + + if (peer->max_fails + && peer->fails >= peer->max_fails + && now - peer->checked <= peer->fail_timeout) + { + continue; + } + + peer->current_weight += peer->effective_weight; + total += peer->effective_weight; + + if (peer->effective_weight < peer->weight) { + peer->effective_weight++; + } + + if (peer->current_weight > best->current_weight) { + best = peer; + p = i; + } + } + } + + best->current_weight -= total; + best->checked = now; + + pc->sockaddr = best->sockaddr; + pc->socklen = best->socklen; + pc->name = &best->name; + + lcp->rrp.current = p; + + n = p / (8 * sizeof(uintptr_t)); + m = (uintptr_t) 1 << p % (8 * sizeof(uintptr_t)); + + lcp->rrp.tried[n] |= m; + lcp->conns[p]++; + + if (pc->tries == 1 && peers->next) { + pc->tries += peers->next->number; + } + + return NGX_OK; + +failed: + + if (peers->next) { + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0, + "get least conn peer, backup servers"); + + lcp->conns += peers->number; + + lcp->rrp.peers = peers->next; + pc->tries = lcp->rrp.peers->number; + + n = lcp->rrp.peers->number / (8 * sizeof(uintptr_t)) + 1; + for (i = 0; i < n; i++) { + lcp->rrp.tried[i] = 0; + } + + rc = ngx_http_upstream_get_least_conn_peer(pc, lcp); + + if (rc != NGX_BUSY) { + return rc; + } + } + + /* all peers failed, mark them as live for quick recovery */ + + for (i = 0; i < peers->number; i++) { + peers->peer[i].fails = 0; + } + + pc->name = peers->name; + + return NGX_BUSY; +} + + +static void +ngx_http_upstream_free_least_conn_peer(ngx_peer_connection_t *pc, + void *data, ngx_uint_t state) +{ + ngx_http_upstream_lc_peer_data_t *lcp = data; + + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, + "free least conn peer %ui %ui", pc->tries, state); + + if (lcp->rrp.peers->single) { + lcp->free_rr_peer(pc, &lcp->rrp, state); + return; + } + + if (state == 0 && pc->tries == 0) { + return; + } + + lcp->conns[lcp->rrp.current]--; + + lcp->free_rr_peer(pc, &lcp->rrp, state); +} + + +static void * +ngx_http_upstream_least_conn_create_conf(ngx_conf_t *cf) +{ + ngx_http_upstream_least_conn_conf_t *conf; + + conf = ngx_pcalloc(cf->pool, + sizeof(ngx_http_upstream_least_conn_conf_t)); + if (conf == NULL) { + return NULL; + } + + /* + * set by ngx_pcalloc(): + * + * conf->conns = NULL; + */ + + return conf; +} + + +static char * +ngx_http_upstream_least_conn(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + ngx_http_upstream_srv_conf_t *uscf; + + uscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_upstream_module); + + uscf->peer.init_upstream = ngx_http_upstream_init_least_conn; + + uscf->flags = NGX_HTTP_UPSTREAM_CREATE + |NGX_HTTP_UPSTREAM_WEIGHT + |NGX_HTTP_UPSTREAM_MAX_FAILS + |NGX_HTTP_UPSTREAM_FAIL_TIMEOUT + |NGX_HTTP_UPSTREAM_DOWN + |NGX_HTTP_UPSTREAM_BACKUP; + + return NGX_CONF_OK; +} diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_xslt_filter_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_xslt_filter_module.c index 4309a448908..9b0354b2ee6 100644 --- a/usr.sbin/nginx/src/http/modules/ngx_http_xslt_filter_module.c +++ b/usr.sbin/nginx/src/http/modules/ngx_http_xslt_filter_module.c @@ -810,7 +810,7 @@ ngx_http_xslt_entities(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) file = xmcf->dtd_files.elts; for (i = 0; i < xmcf->dtd_files.nelts; i++) { - if (ngx_strcmp(file[i].name, &value[1].data) == 0) { + if (ngx_strcmp(file[i].name, value[1].data) == 0) { xlcf->dtd = file[i].data; return NGX_CONF_OK; } @@ -884,7 +884,7 @@ ngx_http_xslt_stylesheet(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) file = xmcf->sheet_files.elts; for (i = 0; i < xmcf->sheet_files.nelts; i++) { - if (ngx_strcmp(file[i].name, &value[1].data) == 0) { + if (ngx_strcmp(file[i].name, value[1].data) == 0) { sheet->stylesheet = file[i].data; goto found; } diff --git a/usr.sbin/nginx/src/http/ngx_http_core_module.c b/usr.sbin/nginx/src/http/ngx_http_core_module.c index 6aa4d0240ad..a079795c4d7 100644 --- a/usr.sbin/nginx/src/http/ngx_http_core_module.c +++ b/usr.sbin/nginx/src/http/ngx_http_core_module.c @@ -4666,7 +4666,7 @@ ngx_http_core_try_files(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) code = ngx_atoi(tf[i - 1].name.data + 1, tf[i - 1].name.len - 2); - if (code == NGX_ERROR) { + if (code == NGX_ERROR || code > 999) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid code \"%*s\"", tf[i - 1].name.len - 1, tf[i - 1].name.data); diff --git a/usr.sbin/nginx/src/http/ngx_http_header_filter_module.c b/usr.sbin/nginx/src/http/ngx_http_header_filter_module.c index 8a6080f6008..1e01c857dc1 100644 --- a/usr.sbin/nginx/src/http/ngx_http_header_filter_module.c +++ b/usr.sbin/nginx/src/http/ngx_http_header_filter_module.c @@ -395,7 +395,7 @@ ngx_http_header_filter(ngx_http_request_t *r) } } else { - len += sizeof("Connection: closed" CRLF) - 1; + len += sizeof("Connection: close" CRLF) - 1; } #if (NGX_HTTP_GZIP) @@ -445,7 +445,7 @@ ngx_http_header_filter(ngx_http_request_t *r) b->last = ngx_copy(b->last, status_line->data, status_line->len); } else { - b->last = ngx_sprintf(b->last, "%ui", status); + b->last = ngx_sprintf(b->last, "%03ui", status); } *b->last++ = CR; *b->last++ = LF; diff --git a/usr.sbin/nginx/src/http/ngx_http_request.c b/usr.sbin/nginx/src/http/ngx_http_request.c index b1877131cc9..e0ae5241f4e 100644 --- a/usr.sbin/nginx/src/http/ngx_http_request.c +++ b/usr.sbin/nginx/src/http/ngx_http_request.c @@ -138,7 +138,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 || NGX_HTTP_GEO) +#if (NGX_HTTP_X_FORWARDED_FOR) { ngx_string("X-Forwarded-For"), offsetof(ngx_http_headers_in_t, x_forwarded_for), ngx_http_process_header_line }, diff --git a/usr.sbin/nginx/src/http/ngx_http_request.h b/usr.sbin/nginx/src/http/ngx_http_request.h index 70ca6097efa..c2651a86fd1 100644 --- a/usr.sbin/nginx/src/http/ngx_http_request.h +++ b/usr.sbin/nginx/src/http/ngx_http_request.h @@ -137,6 +137,13 @@ #define NGX_HTTP_COPY_BUFFERED 0x04 +#if (NGX_HTTP_PROXY || NGX_HTTP_REALIP || NGX_HTTP_GEO) +#ifndef NGX_HTTP_X_FORWARDED_FOR +#define NGX_HTTP_X_FORWARDED_FOR 1 +#endif +#endif + + typedef enum { NGX_HTTP_INITING_REQUEST_STATE = 0, NGX_HTTP_READING_REQUEST_STATE, @@ -192,7 +199,7 @@ typedef struct { ngx_table_elt_t *keep_alive; -#if (NGX_HTTP_PROXY || NGX_HTTP_REALIP || NGX_HTTP_GEO) +#if (NGX_HTTP_X_FORWARDED_FOR) ngx_table_elt_t *x_forwarded_for; #endif diff --git a/usr.sbin/nginx/src/http/ngx_http_upstream.c b/usr.sbin/nginx/src/http/ngx_http_upstream.c index 70a4e166856..3730a20262c 100644 --- a/usr.sbin/nginx/src/http/ngx_http_upstream.c +++ b/usr.sbin/nginx/src/http/ngx_http_upstream.c @@ -3677,6 +3677,7 @@ static ngx_int_t ngx_http_upstream_rewrite_set_cookie(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset) { + ngx_int_t rc; ngx_table_elt_t *ho; ho = ngx_list_push(&r->headers_out.headers); @@ -3687,7 +3688,20 @@ ngx_http_upstream_rewrite_set_cookie(ngx_http_request_t *r, ngx_table_elt_t *h, *ho = *h; if (r->upstream->rewrite_cookie) { - return r->upstream->rewrite_cookie(r, ho); + rc = r->upstream->rewrite_cookie(r, ho); + + if (rc == NGX_DECLINED) { + return NGX_OK; + } + +#if (NGX_DEBUG) + if (rc == NGX_OK) { + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "rewritten cookie: \"%V\"", &ho->value); + } +#endif + + return rc; } return NGX_OK; diff --git a/usr.sbin/nginx/src/http/ngx_http_upstream_round_robin.c b/usr.sbin/nginx/src/http/ngx_http_upstream_round_robin.c index 214de7b74fc..c4998fca519 100644 --- a/usr.sbin/nginx/src/http/ngx_http_upstream_round_robin.c +++ b/usr.sbin/nginx/src/http/ngx_http_upstream_round_robin.c @@ -30,7 +30,7 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf, ngx_http_upstream_srv_conf_t *us) { ngx_url_t u; - ngx_uint_t i, j, n; + ngx_uint_t i, j, n, w; ngx_http_upstream_server_t *server; ngx_http_upstream_rr_peers_t *peers, *backup; @@ -40,6 +40,7 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf, server = us->servers->elts; n = 0; + w = 0; for (i = 0; i < us->servers->nelts; i++) { if (server[i].backup) { @@ -47,6 +48,7 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf, } n += server[i].naddrs; + w += server[i].naddrs * server[i].weight; } if (n == 0) { @@ -64,6 +66,8 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf, peers->single = (n == 1); peers->number = n; + peers->weighted = (w != n); + peers->total_weight = w; peers->name = &us->host; n = 0; @@ -96,6 +100,7 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf, /* backup servers */ n = 0; + w = 0; for (i = 0; i < us->servers->nelts; i++) { if (!server[i].backup) { @@ -103,6 +108,7 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf, } n += server[i].naddrs; + w += server[i].naddrs * server[i].weight; } if (n == 0) { @@ -118,6 +124,8 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf, peers->single = 0; backup->single = 0; backup->number = n; + backup->weighted = (w != n); + backup->total_weight = w; backup->name = &us->host; n = 0; @@ -185,6 +193,8 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf, peers->single = (n == 1); peers->number = n; + peers->weighted = 0; + peers->total_weight = n; peers->name = &us->host; for (i = 0; i < u.naddrs; i++) { diff --git a/usr.sbin/nginx/src/http/ngx_http_upstream_round_robin.h b/usr.sbin/nginx/src/http/ngx_http_upstream_round_robin.h index 4de3caea1b0..3f8cbf87f7f 100644 --- a/usr.sbin/nginx/src/http/ngx_http_upstream_round_robin.h +++ b/usr.sbin/nginx/src/http/ngx_http_upstream_round_robin.h @@ -41,13 +41,17 @@ typedef struct { typedef struct ngx_http_upstream_rr_peers_s ngx_http_upstream_rr_peers_t; struct ngx_http_upstream_rr_peers_s { - ngx_uint_t single; /* unsigned single:1; */ ngx_uint_t number; ngx_uint_t last_cached; /* ngx_mutex_t *mutex; */ ngx_connection_t **cached; + ngx_uint_t total_weight; + + unsigned single:1; + unsigned weighted:1; + ngx_str_t *name; ngx_http_upstream_rr_peers_t *next; diff --git a/usr.sbin/nginx/src/http/ngx_http_variables.c b/usr.sbin/nginx/src/http/ngx_http_variables.c index 949cef9107c..f34a6d9a372 100644 --- a/usr.sbin/nginx/src/http/ngx_http_variables.c +++ b/usr.sbin/nginx/src/http/ngx_http_variables.c @@ -77,6 +77,8 @@ static ngx_int_t ngx_http_variable_request_body(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_variable_request_body_file(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); +static ngx_int_t ngx_http_variable_status(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_variable_sent_content_type(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); @@ -132,7 +134,7 @@ static ngx_http_variable_t ngx_http_core_variables[] = { offsetof(ngx_http_request_t, headers_in.via), 0, 0 }, #endif -#if (NGX_HTTP_PROXY || NGX_HTTP_REALIP) +#if (NGX_HTTP_X_FORWARDED_FOR) { ngx_string("http_x_forwarded_for"), NULL, ngx_http_variable_header, offsetof(ngx_http_request_t, headers_in.x_forwarded_for), 0, 0 }, #endif @@ -225,6 +227,10 @@ static ngx_http_variable_t ngx_http_core_variables[] = { ngx_http_variable_request_body_file, 0, 0, 0 }, + { ngx_string("status"), NULL, + ngx_http_variable_status, 0, + NGX_HTTP_VAR_NOCACHEABLE, 0 }, + { ngx_string("sent_http_content_type"), NULL, ngx_http_variable_sent_content_type, 0, 0, 0 }, @@ -1456,6 +1462,39 @@ ngx_http_variable_body_bytes_sent(ngx_http_request_t *r, static ngx_int_t +ngx_http_variable_status(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) +{ + ngx_uint_t status; + + v->data = ngx_pnalloc(r->pool, NGX_INT_T_LEN); + if (v->data == NULL) { + return NGX_ERROR; + } + + if (r->err_status) { + status = r->err_status; + + } else if (r->headers_out.status) { + status = r->headers_out.status; + + } else if (r->http_version == NGX_HTTP_VERSION_9) { + status = 9; + + } else { + status = 0; + } + + v->len = ngx_sprintf(v->data, "%03ui", status) - v->data; + v->valid = 1; + v->no_cacheable = 0; + v->not_found = 0; + + return NGX_OK; +} + + +static ngx_int_t ngx_http_variable_sent_content_type(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { @@ -2016,7 +2055,7 @@ ngx_int_t ngx_http_variables_add_core_vars(ngx_conf_t *cf) { ngx_int_t rc; - ngx_http_variable_t *v; + ngx_http_variable_t *cv, *v; ngx_http_core_main_conf_t *cmcf; cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); @@ -2036,7 +2075,14 @@ ngx_http_variables_add_core_vars(ngx_conf_t *cf) return NGX_ERROR; } - for (v = ngx_http_core_variables; v->name.len; v++) { + for (cv = ngx_http_core_variables; cv->name.len; cv++) { + v = ngx_palloc(cf->pool, sizeof(ngx_http_variable_t)); + if (v == NULL) { + return NGX_ERROR; + } + + *v = *cv; + rc = ngx_hash_add_key(cmcf->variables_keys, &v->name, v, NGX_HASH_READONLY_KEY); diff --git a/usr.sbin/nginx/src/os/unix/ngx_errno.c b/usr.sbin/nginx/src/os/unix/ngx_errno.c index 75176c49a47..e787b2377ed 100644 --- a/usr.sbin/nginx/src/os/unix/ngx_errno.c +++ b/usr.sbin/nginx/src/os/unix/ngx_errno.c @@ -42,7 +42,7 @@ ngx_strerror(ngx_err_t err, u_char *errstr, size_t size) } -ngx_uint_t +ngx_int_t ngx_strerror_init(void) { char *msg; diff --git a/usr.sbin/nginx/src/os/unix/ngx_errno.h b/usr.sbin/nginx/src/os/unix/ngx_errno.h index 2912dea0441..125087e781d 100644 --- a/usr.sbin/nginx/src/os/unix/ngx_errno.h +++ b/usr.sbin/nginx/src/os/unix/ngx_errno.h @@ -69,7 +69,7 @@ typedef int ngx_err_t; u_char *ngx_strerror(ngx_err_t err, u_char *errstr, size_t size); -ngx_uint_t ngx_strerror_init(void); +ngx_int_t ngx_strerror_init(void); #endif /* _NGX_ERRNO_H_INCLUDED_ */ diff --git a/usr.sbin/nginx/src/os/unix/ngx_freebsd_init.c b/usr.sbin/nginx/src/os/unix/ngx_freebsd_init.c index 57af44a20cf..aeeceaf2565 100644 --- a/usr.sbin/nginx/src/os/unix/ngx_freebsd_init.c +++ b/usr.sbin/nginx/src/os/unix/ngx_freebsd_init.c @@ -76,9 +76,9 @@ ngx_debug_init() { #if (NGX_DEBUG_MALLOC) -#if __FreeBSD_version >= 500014 +#if __FreeBSD_version >= 500014 && __FreeBSD_version < 1000011 _malloc_options = "J"; -#else +#elif __FreeBSD_version < 500014 malloc_options = "J"; #endif diff --git a/usr.sbin/nginx/src/os/unix/ngx_posix_config.h b/usr.sbin/nginx/src/os/unix/ngx_posix_config.h index 4d432a7e32e..4cf90cc9897 100644 --- a/usr.sbin/nginx/src/os/unix/ngx_posix_config.h +++ b/usr.sbin/nginx/src/os/unix/ngx_posix_config.h @@ -12,6 +12,7 @@ #if (NGX_HPUX) #define _XOPEN_SOURCE #define _XOPEN_SOURCE_EXTENDED 1 +#define _HPUX_ALT_XOPEN_SOCKET_API #endif diff --git a/usr.sbin/nginx/src/os/unix/ngx_process_cycle.c b/usr.sbin/nginx/src/os/unix/ngx_process_cycle.c index b9d4c8c7ec5..ed8c24029f3 100644 --- a/usr.sbin/nginx/src/os/unix/ngx_process_cycle.c +++ b/usr.sbin/nginx/src/os/unix/ngx_process_cycle.c @@ -712,6 +712,8 @@ ngx_master_process_exit(ngx_cycle_t *cycle) ngx_exit_log.file = &ngx_exit_log_file; ngx_exit_cycle.log = &ngx_exit_log; + ngx_exit_cycle.files = ngx_cycle->files; + ngx_exit_cycle.files_n = ngx_cycle->files_n; ngx_cycle = &ngx_exit_cycle; ngx_destroy_pool(cycle->pool); @@ -1097,6 +1099,8 @@ ngx_worker_process_exit(ngx_cycle_t *cycle) ngx_exit_log.file = &ngx_exit_log_file; ngx_exit_cycle.log = &ngx_exit_log; + ngx_exit_cycle.files = ngx_cycle->files; + ngx_exit_cycle.files_n = ngx_cycle->files_n; ngx_cycle = &ngx_exit_cycle; ngx_destroy_pool(cycle->pool); |