Changes of Revision 12
[-] | Changed | nginx.spec |
x 1
2 %define with_rtmp_ext 1 3 4 Name: nginx 5 -Version: 1.6.0 6 +Version: 1.7.1 7 Release: 2 8 Summary: Robust, small and high performance http and reverse proxy server 9 Group: System Environment/Daemons 10
11 --with-http_gzip_static_module \ 12 --with-http_stub_status_module \ 13 --with-http_mp4_module \ 14 + --with-http_degradation_module \ 15 --with-mail \ 16 --with-mail_ssl_module \ 17 --with-debug \ 18 |
||
[+] | Changed | nginx-1.7.1.tar.gz/CHANGES ^ |
@@ -1,7 +1,49 @@ -Changes with nginx 1.6.0 24 Apr 2014 +Changes with nginx 1.7.1 27 May 2014 - *) 1.6.x stable branch. + *) Feature: the "$upstream_cookie_..." variables. + + *) Feature: the $ssl_client_fingerprint variable. + + *) Feature: the "error_log" and "access_log" directives now support + logging to syslog. + + *) Feature: the mail proxy now logs client port on connect. + + *) Bugfix: memory leak if the "ssl_stapling" directive was used. + Thanks to Filipe da Silva. + + *) Bugfix: the "alias" directive used inside a location given by a + regular expression worked incorrectly if the "if" or "limit_except" + directives were used. + + *) Bugfix: the "charset" directive did not set a charset to encoded + backend responses. + + *) Bugfix: a "proxy_pass" directive without URI part might use original + request after the $args variable was set. + Thanks to Yichun Zhang. + + *) Bugfix: in the "none" parameter in the "smtp_auth" directive; the bug + had appeared in 1.5.6. + Thanks to Svyatoslav Nikolsky. + + *) Bugfix: if sub_filter and SSI were used together, then responses + might be transferred incorrectly. + + *) Bugfix: nginx could not be built with the --with-file-aio option on + Linux/aarch64. + + +Changes with nginx 1.7.0 24 Apr 2014 + + *) Feature: backend SSL certificate verification. + + *) Feature: support for SNI while working with SSL backends. + + *) Feature: the $ssl_server_name variable. + + *) Feature: the "if" parameter of the "access_log" directive. Changes with nginx 1.5.13 08 Apr 2014 | ||
[+] | Changed | nginx-1.7.1.tar.gz/CHANGES.ru ^ |
@@ -1,7 +1,51 @@ -Изменения в nginx 1.6.0 24.04.2014 +Изменения в nginx 1.7.1 27.05.2014 - *) Стабильная ветка 1.6.x. + *) Добавление: переменные "$upstream_cookie_...". + + *) Добавление: переменная $ssl_client_fingerprint. + + *) Добавление: директивы error_log и access_log теперь поддерживают + логгирование в syslog. + + *) Добавление: почтовый прокси-сервер теперь логгирует порт клиента при + соединении. + + *) Исправление: утечки памяти при использовании директивы + "ssl_stapling". + Спасибо Filipe da Silva. + + *) Исправление: директива alias внутри location'а, заданного регулярным + выражением, работала неправильно, если использовались директивы if + или limit_except. + + *) Исправление: директива charset не ставила кодировку для сжатых + ответов бэкендов. + + *) Исправление: директива proxy_pass без URI могла использовать + оригинальный запрос после установки переменной $args. + Спасибо Yichun Zhang. + + *) Исправление: в работе параметра none директивы smtp_auth; ошибка + появилась в 1.5.6. + Спасибо Святославу Никольскому. + + *) Исправление: при совместном использовании sub_filter и SSI ответы + могли передаваться неверно. + + *) Исправление: nginx не собирался с параметром --with-file-aio на + Linux/aarch64. + + +Изменения в nginx 1.7.0 24.04.2014 + + *) Добавление: проверка SSL-сертификатов бэкендов. + + *) Добавление: поддержка SNI при работе с бэкендами по SSL. + + *) Добавление: переменная $ssl_server_name. + + *) Добавление: параметр if директивы access_log. Изменения в nginx 1.5.13 08.04.2014 | ||
[+] | Changed | nginx-1.7.1.tar.gz/auto/lib/google-perftools/conf ^ |
@@ -52,7 +52,7 @@ cat << END -$0: error: the Google perftool module requires the Google perftools +$0: error: the Google perftools module requires the Google perftools library. You can either do not enable the module or install the library. END | ||
[+] | Changed | nginx-1.7.1.tar.gz/auto/options ^ |
@@ -14,6 +14,7 @@ NGX_LOCK_PATH= NGX_USER= NGX_GROUP= +NGX_BUILD= CC=${CC:-cc} CPP= @@ -178,6 +179,7 @@ --crossbuild=*) NGX_PLATFORM="$value" ;; + --build=*) NGX_BUILD="$value" ;; --builddir=*) NGX_OBJS="$value" ;; --with-rtsig_module) EVENT_RTSIG=YES ;; @@ -341,6 +343,7 @@ --group=GROUP set non-privileged group for worker processes + --build=NAME set build name --builddir=DIR set build directory --with-rtsig_module enable rtsig module | ||
[+] | Changed | nginx-1.7.1.tar.gz/auto/sources ^ |
@@ -37,7 +37,8 @@ src/core/ngx_resolver.h \ src/core/ngx_open_file_cache.h \ src/core/ngx_crypt.h \ - src/core/ngx_proxy_protocol.h" + src/core/ngx_proxy_protocol.h \ + src/core/ngx_syslog.h" CORE_SRCS="src/core/nginx.c \ @@ -69,7 +70,8 @@ src/core/ngx_resolver.c \ src/core/ngx_open_file_cache.c \ src/core/ngx_crypt.c \ - src/core/ngx_proxy_protocol.c" + src/core/ngx_proxy_protocol.c \ + src/core/ngx_syslog.c" REGEX_MODULE=ngx_regex_module | ||
[+] | Changed | nginx-1.7.1.tar.gz/auto/unix ^ |
@@ -398,16 +398,36 @@ if [ $ngx_found = yes ]; then CORE_SRCS="$CORE_SRCS $FILE_AIO_SRCS" + fi - elif [ $ngx_found = no ]; then + if [ $ngx_found = no ]; then ngx_feature="Linux AIO support" ngx_feature_name="NGX_HAVE_FILE_AIO" ngx_feature_run=no ngx_feature_incs="#include <linux/aio_abi.h> - #include <sys/syscall.h>" + #include <sys/eventfd.h>" ngx_feature_path= ngx_feature_libs= + ngx_feature_test="struct iocb iocb; + iocb.aio_lio_opcode = IOCB_CMD_PREAD; + iocb.aio_flags = IOCB_FLAG_RESFD; + iocb.aio_resfd = -1; + (void) eventfd(0, 0)" + . auto/feature + + if [ $ngx_found = yes ]; then + have=NGX_HAVE_EVENTFD . auto/have + have=NGX_HAVE_SYS_EVENTFD_H . auto/have + CORE_SRCS="$CORE_SRCS $LINUX_AIO_SRCS" + fi + fi + + if [ $ngx_found = no ]; then + + ngx_feature="Linux AIO support (SYS_eventfd)" + ngx_feature_incs="#include <linux/aio_abi.h> + #include <sys/syscall.h>" ngx_feature_test="int n = SYS_eventfd; struct iocb iocb; iocb.aio_lio_opcode = IOCB_CMD_PREAD; @@ -418,16 +438,17 @@ if [ $ngx_found = yes ]; then have=NGX_HAVE_EVENTFD . auto/have CORE_SRCS="$CORE_SRCS $LINUX_AIO_SRCS" + fi + fi - else - cat << END + if [ $ngx_found = no ]; then + cat << END $0: no supported file AIO was found Currently file AIO is supported on FreeBSD 4.3+ and Linux 2.6.22+ only END - exit 1 - fi + exit 1 fi fi | ||
[+] | Changed | nginx-1.7.1.tar.gz/configure ^ |
@@ -108,4 +108,8 @@ have=NGX_USER value="\"$NGX_USER\"" . auto/define have=NGX_GROUP value="\"$NGX_GROUP\"" . auto/define +if [ ".$NGX_BUILD" != "." ]; then + have=NGX_BUILD value="\"$NGX_BUILD\"" . auto/define +fi + . auto/summary | ||
[+] | Changed | nginx-1.7.1.tar.gz/src/core/nginx.c ^ |
@@ -217,7 +217,7 @@ } if (ngx_show_version) { - ngx_write_stderr("nginx version: " NGINX_VER NGX_LINEFEED); + ngx_write_stderr("nginx version: " NGINX_VER_BUILD NGX_LINEFEED); if (ngx_show_help) { ngx_write_stderr( | ||
[+] | Changed | nginx-1.7.1.tar.gz/src/core/nginx.h ^ |
@@ -9,10 +9,16 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 1006000 -#define NGINX_VERSION "1.6.0" +#define nginx_version 1007001 +#define NGINX_VERSION "1.7.1" #define NGINX_VER "nginx/" NGINX_VERSION +#ifdef NGX_BUILD +#define NGINX_VER_BUILD NGINX_VER " (" NGX_BUILD ")" +#else +#define NGINX_VER_BUILD NGINX_VER +#endif + #define NGINX_VAR "NGINX" #define NGX_OLDPID_EXT ".oldbin" | ||
[+] | Changed | nginx-1.7.1.tar.gz/src/core/ngx_conf_file.c ^ |
@@ -266,7 +266,7 @@ ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno, ngx_close_file_n " %s failed", filename->data); - return NGX_CONF_ERROR; + rc = NGX_ERROR; } cf->conf_file = prev; | ||
[+] | Changed | nginx-1.7.1.tar.gz/src/core/ngx_core.h ^ |
@@ -77,12 +77,13 @@ #include <ngx_open_file_cache.h> #include <ngx_os.h> #include <ngx_connection.h> +#include <ngx_syslog.h> #include <ngx_proxy_protocol.h> -#define LF (u_char) 10 -#define CR (u_char) 13 -#define CRLF "\x0d\x0a" +#define LF (u_char) '\n' +#define CR (u_char) '\r' +#define CRLF "\r\n" #define ngx_abs(value) (((value) >= 0) ? (value) : - (value)) | ||
[+] | Changed | nginx-1.7.1.tar.gz/src/core/ngx_cycle.c ^ |
@@ -1104,6 +1104,8 @@ ngx_close_file_n " \"%s\" failed", file[i].name.data); } + + continue; } if (fi.st_uid != user) { @@ -1117,6 +1119,8 @@ ngx_close_file_n " \"%s\" failed", file[i].name.data); } + + continue; } } @@ -1133,6 +1137,8 @@ ngx_close_file_n " \"%s\" failed", file[i].name.data); } + + continue; } } } | ||
[+] | Changed | nginx-1.7.1.tar.gz/src/core/ngx_log.c ^ |
@@ -148,6 +148,12 @@ break; } + if (log->writer) { + log->writer(log, level, errstr, p - errstr); + log = log->next; + continue; + } + (void) ngx_write_fd(log->file->fd, errstr, p - errstr); if (log->file->fd == ngx_stderr) { @@ -366,15 +372,33 @@ ngx_int_t ngx_log_open_default(ngx_cycle_t *cycle) { - static ngx_str_t error_log = ngx_string(NGX_ERROR_LOG_PATH); + ngx_log_t *log; + static ngx_str_t error_log = ngx_string(NGX_ERROR_LOG_PATH); + + if (ngx_log_get_file_log(&cycle->new_log) != NULL) { + return NGX_OK; + } - if (cycle->new_log.file == NULL) { - cycle->new_log.file = ngx_conf_open_file(cycle, &error_log); - if (cycle->new_log.file == NULL) { + if (cycle->new_log.log_level != 0) { + /* there are some error logs, but no files */ + + log = ngx_pcalloc(cycle->pool, sizeof(ngx_log_t)); + if (log == NULL) { return NGX_ERROR; } - cycle->new_log.log_level = NGX_LOG_ERR; + log->log_level = NGX_LOG_ERR; + ngx_log_insert(&cycle->new_log, log); + + } else { + /* no error logs at all */ + log = &cycle->new_log; + log->log_level = NGX_LOG_ERR; + } + + log->file = ngx_conf_open_file(cycle, &error_log); + if (log->file == NULL) { + return NGX_ERROR; } return NGX_OK; @@ -390,7 +414,8 @@ return NGX_OK; } - fd = cycle->log->file->fd; + /* file log always exists when we are called */ + fd = ngx_log_get_file_log(cycle->log)->file->fd; if (fd != ngx_stderr) { if (ngx_set_stderr(fd) == NGX_FILE_ERROR) { @@ -405,6 +430,21 @@ } +ngx_log_t * +ngx_log_get_file_log(ngx_log_t *head) +{ + ngx_log_t *log; + + for (log = head; log; log = log->next) { + if (log->file != NULL) { + return log; + } + } + + return NULL; +} + + static char * ngx_log_set_levels(ngx_conf_t *cf, ngx_log_t *log) { @@ -482,8 +522,9 @@ char * ngx_log_set_log(ngx_conf_t *cf, ngx_log_t **head) { - ngx_log_t *new_log; - ngx_str_t *value, name; + ngx_log_t *new_log; + ngx_str_t *value, name; + ngx_syslog_peer_t *peer; if (*head != NULL && (*head)->log_level == 0) { new_log = *head; @@ -506,13 +547,30 @@ ngx_str_null(&name); cf->cycle->log_use_stderr = 1; - } else { - name = value[1]; - } + new_log->file = ngx_conf_open_file(cf->cycle, &name); + if (new_log->file == NULL) { + return NGX_CONF_ERROR; + } + + + } else if (ngx_strncmp(value[1].data, "syslog:", 7) == 0) { + peer = ngx_pcalloc(cf->pool, sizeof(ngx_syslog_peer_t)); + if (peer == NULL) { + return NGX_CONF_ERROR; + } + + if (ngx_syslog_process_conf(cf, peer) != NGX_CONF_OK) { + return NGX_CONF_ERROR; + } - new_log->file = ngx_conf_open_file(cf->cycle, &name); - if (new_log->file == NULL) { - return NGX_CONF_ERROR; + new_log->writer = ngx_syslog_writer; + new_log->wdata = peer; + + } else { + new_log->file = ngx_conf_open_file(cf->cycle, &value[1]); + if (new_log->file == NULL) { + return NGX_CONF_ERROR; + } } if (ngx_log_set_levels(cf, new_log) != NGX_CONF_OK) { | ||
[+] | Changed | nginx-1.7.1.tar.gz/src/core/ngx_log.h ^ |
@@ -43,6 +43,8 @@ typedef u_char *(*ngx_log_handler_pt) (ngx_log_t *log, u_char *buf, size_t len); +typedef void (*ngx_log_writer_pt) (ngx_log_t *log, ngx_uint_t level, + u_char *buf, size_t len); struct ngx_log_s { @@ -54,6 +56,9 @@ ngx_log_handler_pt handler; void *data; + ngx_log_writer_pt writer; + void *wdata; + /* * we declare "action" as "char *" because the actions are usually * the static strings and in the "u_char *" case we have to override @@ -227,6 +232,7 @@ u_char *ngx_log_errno(u_char *buf, u_char *last, ngx_err_t err); ngx_int_t ngx_log_open_default(ngx_cycle_t *cycle); ngx_int_t ngx_log_redirect_stderr(ngx_cycle_t *cycle); +ngx_log_t *ngx_log_get_file_log(ngx_log_t *head); char *ngx_log_set_log(ngx_conf_t *cf, ngx_log_t **head); | ||
[+] | Added | nginx-1.7.1.tar.gz/src/core/ngx_syslog.c ^ |
@@ -0,0 +1,346 @@ + +/* + * Copyright (C) Nginx, Inc. + */ + + +#include <ngx_config.h> +#include <ngx_core.h> +#include <ngx_event.h> + + +#define NGX_SYSLOG_MAX_STR \ + NGX_MAX_ERROR_STR + sizeof("<255>Jan 01 00:00:00 ") - 1 \ + + (NGX_MAXHOSTNAMELEN - 1) + 1 /* space */ \ + + 32 /* tag */ + 2 /* colon, space */ + + +static char *ngx_syslog_parse_args(ngx_conf_t *cf, ngx_syslog_peer_t *peer); +static ngx_int_t ngx_syslog_init_peer(ngx_syslog_peer_t *peer); +static void ngx_syslog_cleanup(void *data); + + +static char *facilities[] = { + "kern", "user", "mail", "daemon", "auth", "intern", "lpr", "news", "uucp", + "clock", "authpriv", "ftp", "ntp", "audit", "alert", "cron", "local0", + "local1", "local2", "local3", "local4", "local5", "local6", "local7", + NULL +}; + +/* note 'error/warn' like in nginx.conf, not 'err/warning' */ +static char *severities[] = { + "emerg", "alert", "crit", "error", "warn", "notice", "info", "debug", NULL +}; + +static ngx_log_t ngx_syslog_dummy_log; +static ngx_event_t ngx_syslog_dummy_event; + + +char * +ngx_syslog_process_conf(ngx_conf_t *cf, ngx_syslog_peer_t *peer) +{ + peer->pool = cf->pool; + peer->facility = NGX_CONF_UNSET_UINT; + peer->severity = NGX_CONF_UNSET_UINT; + + if (ngx_syslog_parse_args(cf, peer) != NGX_CONF_OK) { + return NGX_CONF_ERROR; + } + + if (peer->server.sockaddr == NULL) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "no syslog server specified"); + return NGX_CONF_ERROR; + } + + if (peer->facility == NGX_CONF_UNSET_UINT) { + peer->facility = 23; /* local7 */ + } + + if (peer->severity == NGX_CONF_UNSET_UINT) { + peer->severity = 6; /* info */ + } + + if (peer->tag.data == NULL) { + ngx_str_set(&peer->tag, "nginx"); + } + + peer->conn.fd = (ngx_socket_t) -1; + + return NGX_CONF_OK; +} + + +static char * +ngx_syslog_parse_args(ngx_conf_t *cf, ngx_syslog_peer_t *peer) +{ + u_char *p, *comma, c; + size_t len; + ngx_str_t *value; + ngx_url_t u; + ngx_uint_t i; + + value = cf->args->elts; + + p = value[1].data + sizeof("syslog:") - 1; + + for ( ;; ) { + comma = (u_char *) ngx_strchr(p, ','); + + if (comma != NULL) { + len = comma - p; + *comma = '\0'; + + } else { + len = value[1].data + value[1].len - p; + } + + if (ngx_strncmp(p, "server=", 7) == 0) { + + if (peer->server.sockaddr != NULL) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "duplicate syslog \"server\""); + return NGX_CONF_ERROR; + } + + ngx_memzero(&u, sizeof(ngx_url_t)); + + u.url.data = p + 7; + u.url.len = len - 7; + u.default_port = 514; + + if (ngx_parse_url(cf->pool, &u) != NGX_OK) { + if (u.err) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "%s in syslog server \"%V\"", + u.err, &u.url); + } + + return NGX_CONF_ERROR; + } + + peer->server = u.addrs[0]; + + } else if (ngx_strncmp(p, "facility=", 9) == 0) { + + if (peer->facility != NGX_CONF_UNSET_UINT) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "duplicate syslog \"facility\""); + return NGX_CONF_ERROR; + } + + for (i = 0; facilities[i] != NULL; i++) { + + if (ngx_strcmp(p + 9, facilities[i]) == 0) { + peer->facility = i; + goto next; + } + } + + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "unknown syslog facility \"%s\"", p + 9); + return NGX_CONF_ERROR; + + } else if (ngx_strncmp(p, "severity=", 9) == 0) { + + if (peer->severity != NGX_CONF_UNSET_UINT) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "duplicate syslog \"severity\""); + return NGX_CONF_ERROR; + } + + for (i = 0; severities[i] != NULL; i++) { + + if (ngx_strcmp(p + 9, severities[i]) == 0) { + peer->severity = i; + goto next; + } + } + + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "unknown syslog severity \"%s\"", p + 9); + return NGX_CONF_ERROR; + + } else if (ngx_strncmp(p, "tag=", 4) == 0) { + + if (peer->tag.data != NULL) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "duplicate syslog \"tag\""); + return NGX_CONF_ERROR; + } + + /* + * RFC 3164: the TAG is a string of ABNF alphanumeric characters + * that MUST NOT exceed 32 characters. + */ + if (len - 4 > 32) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "syslog tag length exceeds 32"); + return NGX_CONF_ERROR; + } + + for (i = 4; i < len; i++) { + c = ngx_tolower(p[i]); + + if (c < '0' || (c > '9' && c < 'a') || c > 'z') { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "syslog \"tag\" only allows " + "alphanumeric characters"); + return NGX_CONF_ERROR; + } + } + + peer->tag.data = p + 4; + peer->tag.len = len - 4; + + } else { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "unknown syslog parameter \"%s\"", p); + return NGX_CONF_ERROR; + } + + next: + + if (comma == NULL) { + break; + } + + p = comma + 1; + } + + return NGX_CONF_OK; +} + + +u_char * +ngx_syslog_add_header(ngx_syslog_peer_t *peer, u_char *buf) +{ + ngx_uint_t pri; + + pri = peer->facility * 8 + peer->severity; + + return ngx_sprintf(buf, "<%ui>%V %V %V: ", pri, &ngx_cached_syslog_time, + &ngx_cycle->hostname, &peer->tag); +} + + +void +ngx_syslog_writer(ngx_log_t *log, ngx_uint_t level, u_char *buf, + size_t len) +{ + u_char *p, msg[NGX_SYSLOG_MAX_STR]; + ngx_uint_t head_len; + ngx_syslog_peer_t *peer; + + peer = log->wdata; + + if (peer->processing) { + return; + } + + peer->processing = 1; + peer->severity = level - 1; + + p = ngx_syslog_add_header(peer, msg); + head_len = p - msg; + + len -= NGX_LINEFEED_SIZE; + + if (len > NGX_SYSLOG_MAX_STR - head_len) { + len = NGX_SYSLOG_MAX_STR - head_len; + } + + p = ngx_snprintf(p, len, "%s", buf); + + (void) ngx_syslog_send(peer, msg, p - msg); + + peer->processing = 0; +} + + +ssize_t +ngx_syslog_send(ngx_syslog_peer_t *peer, u_char *buf, size_t len) +{ + if (peer->conn.fd == (ngx_socket_t) -1) { + if (ngx_syslog_init_peer(peer) != NGX_OK) { + return NGX_ERROR; + } + } + + if (ngx_send) { + return ngx_send(&peer->conn, buf, len); + + } else { + /* event module has not yet set ngx_io */ + return ngx_os_io.send(&peer->conn, buf, len); + } +} + + +static ngx_int_t +ngx_syslog_init_peer(ngx_syslog_peer_t *peer) +{ + ngx_socket_t fd; + ngx_pool_cleanup_t *cln; + + peer->conn.read = &ngx_syslog_dummy_event; + peer->conn.write = &ngx_syslog_dummy_event; + peer->conn.log = &ngx_syslog_dummy_log; + + ngx_syslog_dummy_event.log = &ngx_syslog_dummy_log; + + fd = ngx_socket(peer->server.sockaddr->sa_family, SOCK_DGRAM, 0); + if (fd == (ngx_socket_t) -1) { + ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_socket_errno, + ngx_socket_n " failed"); + return NGX_ERROR; + } + + if (ngx_nonblocking(fd) == -1) { + ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_socket_errno, + ngx_nonblocking_n " failed"); + goto failed; + } + + if (connect(fd, peer->server.sockaddr, peer->server.socklen) == -1) { + ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_socket_errno, + "connect() failed"); + goto failed; + } + + cln = ngx_pool_cleanup_add(peer->pool, 0); + if (cln == NULL) { + goto failed; + } + + cln->data = peer; + cln->handler = ngx_syslog_cleanup; + + peer->conn.fd = fd; + + /* UDP sockets are always ready to write */ + peer->conn.write->ready = 1; + + return NGX_OK; + +failed: + + if (ngx_close_socket(fd) == -1) { + ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_socket_errno, + ngx_close_socket_n " failed"); + } + + return NGX_ERROR; +} + + +static void +ngx_syslog_cleanup(void *data) +{ + ngx_syslog_peer_t *peer = data; + + if (ngx_close_socket(peer->conn.fd) == -1) { + ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_socket_errno, + ngx_close_socket_n " failed"); + } +} | ||
[+] | Added | nginx-1.7.1.tar.gz/src/core/ngx_syslog.h ^ |
@@ -0,0 +1,30 @@ + +/* + * Copyright (C) Nginx, Inc. + */ + + +#ifndef _NGX_SYSLOG_H_INCLUDED_ +#define _NGX_SYSLOG_H_INCLUDED_ + + +typedef struct { + ngx_pool_t *pool; + ngx_uint_t facility; + ngx_uint_t severity; + ngx_str_t tag; + + ngx_addr_t server; + ngx_connection_t conn; + ngx_uint_t processing; /* unsigned processing:1; */ +} ngx_syslog_peer_t; + + +char *ngx_syslog_process_conf(ngx_conf_t *cf, ngx_syslog_peer_t *peer); +u_char *ngx_syslog_add_header(ngx_syslog_peer_t *peer, u_char *buf); +void ngx_syslog_writer(ngx_log_t *log, ngx_uint_t level, u_char *buf, + size_t len); +ssize_t ngx_syslog_send(ngx_syslog_peer_t *peer, u_char *buf, size_t len); + + +#endif /* _NGX_SYSLOG_H_INCLUDED_ */ | ||
[+] | Changed | nginx-1.7.1.tar.gz/src/core/ngx_times.c ^ |
@@ -29,6 +29,7 @@ volatile ngx_str_t ngx_cached_http_time; volatile ngx_str_t ngx_cached_http_log_time; volatile ngx_str_t ngx_cached_http_log_iso8601; +volatile ngx_str_t ngx_cached_syslog_time; #if !(NGX_WIN32) @@ -50,6 +51,8 @@ [sizeof("28/Sep/1970:12:00:00 +0600")]; static u_char cached_http_log_iso8601[NGX_TIME_SLOTS] [sizeof("1970-09-28T12:00:00+06:00")]; +static u_char cached_syslog_time[NGX_TIME_SLOTS] + [sizeof("Sep 28 12:00:00")]; static char *week[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; @@ -63,6 +66,7 @@ ngx_cached_http_time.len = sizeof("Mon, 28 Sep 1970 06:00:00 GMT") - 1; ngx_cached_http_log_time.len = sizeof("28/Sep/1970:12:00:00 +0600") - 1; ngx_cached_http_log_iso8601.len = sizeof("1970-09-28T12:00:00+06:00") - 1; + ngx_cached_syslog_time.len = sizeof("Sep 28 12:00:00") - 1; ngx_cached_time = &cached_time[0]; @@ -73,7 +77,7 @@ void ngx_time_update(void) { - u_char *p0, *p1, *p2, *p3; + u_char *p0, *p1, *p2, *p3, *p4; ngx_tm_t tm, gmt; time_t sec; ngx_uint_t msec; @@ -166,6 +170,11 @@ tp->gmtoff < 0 ? '-' : '+', ngx_abs(tp->gmtoff / 60), ngx_abs(tp->gmtoff % 60)); + p4 = &cached_syslog_time[slot][0]; + + (void) ngx_sprintf(p4, "%s %2d %02d:%02d:%02d", + months[tm.ngx_tm_mon - 1], tm.ngx_tm_mday, + tm.ngx_tm_hour, tm.ngx_tm_min, tm.ngx_tm_sec); ngx_memory_barrier(); @@ -174,6 +183,7 @@ ngx_cached_err_log_time.data = p1; ngx_cached_http_log_time.data = p2; ngx_cached_http_log_iso8601.data = p3; + ngx_cached_syslog_time.data = p4; ngx_unlock(&ngx_time_lock); } @@ -184,7 +194,7 @@ void ngx_time_sigsafe_update(void) { - u_char *p; + u_char *p, *p2; ngx_tm_t tm; time_t sec; ngx_time_t *tp; @@ -224,9 +234,16 @@ tm.ngx_tm_mday, tm.ngx_tm_hour, tm.ngx_tm_min, tm.ngx_tm_sec); + p2 = &cached_syslog_time[slot][0]; + + (void) ngx_sprintf(p2, "%s %2d %02d:%02d:%02d", + months[tm.ngx_tm_mon - 1], tm.ngx_tm_mday, + tm.ngx_tm_hour, tm.ngx_tm_min, tm.ngx_tm_sec); + ngx_memory_barrier(); ngx_cached_err_log_time.data = p; + ngx_cached_syslog_time.data = p2; ngx_unlock(&ngx_time_lock); } | ||
[+] | Changed | nginx-1.7.1.tar.gz/src/core/ngx_times.h ^ |
@@ -40,6 +40,7 @@ extern volatile ngx_str_t ngx_cached_http_time; extern volatile ngx_str_t ngx_cached_http_log_time; extern volatile ngx_str_t ngx_cached_http_log_iso8601; +extern volatile ngx_str_t ngx_cached_syslog_time; /* * milliseconds elapsed since epoch and truncated to ngx_msec_t, | ||
[+] | Changed | nginx-1.7.1.tar.gz/src/event/modules/ngx_epoll_module.c ^ |
@@ -193,10 +193,6 @@ * We call io_setup(), io_destroy() io_submit(), and io_getevents() directly * as syscalls instead of libaio usage, because the library header file * supports eventfd() since 0.3.107 version only. - * - * Also we do not use eventfd() in glibc, because glibc supports it - * since 2.8 version and glibc maps two syscalls eventfd() and eventfd2() - * into single eventfd() function with different number of parameters. */ static int @@ -227,7 +223,11 @@ int n; struct epoll_event ee; +#if (NGX_HAVE_SYS_EVENTFD_H) + ngx_eventfd = eventfd(0, 0); +#else ngx_eventfd = syscall(SYS_eventfd, 0); +#endif if (ngx_eventfd == -1) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, | ||
[+] | Changed | nginx-1.7.1.tar.gz/src/event/ngx_event_accept.c ^ |
@@ -288,9 +288,11 @@ #if (NGX_DEBUG) { + ngx_str_t addr; struct sockaddr_in *sin; ngx_cidr_t *cidr; ngx_uint_t i; + u_char text[NGX_SOCKADDR_STRLEN]; #if (NGX_HAVE_INET6) struct sockaddr_in6 *sin6; ngx_uint_t n; @@ -340,11 +342,17 @@ continue; } + if (log->log_level & NGX_LOG_DEBUG_EVENT) { + addr.data = text; + addr.len = ngx_sock_ntop(c->sockaddr, c->socklen, text, + NGX_SOCKADDR_STRLEN, 1); + + ngx_log_debug3(NGX_LOG_DEBUG_EVENT, log, 0, + "*%uA accept: %V fd:%d", c->number, &addr, s); } -#endif - ngx_log_debug3(NGX_LOG_DEBUG_EVENT, log, 0, - "*%uA accept: %V fd:%d", c->number, &c->addr_text, s); + } +#endif if (ngx_add_conn && (ngx_event_flags & NGX_USE_EPOLL_EVENT) == 0) { if (ngx_add_conn(c) == NGX_ERROR) { | ||
[+] | Changed | nginx-1.7.1.tar.gz/src/event/ngx_event_openssl.c ^ |
@@ -44,6 +44,10 @@ HMAC_CTX *hctx, int enc); #endif +#if OPENSSL_VERSION_NUMBER < 0x10002001L +static ngx_int_t ngx_ssl_check_name(ngx_str_t *name, ASN1_STRING *str); +#endif + static void *ngx_openssl_create_conf(ngx_cycle_t *cycle); static char *ngx_openssl_engine(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static void ngx_openssl_exit(ngx_cycle_t *cycle); @@ -2418,7 +2422,7 @@ if (enc == 1) { /* encrypt session ticket */ - ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, + ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, "ssl session ticket encrypt, key: \"%*s\" (%s session)", ngx_hex_dump(buf, key[0].name, 16) - buf, buf, SSL_session_reused(ssl_conn) ? "reused" : "new"); @@ -2440,7 +2444,7 @@ } } - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, "ssl session ticket decrypt, key: \"%*s\" not found", ngx_hex_dump(buf, name, 16) - buf, buf); @@ -2448,7 +2452,7 @@ found: - ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, + ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, "ssl session ticket decrypt, key: \"%*s\"%s", ngx_hex_dump(buf, key[i].name, 16) - buf, buf, (i == 0) ? " (default)" : ""); @@ -2487,6 +2491,175 @@ ngx_int_t +ngx_ssl_check_host(ngx_connection_t *c, ngx_str_t *name) +{ + X509 *cert; + + cert = SSL_get_peer_certificate(c->ssl->connection); + if (cert == NULL) { + return NGX_ERROR; + } + +#if OPENSSL_VERSION_NUMBER >= 0x10002001L + + /* X509_check_host() is only available in OpenSSL 1.0.2+ */ + + if (name->len == 0) { + goto failed; + } + + if (X509_check_host(cert, name->data, name->len, 0) != 1) { + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, + "X509_check_host(): no match"); + goto failed; + } + + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, + "X509_check_host(): match"); + + goto found; + +#else + { + int n, i; + X509_NAME *sname; + ASN1_STRING *str; + X509_NAME_ENTRY *entry; + GENERAL_NAME *altname; + STACK_OF(GENERAL_NAME) *altnames; + + /* + * As per RFC6125 and RFC2818, we check subjectAltName extension, + * and if it's not present - commonName in Subject is checked. + */ + + altnames = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL); + + if (altnames) { + n = sk_GENERAL_NAME_num(altnames); + + for (i = 0; i < n; i++) { + altname = sk_GENERAL_NAME_value(altnames, i); + + if (altname->type != GEN_DNS) { + continue; + } + + str = altname->d.dNSName; + + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, + "SSL subjectAltName: \"%*s\"", + ASN1_STRING_length(str), ASN1_STRING_data(str)); + + if (ngx_ssl_check_name(name, str) == NGX_OK) { + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, + "SSL subjectAltName: match"); + GENERAL_NAMES_free(altnames); + goto found; + } + } + + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, + "SSL subjectAltName: no match"); + + GENERAL_NAMES_free(altnames); + goto failed; + } + + /* + * If there is no subjectAltName extension, check commonName + * in Subject. While RFC2818 requires to only check "most specific" + * CN, both Apache and OpenSSL check all CNs, and so do we. + */ + + sname = X509_get_subject_name(cert); + + if (sname == NULL) { + goto failed; + } + + i = -1; + for ( ;; ) { + i = X509_NAME_get_index_by_NID(sname, NID_commonName, i); + + if (i < 0) { + break; + } + + entry = X509_NAME_get_entry(sname, i); + str = X509_NAME_ENTRY_get_data(entry); + + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, + "SSL commonName: \"%*s\"", + ASN1_STRING_length(str), ASN1_STRING_data(str)); + + if (ngx_ssl_check_name(name, str) == NGX_OK) { + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, + "SSL commonName: match"); + goto found; + } + } + + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, + "SSL commonName: no match"); + } +#endif + +failed: + + X509_free(cert); + return NGX_ERROR; + +found: + + X509_free(cert); + return NGX_OK; +} + + +#if OPENSSL_VERSION_NUMBER < 0x10002001L + +static ngx_int_t +ngx_ssl_check_name(ngx_str_t *name, ASN1_STRING *pattern) +{ + u_char *s, *p, *end; + size_t slen, plen; + + s = name->data; + slen = name->len; + + p = ASN1_STRING_data(pattern); + plen = ASN1_STRING_length(pattern); + + if (slen == plen && ngx_strncasecmp(s, p, plen) == 0) { + return NGX_OK; + } + + if (plen > 2 && p[0] == '*' && p[1] == '.') { + plen -= 1; + p += 1; + + end = s + slen; + s = ngx_strlchr(s, end, '.'); + + if (s == NULL) { + return NGX_ERROR; + } + + slen = end - s; + + if (plen == slen && ngx_strncasecmp(s, p, plen) == 0) { + return NGX_OK; + } + } + + return NGX_ERROR; +} + +#endif + + +ngx_int_t ngx_ssl_get_protocol(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) { s->data = (u_char *) SSL_get_version(c->ssl->connection); @@ -2545,6 +2718,28 @@ ngx_int_t +ngx_ssl_get_server_name(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) +{ +#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME + + const char *servername; + + servername = SSL_get_servername(c->ssl->connection, + TLSEXT_NAMETYPE_host_name); + if (servername) { + s->data = (u_char *) servername; + s->len = ngx_strlen(servername); + return NGX_OK; + } + +#endif + + s->len = 0; + return NGX_OK; +} + + +ngx_int_t ngx_ssl_get_raw_certificate(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) { size_t len; @@ -2758,6 +2953,40 @@ X509_free(cert); return NGX_OK; +} + + +ngx_int_t +ngx_ssl_get_fingerprint(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) +{ + X509 *cert; + unsigned int len; + u_char buf[EVP_MAX_MD_SIZE]; + + s->len = 0; + + cert = SSL_get_peer_certificate(c->ssl->connection); + if (cert == NULL) { + return NGX_OK; + } + + if (!X509_digest(cert, EVP_sha1(), buf, &len)) { + X509_free(cert); + return NGX_ERROR; + } + + s->len = 2 * len; + s->data = ngx_pnalloc(pool, 2 * len); + if (s->data == NULL) { + X509_free(cert); + return NGX_ERROR; + } + + ngx_hex_dump(s->data, buf, len); + + X509_free(cert); + + return NGX_OK; } | ||
[+] | Changed | nginx-1.7.1.tar.gz/src/event/ngx_event_openssl.h ^ |
@@ -150,6 +150,8 @@ || n == X509_V_ERR_CERT_UNTRUSTED \ || n == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE) +ngx_int_t ngx_ssl_check_host(ngx_connection_t *c, ngx_str_t *name); + ngx_int_t ngx_ssl_get_protocol(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s); @@ -159,6 +161,8 @@ ngx_str_t *s); ngx_int_t ngx_ssl_get_session_reused(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s); +ngx_int_t ngx_ssl_get_server_name(ngx_connection_t *c, ngx_pool_t *pool, + ngx_str_t *s); ngx_int_t ngx_ssl_get_raw_certificate(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s); ngx_int_t ngx_ssl_get_certificate(ngx_connection_t *c, ngx_pool_t *pool, @@ -169,6 +173,8 @@ 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_fingerprint(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); | ||
[+] | Changed | nginx-1.7.1.tar.gz/src/event/ngx_event_openssl_stapling.c ^ |
@@ -1195,6 +1195,8 @@ b->last = p; ctx->request = b; + OCSP_REQUEST_free(ocsp); + return NGX_OK; failed: | ||
[+] | Changed | nginx-1.7.1.tar.gz/src/http/modules/ngx_http_charset_filter_module.c ^ |
@@ -272,12 +272,27 @@ return ngx_http_next_header_filter(r); } + if (source_charset == charset) { + r->headers_out.content_type.len = r->headers_out.content_type_len; + + ngx_http_set_charset(r, &dst); + + return ngx_http_next_header_filter(r); + } + + /* source_charset != charset */ + + if (r->headers_out.content_encoding + && r->headers_out.content_encoding->value.len) + { + return ngx_http_next_header_filter(r); + } + mcf = ngx_http_get_module_main_conf(r, ngx_http_charset_filter_module); charsets = mcf->charsets.elts; - if (source_charset != charset - && (charsets[source_charset].tables == NULL - || charsets[source_charset].tables[charset] == NULL)) + if (charsets[source_charset].tables == NULL + || charsets[source_charset].tables[charset] == NULL) { goto no_charset_map; } @@ -286,11 +301,7 @@ ngx_http_set_charset(r, &dst); - if (source_charset != charset) { - return ngx_http_charset_ctx(r, charsets, charset, source_charset); - } - - return ngx_http_next_header_filter(r); + return ngx_http_charset_ctx(r, charsets, charset, source_charset); no_charset_map: @@ -311,13 +322,6 @@ ngx_http_charset_loc_conf_t *mlcf; ngx_http_charset_main_conf_t *mcf; - if (!r->ignore_content_encoding - && r->headers_out.content_encoding - && r->headers_out.content_encoding->value.len) - { - return NGX_DECLINED; - } - if (r->headers_out.content_type.len == 0) { return NGX_DECLINED; } | ||
[+] | Changed | nginx-1.7.1.tar.gz/src/http/modules/ngx_http_gzip_static_module.c ^ |
@@ -246,8 +246,6 @@ ngx_str_set(&h->value, "gzip"); r->headers_out.content_encoding = h; - r->ignore_content_encoding = 1; - /* we need to allocate all before the header would be sent */ b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); | ||
[+] | Changed | nginx-1.7.1.tar.gz/src/http/modules/ngx_http_log_module.c ^ |
@@ -66,7 +66,9 @@ ngx_http_log_script_t *script; time_t disk_full_time; time_t error_log_time; + ngx_syslog_peer_t *syslog_peer; ngx_http_log_fmt_t *format; + ngx_http_complex_value_t *filter; } ngx_http_log_t; @@ -239,7 +241,9 @@ ngx_http_log_handler(ngx_http_request_t *r) { u_char *line, *p; - size_t len; + size_t len, size; + ssize_t n; + ngx_str_t val; ngx_uint_t i, l; ngx_http_log_t *log; ngx_http_log_op_t *op; @@ -258,6 +262,16 @@ log = lcf->logs->elts; for (l = 0; l < lcf->logs->nelts; l++) { + if (log[l].filter) { + if (ngx_http_complex_value(r, log[l].filter, &val) != NGX_OK) { + return NGX_ERROR; + } + + if (val.len == 0 || (val.len == 1 && val.data[0] == '0')) { + continue; + } + } + if (ngx_time() == log[l].disk_full_time) { /* @@ -282,6 +296,16 @@ } } + if (log[l].syslog_peer) { + + /* length of syslog's PRI and HEADER message parts */ + len += sizeof("<255>Jan 01 00:00:00 ") - 1 + + ngx_cycle->hostname.len + 1 + + log[l].syslog_peer->tag.len + 2; + + goto alloc_line; + } + len += NGX_LINEFEED_SIZE; buffer = log[l].file ? log[l].file->data : NULL; @@ -320,6 +344,8 @@ } } + alloc_line: + line = ngx_pnalloc(r->pool, len); if (line == NULL) { return NGX_ERROR; @@ -327,10 +353,33 @@ p = line; + if (log[l].syslog_peer) { + p = ngx_syslog_add_header(log[l].syslog_peer, line); + } + for (i = 0; i < log[l].format->ops->nelts; i++) { p = op[i].run(r, p, &op[i]); } + if (log[l].syslog_peer) { + + size = p - line; + + n = ngx_syslog_send(log[l].syslog_peer, line, size); + + if (n < 0) { + ngx_log_error(NGX_LOG_WARN, r->connection->log, 0, + "send() to syslog failed"); + + } else if ((size_t) n != size) { + ngx_log_error(NGX_LOG_WARN, r->connection->log, 0, + "send() to syslog has written only %z of %uz", + n, size); + } + + continue; + } + ngx_linefeed(p); ngx_http_log_write(r, &log[l], line, p - line); @@ -1068,6 +1117,7 @@ log->script = NULL; log->disk_full_time = 0; log->error_log_time = 0; + log->syslog_peer = NULL; lmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_log_module); fmt = lmcf->formats.elts; @@ -1085,16 +1135,18 @@ { ngx_http_log_loc_conf_t *llcf = conf; - ssize_t size; - ngx_int_t gzip; - ngx_uint_t i, n; - ngx_msec_t flush; - ngx_str_t *value, name, s; - ngx_http_log_t *log; - ngx_http_log_buf_t *buffer; - ngx_http_log_fmt_t *fmt; - ngx_http_log_main_conf_t *lmcf; - ngx_http_script_compile_t sc; + ssize_t size; + ngx_int_t gzip; + ngx_uint_t i, n; + ngx_msec_t flush; + ngx_str_t *value, name, s, filter; + ngx_http_log_t *log; + ngx_syslog_peer_t *peer; + ngx_http_log_buf_t *buffer; + ngx_http_log_fmt_t *fmt; + ngx_http_log_main_conf_t *lmcf; + ngx_http_script_compile_t sc; + ngx_http_compile_complex_value_t ccv; value = cf->args->elts; @@ -1125,6 +1177,23 @@ ngx_memzero(log, sizeof(ngx_http_log_t)); + + if (ngx_strncmp(value[1].data, "syslog:", 7) == 0) { + + peer = ngx_pcalloc(cf->pool, sizeof(ngx_syslog_peer_t)); + if (peer == NULL) { + return NGX_CONF_ERROR; + } + + if (ngx_syslog_process_conf(cf, peer) != NGX_CONF_OK) { + return NGX_CONF_ERROR; + } + + log->syslog_peer = peer; + + goto process_formats; + } + n = ngx_http_script_variables_count(&value[1]); if (n == 0) { @@ -1158,6 +1227,8 @@ } } +process_formats: + if (cf->args->nelts >= 3) { name = value[2]; @@ -1186,9 +1257,21 @@ return NGX_CONF_ERROR; } + if (log->syslog_peer != NULL) { + if (cf->args->nelts > 3) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "parameter \"%V\" is not supported by syslog", + &value[3]); + return NGX_CONF_ERROR; + } + + return NGX_CONF_OK; + } + size = 0; flush = 0; gzip = 0; + filter.len = 0; for (i = 3; i < cf->args->nelts; i++) { @@ -1255,6 +1338,12 @@ #endif } + if (ngx_strncmp(value[i].data, "if=", 3) == 0) { + filter.len = value[i].len - 3; + filter.data = value[i].data + 3; + continue; + } + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", &value[i]); return NGX_CONF_ERROR; @@ -1324,6 +1413,23 @@ log->file->data = buffer; } + if (filter.len) { + log->filter = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t)); + if (log->filter == NULL) { + return NGX_CONF_ERROR; + } + + ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); + + ccv.cf = cf; + ccv.value = &filter; + ccv.complex_value = log->filter; + + if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { + return NGX_CONF_ERROR; + } + } + return NGX_CONF_OK; } | ||
[+] | Changed | nginx-1.7.1.tar.gz/src/http/modules/ngx_http_proxy_module.c ^ |
@@ -81,6 +81,9 @@ ngx_uint_t ssl; ngx_uint_t ssl_protocols; ngx_str_t ssl_ciphers; + ngx_uint_t ssl_verify_depth; + ngx_str_t ssl_trusted_certificate; + ngx_str_t ssl_crl; #endif } ngx_http_proxy_loc_conf_t; @@ -553,6 +556,48 @@ offsetof(ngx_http_proxy_loc_conf_t, ssl_ciphers), NULL }, + { ngx_string("proxy_ssl_name"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_http_set_complex_value_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_proxy_loc_conf_t, upstream.ssl_name), + NULL }, + + { ngx_string("proxy_ssl_server_name"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_proxy_loc_conf_t, upstream.ssl_server_name), + NULL }, + + { ngx_string("proxy_ssl_verify"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_proxy_loc_conf_t, upstream.ssl_verify), + NULL }, + + { ngx_string("proxy_ssl_verify_depth"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_num_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_proxy_loc_conf_t, ssl_verify_depth), + NULL }, + + { ngx_string("proxy_ssl_trusted_certificate"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_str_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_proxy_loc_conf_t, ssl_trusted_certificate), + NULL }, + + { ngx_string("proxy_ssl_crl"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_str_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_proxy_loc_conf_t, ssl_crl), + NULL }, + #endif ngx_null_command @@ -1249,7 +1294,7 @@ } ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http proxy header:\n\"%*s\"", + "http proxy header:%N\"%*s\"", (size_t) (b->last - b->pos), b->pos); if (plcf->body_set == NULL && plcf->upstream.pass_request_body) { @@ -2320,7 +2365,7 @@ if (replacement->len > len) { - data = ngx_pnalloc(r->pool, new_len); + data = ngx_pnalloc(r->pool, new_len + 1); if (data == NULL) { return NGX_ERROR; } @@ -2329,7 +2374,7 @@ p = ngx_copy(p, replacement->data, replacement->len); ngx_memcpy(p, h->value.data + prefix + len, - h->value.len - len - prefix); + h->value.len - len - prefix + 1); h->value.data = data; @@ -2338,7 +2383,7 @@ replacement->len); ngx_memmove(p, h->value.data + prefix + len, - h->value.len - len - prefix); + h->value.len - len - prefix + 1); } h->value.len = new_len; @@ -2390,6 +2435,7 @@ * conf->upstream.location = NULL; * conf->upstream.store_lengths = NULL; * conf->upstream.store_values = NULL; + * conf->upstream.ssl_name = NULL; * * conf->method = { 0, NULL }; * conf->headers_source = NULL; @@ -2403,6 +2449,8 @@ * conf->ssl = 0; * conf->ssl_protocols = 0; * conf->ssl_ciphers = { 0, NULL }; + * conf->ssl_trusted_certificate = { 0, NULL }; + * conf->ssl_crl = { 0, NULL }; */ conf->upstream.store = NGX_CONF_UNSET; @@ -2441,8 +2489,12 @@ conf->upstream.pass_headers = NGX_CONF_UNSET_PTR; conf->upstream.intercept_errors = NGX_CONF_UNSET; + #if (NGX_HTTP_SSL) conf->upstream.ssl_session_reuse = NGX_CONF_UNSET; + conf->upstream.ssl_server_name = NGX_CONF_UNSET; + conf->upstream.ssl_verify = NGX_CONF_UNSET; + conf->ssl_verify_depth = NGX_CONF_UNSET_UINT; #endif /* "proxy_cyclic_temp_file" is disabled */ @@ -2714,6 +2766,7 @@ prev->upstream.intercept_errors, 0); #if (NGX_HTTP_SSL) + ngx_conf_merge_value(conf->upstream.ssl_session_reuse, prev->upstream.ssl_session_reuse, 1); @@ -2725,9 +2778,24 @@ ngx_conf_merge_str_value(conf->ssl_ciphers, prev->ssl_ciphers, "DEFAULT"); + if (conf->upstream.ssl_name == NULL) { + conf->upstream.ssl_name = prev->upstream.ssl_name; + } + + ngx_conf_merge_value(conf->upstream.ssl_server_name, + prev->upstream.ssl_server_name, 0); + ngx_conf_merge_value(conf->upstream.ssl_verify, + prev->upstream.ssl_verify, 0); + ngx_conf_merge_uint_value(conf->ssl_verify_depth, + prev->ssl_verify_depth, 1); + ngx_conf_merge_str_value(conf->ssl_trusted_certificate, + prev->ssl_trusted_certificate, ""); + ngx_conf_merge_str_value(conf->ssl_crl, prev->ssl_crl, ""); + if (conf->ssl && ngx_http_proxy_set_ssl(cf, conf) != NGX_OK) { return NGX_CONF_ERROR; } + #endif ngx_conf_merge_value(conf->redirect, prev->redirect, 1); @@ -3774,6 +3842,14 @@ return NGX_ERROR; } + cln = ngx_pool_cleanup_add(cf->pool, 0); + if (cln == NULL) { + return NGX_ERROR; + } + + cln->handler = ngx_ssl_cleanup_ctx; + cln->data = plcf->upstream.ssl; + if (SSL_CTX_set_cipher_list(plcf->upstream.ssl->ctx, (const char *) plcf->ssl_ciphers.data) == 0) @@ -3784,13 +3860,25 @@ return NGX_ERROR; } - cln = ngx_pool_cleanup_add(cf->pool, 0); - if (cln == NULL) { - return NGX_ERROR; - } + if (plcf->upstream.ssl_verify) { + if (plcf->ssl_trusted_certificate.len == 0) { + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, + "no proxy_ssl_trusted_certificate for proxy_ssl_verify"); + return NGX_ERROR; + } - cln->handler = ngx_ssl_cleanup_ctx; - cln->data = plcf->upstream.ssl; + if (ngx_ssl_trusted_certificate(cf, plcf->upstream.ssl, + &plcf->ssl_trusted_certificate, + plcf->ssl_verify_depth) + != NGX_OK) + { + return NGX_ERROR; + } + + if (ngx_ssl_crl(cf, plcf->upstream.ssl, &plcf->ssl_crl) != NGX_OK) { + return NGX_ERROR; + } + } return NGX_OK; } | ||
[+] | Changed | nginx-1.7.1.tar.gz/src/http/modules/ngx_http_ssl_module.c ^ |
@@ -273,6 +273,9 @@ { ngx_string("ssl_session_reused"), NULL, ngx_http_ssl_variable, (uintptr_t) ngx_ssl_get_session_reused, NGX_HTTP_VAR_CHANGEABLE, 0 }, + { ngx_string("ssl_server_name"), NULL, ngx_http_ssl_variable, + (uintptr_t) ngx_ssl_get_server_name, NGX_HTTP_VAR_CHANGEABLE, 0 }, + { ngx_string("ssl_client_cert"), NULL, ngx_http_ssl_variable, (uintptr_t) ngx_ssl_get_certificate, NGX_HTTP_VAR_CHANGEABLE, 0 }, @@ -289,6 +292,9 @@ { 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_fingerprint"), NULL, ngx_http_ssl_variable, + (uintptr_t) ngx_ssl_get_fingerprint, 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 }, | ||
[+] | Changed | nginx-1.7.1.tar.gz/src/http/modules/ngx_http_sub_filter_module.c ^ |
@@ -305,6 +305,7 @@ b->last = ctx->copy_end; b->shadow = NULL; b->last_buf = 0; + b->last_in_chain = 0; b->recycled = 0; if (b->in_file) { @@ -374,7 +375,9 @@ continue; } - if (ctx->buf->last_buf && ctx->looked.len) { + if (ctx->looked.len + && (ctx->buf->last_buf || ctx->buf->last_in_chain)) + { cl = ngx_chain_get_free_buf(r->pool, &ctx->free); if (cl == NULL) { return NGX_ERROR; @@ -394,7 +397,7 @@ ctx->looked.len = 0; } - if (ctx->buf->last_buf || ctx->buf->flush + if (ctx->buf->last_buf || ctx->buf->flush || ctx->buf->sync || ngx_buf_in_memory(ctx->buf)) { if (b == NULL) { @@ -414,6 +417,7 @@ } b->last_buf = ctx->buf->last_buf; + b->last_in_chain = ctx->buf->last_in_chain; b->flush = ctx->buf->flush; b->shadow = ctx->buf; | ||
[+] | Changed | nginx-1.7.1.tar.gz/src/http/modules/ngx_http_upstream_ip_hash_module.c ^ |
@@ -231,7 +231,7 @@ next: - if (++iphp->tries >= 20) { + if (++iphp->tries > 20) { return iphp->get_rr_peer(pc, &iphp->rrp); } } | ||
[+] | Changed | nginx-1.7.1.tar.gz/src/http/modules/ngx_http_uwsgi_module.c ^ |
@@ -39,6 +39,9 @@ ngx_uint_t ssl; ngx_uint_t ssl_protocols; ngx_str_t ssl_ciphers; + ngx_uint_t ssl_verify_depth; + ngx_str_t ssl_trusted_certificate; + ngx_str_t ssl_crl; #endif } ngx_http_uwsgi_loc_conf_t; @@ -409,6 +412,48 @@ offsetof(ngx_http_uwsgi_loc_conf_t, ssl_ciphers), NULL }, + { ngx_string("uwsgi_ssl_name"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_http_set_complex_value_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_uwsgi_loc_conf_t, upstream.ssl_name), + NULL }, + + { ngx_string("uwsgi_ssl_server_name"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_uwsgi_loc_conf_t, upstream.ssl_server_name), + NULL }, + + { ngx_string("uwsgi_ssl_verify"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_uwsgi_loc_conf_t, upstream.ssl_verify), + NULL }, + + { ngx_string("uwsgi_ssl_verify_depth"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_num_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_uwsgi_loc_conf_t, ssl_verify_depth), + NULL }, + + { ngx_string("uwsgi_ssl_trusted_certificate"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_str_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_uwsgi_loc_conf_t, ssl_trusted_certificate), + NULL }, + + { ngx_string("uwsgi_ssl_crl"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_str_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_uwsgi_loc_conf_t, ssl_crl), + NULL }, + #endif ngx_null_command @@ -1243,8 +1288,12 @@ conf->upstream.pass_headers = NGX_CONF_UNSET_PTR; conf->upstream.intercept_errors = NGX_CONF_UNSET; + #if (NGX_HTTP_SSL) conf->upstream.ssl_session_reuse = NGX_CONF_UNSET; + conf->upstream.ssl_server_name = NGX_CONF_UNSET; + conf->upstream.ssl_verify = NGX_CONF_UNSET; + conf->ssl_verify_depth = NGX_CONF_UNSET_UINT; #endif /* "uwsgi_cyclic_temp_file" is disabled */ @@ -1494,6 +1543,7 @@ prev->upstream.intercept_errors, 0); #if (NGX_HTTP_SSL) + ngx_conf_merge_value(conf->upstream.ssl_session_reuse, prev->upstream.ssl_session_reuse, 1); @@ -1505,6 +1555,20 @@ ngx_conf_merge_str_value(conf->ssl_ciphers, prev->ssl_ciphers, "DEFAULT"); + if (conf->upstream.ssl_name == NULL) { + conf->upstream.ssl_name = prev->upstream.ssl_name; + } + + ngx_conf_merge_value(conf->upstream.ssl_server_name, + prev->upstream.ssl_server_name, 0); + ngx_conf_merge_value(conf->upstream.ssl_verify, + prev->upstream.ssl_verify, 0); + ngx_conf_merge_uint_value(conf->ssl_verify_depth, + prev->ssl_verify_depth, 1); + ngx_conf_merge_str_value(conf->ssl_trusted_certificate, + prev->ssl_trusted_certificate, ""); + ngx_conf_merge_str_value(conf->ssl_crl, prev->ssl_crl, ""); + if (conf->ssl && ngx_http_uwsgi_set_ssl(cf, conf) != NGX_OK) { return NGX_CONF_ERROR; } @@ -1512,6 +1576,7 @@ if (conf->upstream.ssl == NULL) { conf->upstream.ssl = prev->upstream.ssl; } + #endif ngx_conf_merge_str_value(conf->uwsgi_string, prev->uwsgi_string, ""); @@ -2012,6 +2077,14 @@ return NGX_ERROR; } + cln = ngx_pool_cleanup_add(cf->pool, 0); + if (cln == NULL) { + return NGX_ERROR; + } + + cln->handler = ngx_ssl_cleanup_ctx; + cln->data = uwcf->upstream.ssl; + if (SSL_CTX_set_cipher_list(uwcf->upstream.ssl->ctx, (const char *) uwcf->ssl_ciphers.data) == 0) @@ -2022,13 +2095,25 @@ return NGX_ERROR; } - cln = ngx_pool_cleanup_add(cf->pool, 0); - if (cln == NULL) { - return NGX_ERROR; - } + if (uwcf->upstream.ssl_verify) { + if (uwcf->ssl_trusted_certificate.len == 0) { + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, + "no uwsgi_ssl_trusted_certificate for uwsgi_ssl_verify"); + return NGX_ERROR; + } - cln->handler = ngx_ssl_cleanup_ctx; - cln->data = uwcf->upstream.ssl; + if (ngx_ssl_trusted_certificate(cf, uwcf->upstream.ssl, + &uwcf->ssl_trusted_certificate, + uwcf->ssl_verify_depth) + != NGX_OK) + { + return NGX_ERROR; + } + + if (ngx_ssl_crl(cf, uwcf->upstream.ssl, &uwcf->ssl_crl) != NGX_OK) { + return NGX_ERROR; + } + } return NGX_OK; } | ||
[+] | Changed | nginx-1.7.1.tar.gz/src/http/ngx_http.h ^ |
@@ -105,6 +105,8 @@ ngx_uint_t allow_underscores); ngx_int_t ngx_http_parse_multi_header_lines(ngx_array_t *headers, ngx_str_t *name, ngx_str_t *value); +ngx_int_t ngx_http_parse_set_cookie_lines(ngx_array_t *headers, + ngx_str_t *name, ngx_str_t *value); ngx_int_t ngx_http_arg(ngx_http_request_t *r, u_char *name, size_t len, ngx_str_t *value); void ngx_http_split_args(ngx_http_request_t *r, ngx_str_t *uri, | ||
[+] | Changed | nginx-1.7.1.tar.gz/src/http/ngx_http_core_module.c ^ |
@@ -1245,10 +1245,8 @@ if (!alias) { reserve = len > r->uri.len ? len - r->uri.len : 0; -#if (NGX_PCRE) - } else if (clcf->regex) { + } else if (alias == NGX_MAX_SIZE_T_VALUE) { reserve = len; -#endif } else { reserve = len > r->uri.len - alias ? len - (r->uri.len - alias) : 0; @@ -1365,13 +1363,12 @@ if (!alias) { r->uri = path; -#if (NGX_PCRE) - } else if (clcf->regex) { + } else if (alias == NGX_MAX_SIZE_T_VALUE) { if (!test_dir) { r->uri = path; r->add_uri_to_alias = 1; } -#endif + } else { r->uri.len = alias + path.len; r->uri.data = ngx_pnalloc(r->pool, r->uri.len); @@ -2006,16 +2003,12 @@ } else { -#if (NGX_PCRE) - ngx_uint_t captures; - - captures = alias && clcf->regex; + if (alias == NGX_MAX_SIZE_T_VALUE) { + reserved += r->add_uri_to_alias ? r->uri.len + 1 : 1; - reserved += captures ? r->add_uri_to_alias ? r->uri.len + 1 : 1 - : r->uri.len - alias + 1; -#else - reserved += r->uri.len - alias + 1; -#endif + } else { + reserved += r->uri.len - alias + 1; + } if (ngx_http_script_run(r, path, clcf->root_lengths->elts, reserved, clcf->root_values->elts) @@ -2033,8 +2026,7 @@ *root_length = path->len - reserved; last = path->data + *root_length; -#if (NGX_PCRE) - if (captures) { + if (alias == NGX_MAX_SIZE_T_VALUE) { if (!r->add_uri_to_alias) { *last = '\0'; return last; @@ -2042,7 +2034,6 @@ alias = 0; } -#endif } last = ngx_cpystrn(last, r->uri.data + alias, r->uri.len - alias + 1); @@ -4476,6 +4467,7 @@ #if (NGX_PCRE) if (alias && clcf->regex) { + clcf->alias = NGX_MAX_SIZE_T_VALUE; n = 1; } #endif | ||
[+] | Changed | nginx-1.7.1.tar.gz/src/http/ngx_http_file_cache.c ^ |
@@ -1313,6 +1313,11 @@ for ( ;; ) { + if (ngx_quit || ngx_terminate) { + wait = 1; + break; + } + if (ngx_queue_empty(&cache->sh->queue)) { wait = 10; break; | ||
[+] | Changed | nginx-1.7.1.tar.gz/src/http/ngx_http_parse.c ^ |
@@ -1985,6 +1985,57 @@ ngx_int_t +ngx_http_parse_set_cookie_lines(ngx_array_t *headers, ngx_str_t *name, + ngx_str_t *value) +{ + ngx_uint_t i; + u_char *start, *last, *end; + ngx_table_elt_t **h; + + h = headers->elts; + + for (i = 0; i < headers->nelts; i++) { + + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, headers->pool->log, 0, + "parse header: \"%V: %V\"", &h[i]->key, &h[i]->value); + + if (name->len >= h[i]->value.len) { + continue; + } + + start = h[i]->value.data; + end = h[i]->value.data + h[i]->value.len; + + if (ngx_strncasecmp(start, name->data, name->len) != 0) { + continue; + } + + for (start += name->len; start < end && *start == ' '; start++) { + /* void */ + } + + if (start == end || *start++ != '=') { + /* the invalid header value */ + continue; + } + + while (start < end && *start == ' ') { start++; } + + for (last = start; last < end && *last != ';'; last++) { + /* void */ + } + + value->len = last - start; + value->data = start; + + return i; + } + + return NGX_DECLINED; +} + + +ngx_int_t ngx_http_arg(ngx_http_request_t *r, u_char *name, size_t len, ngx_str_t *value) { u_char *p, *last; | ||
[+] | Changed | nginx-1.7.1.tar.gz/src/http/ngx_http_request.h ^ |
@@ -511,7 +511,6 @@ unsigned discard_body:1; unsigned internal:1; unsigned error_page:1; - unsigned ignore_content_encoding:1; unsigned filter_finalize:1; unsigned post_action:1; unsigned request_complete:1; @@ -588,6 +587,8 @@ \ c->log->file = l->file; \ c->log->next = l->next; \ + c->log->writer = l->writer; \ + c->log->wdata = l->wdata; \ if (!(c->log->log_level & NGX_LOG_DEBUG_CONNECTION)) { \ c->log->log_level = l->log_level; \ } | ||
[+] | Changed | nginx-1.7.1.tar.gz/src/http/ngx_http_spdy.c ^ |
@@ -103,10 +103,10 @@ u_char *pos, u_char *end); static u_char *ngx_http_spdy_state_headers(ngx_http_spdy_connection_t *sc, u_char *pos, u_char *end); -static u_char *ngx_http_spdy_state_headers_error(ngx_http_spdy_connection_t *sc, - u_char *pos, u_char *end); static u_char *ngx_http_spdy_state_headers_skip(ngx_http_spdy_connection_t *sc, u_char *pos, u_char *end); +static u_char *ngx_http_spdy_state_headers_error(ngx_http_spdy_connection_t *sc, + u_char *pos, u_char *end); static u_char *ngx_http_spdy_state_window_update(ngx_http_spdy_connection_t *sc, u_char *pos, u_char *end); static u_char *ngx_http_spdy_state_data(ngx_http_spdy_connection_t *sc, @@ -125,6 +125,9 @@ u_char *pos, u_char *end); static u_char *ngx_http_spdy_state_save(ngx_http_spdy_connection_t *sc, u_char *pos, u_char *end, ngx_http_spdy_handler_pt handler); + +static u_char *ngx_http_spdy_state_inflate_error( + ngx_http_spdy_connection_t *sc, int rc); static u_char *ngx_http_spdy_state_protocol_error( ngx_http_spdy_connection_t *sc); static u_char *ngx_http_spdy_state_internal_error( @@ -392,8 +395,7 @@ c = rev->data; hc = c->data; - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, - "init spdy request"); + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "init spdy request"); c->log->action = "processing SPDY"; @@ -421,12 +423,8 @@ sc->init_window = NGX_SPDY_INIT_STREAM_WINDOW; - sc->handler = ngx_http_spdy_state_head; - - if (hc->proxy_protocol) { - c->log->action = "reading PROXY protocol"; - sc->handler = ngx_http_spdy_proxy_protocol; - } + sc->handler = hc->proxy_protocol ? ngx_http_spdy_proxy_protocol + : ngx_http_spdy_state_head; sc->zstream_in.zalloc = ngx_http_spdy_zalloc; sc->zstream_in.zfree = ngx_http_spdy_zfree; @@ -557,7 +555,7 @@ if (n == 0 && (sc->incomplete || sc->processing)) { ngx_log_error(NGX_LOG_INFO, c->log, 0, - "client closed prematurely connection"); + "client prematurely closed connection"); } if (n == 0 || n == NGX_ERROR) { @@ -645,7 +643,7 @@ stream->handled = 0; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, - "spdy run stream %ui", stream->id); + "run spdy stream %ui", stream->id); wev = stream->request->connection->write; wev->handler(wev); @@ -820,14 +818,19 @@ ngx_http_spdy_proxy_protocol(ngx_http_spdy_connection_t *sc, u_char *pos, u_char *end) { + ngx_log_t *log; + + log = sc->connection->log; + log->action = "reading PROXY protocol"; + pos = ngx_proxy_protocol_parse(sc->connection, pos, end); + log->action = "processing SPDY"; + if (pos == NULL) { return ngx_http_spdy_state_protocol_error(sc); } - sc->connection->log->action = "processing SPDY"; - return ngx_http_spdy_state_complete(sc, pos, end); } @@ -856,7 +859,7 @@ pos += sizeof(uint32_t); ngx_log_debug3(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0, - "spdy process frame head:%08XD f:%Xd l:%uz", + "process spdy frame head:%08XD f:%Xd l:%uz", head, sc->flags, sc->length); if (ngx_spdy_ctl_frame_check(head)) { @@ -868,6 +871,8 @@ return ngx_http_spdy_state_syn_stream(sc, pos, end); case NGX_SPDY_SYN_REPLY: + ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0, + "client sent unexpected SYN_REPLY frame"); return ngx_http_spdy_state_protocol_error(sc); case NGX_SPDY_RST_STREAM: @@ -883,6 +888,8 @@ return ngx_http_spdy_state_skip(sc, pos, end); /* TODO */ case NGX_SPDY_HEADERS: + ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0, + "client sent unexpected HEADERS frame"); return ngx_http_spdy_state_protocol_error(sc); case NGX_SPDY_WINDOW_UPDATE: @@ -900,10 +907,8 @@ return ngx_http_spdy_state_data(sc, pos, end); } - - /* TODO version & type check */ - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0, - "spdy unknown frame"); + ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0, + "client sent invalid frame"); return ngx_http_spdy_state_protocol_error(sc); } @@ -923,7 +928,10 @@ } if (sc->length <= NGX_SPDY_SYN_STREAM_SIZE) { - /* TODO logging */ + ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0, + "client sent SYN_STREAM frame with incorrect length %uz", + sc->length); + return ngx_http_spdy_state_protocol_error(sc); } @@ -937,13 +945,34 @@ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0, "spdy SYN_STREAM frame sid:%ui prio:%ui", sid, prio); + if (sid % 2 == 0 || sid <= sc->last_sid) { + ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0, + "client sent SYN_STREAM frame " + "with invalid Stream-ID %ui", sid); + + stream = ngx_http_spdy_get_stream_by_id(sc, sid); + + if (stream) { + if (ngx_http_spdy_terminate_stream(sc, stream, + NGX_SPDY_PROTOCOL_ERROR) + != NGX_OK) + { + return ngx_http_spdy_state_internal_error(sc); + } + } + + return ngx_http_spdy_state_protocol_error(sc); + } + + sc->last_sid = sid; + sscf = ngx_http_get_module_srv_conf(sc->http_connection->conf_ctx, ngx_http_spdy_module); if (sc->processing >= sscf->concurrent_streams) { ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0, - "spdy concurrent streams exceeded %ui", sc->processing); + "concurrent streams exceeded %ui", sc->processing); if (ngx_http_spdy_send_rst_stream(sc, sid, NGX_SPDY_REFUSED_STREAM, prio) @@ -968,8 +997,6 @@ sc->stream = stream; - sc->last_sid = sid; - return ngx_http_spdy_state_headers(sc, pos, end); } @@ -982,7 +1009,6 @@ size_t size; ngx_buf_t *buf; ngx_int_t rc; - ngx_uint_t complete; ngx_http_request_t *r; size = end - pos; @@ -992,18 +1018,14 @@ ngx_http_spdy_state_headers); } - if (size >= sc->length) { + if (size > sc->length) { size = sc->length; - complete = 1; - - } else { - complete = 0; } r = sc->stream->request; ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "spdy process HEADERS %uz of %uz", size, sc->length); + "process spdy header block %uz of %uz", size, sc->length); buf = r->header_in; @@ -1019,11 +1041,21 @@ if (z == Z_NEED_DICT) { z = inflateSetDictionary(&sc->zstream_in, ngx_http_spdy_dict, sizeof(ngx_http_spdy_dict)); + if (z != Z_OK) { - ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, - "spdy inflateSetDictionary() failed: %d", z); - ngx_http_spdy_close_stream(sc->stream, 0); - return ngx_http_spdy_state_protocol_error(sc); + if (z == Z_DATA_ERROR) { + ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, + "client sent SYN_STREAM frame with header " + "block encoded using wrong dictionary: %ul", + (u_long) sc->zstream_in.adler); + + return ngx_http_spdy_state_protocol_error(sc); + } + + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "inflateSetDictionary() failed: %d", z); + + return ngx_http_spdy_state_internal_error(sc); } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, @@ -1034,10 +1066,7 @@ } if (z != Z_OK) { - ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, - "spdy inflate() failed: %d", z); - ngx_http_spdy_close_stream(sc->stream, 0); - return ngx_http_spdy_state_protocol_error(sc); + return ngx_http_spdy_state_inflate_error(sc, z); } ngx_log_debug5(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, @@ -1055,12 +1084,11 @@ if (buf->last - buf->pos < NGX_SPDY_NV_NUM_SIZE) { - if (complete) { - ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, - "client sent SYN_STREAM frame " - "with invalid HEADERS block"); - ngx_http_spdy_close_stream(sc->stream, NGX_HTTP_BAD_REQUEST); - return ngx_http_spdy_state_protocol_error(sc); + if (sc->length == 0) { + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "premature end of spdy header block"); + + return ngx_http_spdy_state_headers_error(sc, pos, end); } return ngx_http_spdy_state_save(sc, pos, end, @@ -1072,7 +1100,7 @@ buf->pos += NGX_SPDY_NV_NUM_SIZE; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "spdy HEADERS block consists of %ui entries", + "spdy header block has %ui entries", sc->entries); if (ngx_list_init(&r->headers_in.headers, r->pool, 20, @@ -1081,7 +1109,7 @@ { ngx_http_spdy_close_stream(sc->stream, NGX_HTTP_INTERNAL_SERVER_ERROR); - return ngx_http_spdy_state_headers_error(sc, pos, end); + return ngx_http_spdy_state_headers_skip(sc, pos, end); } if (ngx_array_init(&r->headers_in.cookies, r->pool, 2, @@ -1090,7 +1118,7 @@ { ngx_http_spdy_close_stream(sc->stream, NGX_HTTP_INTERNAL_SERVER_ERROR); - return ngx_http_spdy_state_headers_error(sc, pos, end); + return ngx_http_spdy_state_headers_skip(sc, pos, end); } } @@ -1113,16 +1141,15 @@ rc = ngx_http_spdy_alloc_large_header_buffer(r); if (rc == NGX_DECLINED) { - /* TODO logging */ ngx_http_finalize_request(r, NGX_HTTP_REQUEST_HEADER_TOO_LARGE); - return ngx_http_spdy_state_headers_error(sc, pos, end); + return ngx_http_spdy_state_headers_skip(sc, pos, end); } if (rc != NGX_OK) { ngx_http_spdy_close_stream(sc->stream, NGX_HTTP_INTERNAL_SERVER_ERROR); - return ngx_http_spdy_state_headers_error(sc, pos, end); + return ngx_http_spdy_state_headers_skip(sc, pos, end); } /* null-terminate the last processed header name or value */ @@ -1138,10 +1165,7 @@ z = inflate(&sc->zstream_in, Z_NO_FLUSH); if (z != Z_OK) { - ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, - "spdy inflate() failed: %d", z); - ngx_http_spdy_close_stream(sc->stream, 0); - return ngx_http_spdy_state_protocol_error(sc); + return ngx_http_spdy_state_inflate_error(sc, z); } sc->length -= sc->zstream_in.next_in - pos; @@ -1152,33 +1176,22 @@ continue; } - if (complete) { - /* TODO: improve error message */ + if (sc->length == 0) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "spdy again while last chunk"); - ngx_http_spdy_close_stream(sc->stream, 0); - return ngx_http_spdy_state_protocol_error(sc); + "premature end of spdy header block"); + + return ngx_http_spdy_state_headers_error(sc, pos, end); } return ngx_http_spdy_state_save(sc, pos, end, ngx_http_spdy_state_headers); - case NGX_HTTP_PARSE_INVALID_REQUEST: - - /* TODO: improve error message */ - ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, - "client sent invalid header line"); - + case NGX_HTTP_PARSE_INVALID_HEADER: ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); + return ngx_http_spdy_state_headers_skip(sc, pos, end); + default: /* NGX_ERROR */ return ngx_http_spdy_state_headers_error(sc, pos, end); - - default: /* NGX_HTTP_PARSE_INVALID_HEADER */ - - ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, - "client sent invalid HEADERS spdy frame"); - ngx_http_spdy_close_stream(sc->stream, NGX_HTTP_BAD_REQUEST); - return ngx_http_spdy_state_protocol_error(sc); } /* a header line has been parsed successfully */ @@ -1187,29 +1200,27 @@ if (rc != NGX_OK) { if (rc == NGX_HTTP_PARSE_INVALID_HEADER) { - ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, - "client sent invalid HEADERS spdy frame"); - ngx_http_spdy_close_stream(sc->stream, NGX_HTTP_BAD_REQUEST); - return ngx_http_spdy_state_protocol_error(sc); + ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); + return ngx_http_spdy_state_headers_skip(sc, pos, end); } - if (rc == NGX_HTTP_PARSE_INVALID_REQUEST) { - ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); + if (rc != NGX_ABORT) { + ngx_http_spdy_close_stream(sc->stream, + NGX_HTTP_INTERNAL_SERVER_ERROR); } - return ngx_http_spdy_state_headers_error(sc, pos, end); + return ngx_http_spdy_state_headers_skip(sc, pos, end); } } if (buf->pos != buf->last || sc->zstream_in.avail_in) { - ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, - "client sent SYN_STREAM frame " - "with invalid HEADERS block"); - ngx_http_spdy_close_stream(sc->stream, NGX_HTTP_BAD_REQUEST); - return ngx_http_spdy_state_protocol_error(sc); + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "incorrect number of spdy header block entries"); + + return ngx_http_spdy_state_headers_error(sc, pos, end); } - if (!complete) { + if (sc->length) { return ngx_http_spdy_state_save(sc, pos, end, ngx_http_spdy_state_headers); } @@ -1224,18 +1235,6 @@ static u_char * -ngx_http_spdy_state_headers_error(ngx_http_spdy_connection_t *sc, u_char *pos, - u_char *end) -{ - if (sc->connection->error) { - return ngx_http_spdy_state_internal_error(sc); - } - - return ngx_http_spdy_state_headers_skip(sc, pos, end); -} - - -static u_char * ngx_http_spdy_state_headers_skip(ngx_http_spdy_connection_t *sc, u_char *pos, u_char *end) { @@ -1254,6 +1253,9 @@ ngx_http_spdy_state_headers_skip); } + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0, + "spdy header block skip %uz of %uz", size, sc->length); + sc->zstream_in.next_in = pos; sc->zstream_in.avail_in = (size < sc->length) ? size : sc->length; @@ -1263,12 +1265,8 @@ n = inflate(&sc->zstream_in, Z_NO_FLUSH); - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0, - "spdy inflate(): %d", n); - if (n != Z_OK) { - /* TODO: logging */ - return ngx_http_spdy_state_protocol_error(sc); + return ngx_http_spdy_state_inflate_error(sc, n); } } @@ -1285,6 +1283,33 @@ static u_char * +ngx_http_spdy_state_headers_error(ngx_http_spdy_connection_t *sc, u_char *pos, + u_char *end) +{ + ngx_http_spdy_stream_t *stream; + + stream = sc->stream; + + ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0, + "client sent SYN_STREAM frame for stream %ui " + "with invalid header block", stream->id); + + if (ngx_http_spdy_send_rst_stream(sc, stream->id, NGX_SPDY_PROTOCOL_ERROR, + stream->priority) + != NGX_OK) + { + return ngx_http_spdy_state_internal_error(sc); + } + + stream->out_closed = 1; + + ngx_http_spdy_close_stream(stream, NGX_HTTP_BAD_REQUEST); + + return ngx_http_spdy_state_headers_skip(sc, pos, end); +} + + +static u_char * ngx_http_spdy_state_window_update(ngx_http_spdy_connection_t *sc, u_char *pos, u_char *end) { @@ -1322,16 +1347,8 @@ stream = ngx_http_spdy_get_stream_by_id(sc, sid); if (stream == NULL) { - ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0, - "client sent WINDOW_UPDATE frame " - "for unknown stream %ui", sid); - - if (ngx_http_spdy_send_rst_stream(sc, sid, NGX_SPDY_INVALID_STREAM, - NGX_SPDY_LOWEST_PRIORITY) - == NGX_ERROR) - { - return ngx_http_spdy_state_internal_error(sc); - } + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0, + "unknown spdy stream"); return ngx_http_spdy_state_complete(sc, pos, end); } @@ -1341,7 +1358,7 @@ ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0, "client violated flow control for stream %ui: " "received WINDOW_UPDATE frame with delta %uz " - "that is not allowed for window %z", + "not allowed for window %z", sid, delta, stream->send_window); if (ngx_http_spdy_terminate_stream(sc, stream, @@ -1374,7 +1391,7 @@ ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0, "client violated connection flow control: " "received WINDOW_UPDATE frame with delta %uz " - "that is not allowed for window %uz", + "not allowed for window %uz", delta, sc->send_window); return ngx_http_spdy_state_protocol_error(sc); @@ -1417,8 +1434,8 @@ if (sc->length > sc->recv_window) { ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0, - "client violated connection flow control: length of " - "received DATA frame %uz, while available window %uz", + "client violated connection flow control: " + "received DATA frame length %uz, available window %uz", sc->length, sc->recv_window); return ngx_http_spdy_state_protocol_error(sc); @@ -1442,13 +1459,16 @@ stream = sc->stream; if (stream == NULL) { + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0, + "unknown spdy stream"); + return ngx_http_spdy_state_skip(sc, pos, end); } if (sc->length > stream->recv_window) { ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0, - "client violated flow control for stream %ui: length of " - "received DATA frame %uz, while available window %uz", + "client violated flow control for stream %ui: " + "received DATA frame length %uz, available window %uz", stream->id, sc->length, stream->recv_window); if (ngx_http_spdy_terminate_stream(sc, stream, @@ -1478,7 +1498,7 @@ if (stream->in_closed) { ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0, - "client sent DATA frame for half closed stream %ui", + "client sent DATA frame for half-closed stream %ui", stream->id); if (ngx_http_spdy_terminate_stream(sc, stream, @@ -1521,7 +1541,10 @@ stream->in_closed = 1; } - /* TODO log and accounting */ + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0, + "skipping spdy DATA frame, reason: %d", + stream->skip_data); + return ngx_http_spdy_state_skip(sc, pos, end); } @@ -1550,7 +1573,10 @@ if (r->headers_in.content_length_n != -1 && r->headers_in.content_length_n < rb->rest) { - /* TODO logging */ + ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, + "client intended to send body data " + "larger than declared"); + stream->skip_data = NGX_SPDY_DATA_ERROR; goto error; @@ -1561,9 +1587,8 @@ && clcf->client_max_body_size < rb->rest) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, - "client intended to send too large chunked " - "body: %O bytes", - rb->rest); + "client intended to send " + "too large chunked body: %O bytes", rb->rest); stream->skip_data = NGX_SPDY_DATA_ERROR; goto error; @@ -1615,7 +1640,7 @@ } else if (r->headers_in.content_length_n != rb->rest) { ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "client prematurely closed stream: " - "%O of %O bytes of request body received", + "only %O out of %O bytes of request body received", rb->rest, r->headers_in.content_length_n); stream->skip_data = NGX_SPDY_DATA_ERROR; @@ -1694,9 +1719,11 @@ "spdy RST_STREAM sid:%ui st:%ui", sid, status); stream = ngx_http_spdy_get_stream_by_id(sc, sid); + if (stream == NULL) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0, - "unknown stream, probably it has been closed already"); + "unknown spdy stream"); + return ngx_http_spdy_state_complete(sc, pos, end); } @@ -1715,7 +1742,7 @@ case NGX_SPDY_INTERNAL_ERROR: ngx_log_error(NGX_LOG_INFO, fc->log, 0, - "client terminated stream %ui because of internal error", + "client terminated stream %ui due to internal error", sid); break; @@ -1747,7 +1774,10 @@ } if (sc->length != NGX_SPDY_PING_SIZE) { - /* TODO logging */ + ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0, + "client sent PING frame with incorrect length %uz", + sc->length); + return ngx_http_spdy_state_protocol_error(sc); } @@ -1787,6 +1817,9 @@ size = end - pos; + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0, + "spdy frame skip %uz of %uz", size, sc->length); + if (size < sc->length) { sc->length -= size; return ngx_http_spdy_state_save(sc, end, end, @@ -1816,13 +1849,16 @@ sc->length -= NGX_SPDY_SETTINGS_NUM_SIZE; if (sc->length < sc->entries * NGX_SPDY_SETTINGS_PAIR_SIZE) { - /* TODO logging */ + ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0, + "client sent SETTINGS frame with incorrect " + "length %uz or number of entries %ui", + sc->length, sc->entries); + return ngx_http_spdy_state_protocol_error(sc); } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0, - "spdy SETTINGS frame consists of %ui entries", - sc->entries); + "spdy SETTINGS frame has %ui entries", sc->entries); } while (sc->entries) { @@ -1882,7 +1918,20 @@ ngx_http_spdy_state_complete(ngx_http_spdy_connection_t *sc, u_char *pos, u_char *end) { + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0, + "spdy frame complete pos:%p end:%p", pos, end); + + if (pos > end) { + ngx_log_error(NGX_LOG_ALERT, sc->connection->log, 0, + "receive buffer overrun"); + + ngx_debug_point(); + return ngx_http_spdy_state_internal_error(sc); + } + sc->handler = ngx_http_spdy_state_head; + sc->stream = NULL; + return pos; } @@ -1893,12 +1942,17 @@ { size_t size; + ngx_log_debug3(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0, + "spdy frame state save pos:%p end:%p handler:%p", + pos, end, handler); + size = end - pos; if (size > NGX_SPDY_STATE_BUFFER_SIZE) { ngx_log_error(NGX_LOG_ALERT, sc->connection->log, 0, - "spdy state buffer overflow: " - "%uz bytes required", size); + "state buffer overflow: %uz bytes required", size); + + ngx_debug_point(); return ngx_http_spdy_state_internal_error(sc); } @@ -1913,13 +1967,36 @@ static u_char * +ngx_http_spdy_state_inflate_error(ngx_http_spdy_connection_t *sc, int rc) +{ + if (rc == Z_DATA_ERROR || rc == Z_STREAM_END) { + ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0, + "client sent SYN_STREAM frame with " + "corrupted header block, inflate() failed: %d", rc); + + return ngx_http_spdy_state_protocol_error(sc); + } + + ngx_log_error(NGX_LOG_ERR, sc->connection->log, 0, + "inflate() failed: %d", rc); + + return ngx_http_spdy_state_internal_error(sc); +} + + +static u_char * ngx_http_spdy_state_protocol_error(ngx_http_spdy_connection_t *sc) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0, "spdy state protocol error"); - /* TODO */ + if (sc->stream) { + sc->stream->out_closed = 1; + ngx_http_spdy_close_stream(sc->stream, NGX_HTTP_BAD_REQUEST); + } + ngx_http_spdy_finalize_connection(sc, NGX_HTTP_CLIENT_CLOSED_REQUEST); + return NULL; } @@ -1930,8 +2007,13 @@ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0, "spdy state internal error"); - /* TODO */ + if (sc->stream) { + sc->stream->out_closed = 1; + ngx_http_spdy_close_stream(sc->stream, NGX_HTTP_INTERNAL_SERVER_ERROR); + } + ngx_http_spdy_finalize_connection(sc, NGX_HTTP_INTERNAL_SERVER_ERROR); + return NULL; } @@ -1945,7 +2027,7 @@ ngx_http_spdy_out_frame_t *frame; ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0, - "spdy write WINDOW_UPDATE sid:%ui delta:%ui", sid, delta); + "spdy send WINDOW_UPDATE sid:%ui delta:%ui", sid, delta); frame = ngx_http_spdy_get_ctl_frame(sc, NGX_SPDY_WINDOW_UPDATE_SIZE, NGX_SPDY_HIGHEST_PRIORITY); @@ -1984,7 +2066,7 @@ } ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0, - "spdy write RST_STREAM sid:%ui st:%ui", sid, status); + "spdy send RST_STREAM sid:%ui st:%ui", sid, status); frame = ngx_http_spdy_get_ctl_frame(sc, NGX_SPDY_RST_STREAM_SIZE, priority); @@ -2019,7 +2101,7 @@ ngx_http_spdy_out_frame_t *frame; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0, - "spdy create GOAWAY sid:%ui", sc->last_sid); + "spdy send GOAWAY sid:%ui", sc->last_sid); frame = ngx_http_spdy_get_ctl_frame(sc, NGX_SPDY_GOAWAY_SIZE, NGX_SPDY_HIGHEST_PRIORITY); @@ -2055,7 +2137,7 @@ ngx_http_spdy_out_frame_t *frame; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0, - "spdy create SETTINGS frame"); + "spdy send SETTINGS frame"); frame = ngx_palloc(sc->pool, sizeof(ngx_http_spdy_out_frame_t)); if (frame == NULL) { @@ -2177,7 +2259,7 @@ #if (NGX_DEBUG) if (length > NGX_SPDY_CTL_FRAME_BUFFER_SIZE - NGX_SPDY_FRAME_HEADER_SIZE) { ngx_log_error(NGX_LOG_ALERT, sc->pool->log, 0, - "requested control frame is too big: %uz", length); + "requested control frame is too large: %uz", length); return NULL; } @@ -2395,7 +2477,7 @@ r->lowcase_index = ngx_spdy_frame_parse_uint32(p); if (r->lowcase_index == 0) { - return NGX_HTTP_PARSE_INVALID_HEADER; + return NGX_ERROR; } /* null-terminate the previous header value */ @@ -2445,11 +2527,15 @@ case LF: case CR: case ':': - return NGX_HTTP_PARSE_INVALID_REQUEST; + ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, + "client sent invalid header name: \"%*s\"", + r->lowcase_index, r->header_name_start); + + return NGX_HTTP_PARSE_INVALID_HEADER; } if (ch >= 'A' && ch <= 'Z') { - return NGX_HTTP_PARSE_INVALID_HEADER; + return NGX_ERROR; } r->invalid_header = 1; @@ -2502,6 +2588,15 @@ } if (ch == CR || ch == LF) { + ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, + "client sent header \"%*s\" with " + "invalid value: \"%*s\\%c...\"", + r->header_name_end - r->header_name_start, + r->header_name_start, + p - r->header_start, + r->header_start, + ch == CR ? 'r' : 'n'); + return NGX_HTTP_PARSE_INVALID_HEADER; } @@ -2526,7 +2621,7 @@ static ngx_int_t ngx_http_spdy_alloc_large_header_buffer(ngx_http_request_t *r) { - u_char *old, *new; + u_char *old, *new, *p; size_t rest; ngx_buf_t *buf; ngx_http_spdy_stream_t *stream; @@ -2542,12 +2637,30 @@ if (stream->header_buffers == (ngx_uint_t) cscf->large_client_header_buffers.num) { + ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, + "client sent too large request"); + return NGX_DECLINED; } rest = r->header_in->last - r->header_in->pos; + /* + * equality is prohibited since one more byte is needed + * for null-termination + */ if (rest >= cscf->large_client_header_buffers.size) { + p = r->header_in->pos; + + if (rest > NGX_MAX_ERROR_STR - 300) { + rest = NGX_MAX_ERROR_STR - 300; + p[rest++] = '.'; p[rest++] = '.'; p[rest++] = '.'; + } + + ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, + "client sent too long header name or value: \"%*s\"", + rest, p); + return NGX_DECLINED; } @@ -2557,7 +2670,7 @@ } ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "spdy large header alloc: %p %z", + "spdy large header alloc: %p %uz", buf->pos, buf->end - buf->last); old = r->header_in->pos; @@ -2612,13 +2725,16 @@ return sh->handler(r); } - return NGX_HTTP_PARSE_INVALID_REQUEST; + ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, + "client sent invalid header name: \":%*s\"", + r->header_end - r->header_name_start, + r->header_name_start); + + return NGX_HTTP_PARSE_INVALID_HEADER; } h = ngx_list_push(&r->headers_in.headers); if (h == NULL) { - ngx_http_spdy_close_stream(r->spdy_stream, - NGX_HTTP_INTERNAL_SERVER_ERROR); return NGX_ERROR; } @@ -2684,6 +2800,9 @@ }, *test; if (r->method_name.len) { + ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, + "client sent duplicate :method header"); + return NGX_HTTP_PARSE_INVALID_HEADER; } @@ -2721,8 +2840,10 @@ do { if ((*p < 'A' || *p > 'Z') && *p != '_') { ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, - "client sent invalid method"); - return NGX_HTTP_PARSE_INVALID_REQUEST; + "client sent invalid method: \"%V\"", + &r->method_name); + + return NGX_HTTP_PARSE_INVALID_HEADER; } p++; @@ -2737,6 +2858,9 @@ ngx_http_spdy_parse_scheme(ngx_http_request_t *r) { if (r->schema_start) { + ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, + "client sent duplicate :schema header"); + return NGX_HTTP_PARSE_INVALID_HEADER; } @@ -2753,13 +2877,14 @@ ngx_table_elt_t *h; if (r->headers_in.host) { + ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, + "client sent duplicate :host header"); + return NGX_HTTP_PARSE_INVALID_HEADER; } h = ngx_list_push(&r->headers_in.headers); if (h == NULL) { - ngx_http_spdy_close_stream(r->spdy_stream, - NGX_HTTP_INTERNAL_SERVER_ERROR); return NGX_ERROR; } @@ -2783,6 +2908,9 @@ ngx_http_spdy_parse_path(ngx_http_request_t *r) { if (r->unparsed_uri.len) { + ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, + "client sent duplicate :path header"); + return NGX_HTTP_PARSE_INVALID_HEADER; } @@ -2790,11 +2918,19 @@ r->uri_end = r->header_end; if (ngx_http_parse_uri(r) != NGX_OK) { - return NGX_HTTP_PARSE_INVALID_REQUEST; + ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, + "client sent invalid URI: \"%*s\"", + r->uri_end - r->uri_start, r->uri_start); + + return NGX_HTTP_PARSE_INVALID_HEADER; } if (ngx_http_process_request_uri(r) != NGX_OK) { - return NGX_ERROR; + /* + * request has been finalized already + * in ngx_http_process_request_uri() + */ + return NGX_ABORT; } return NGX_OK; @@ -2807,19 +2943,22 @@ u_char *p, ch; if (r->http_protocol.len) { + ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, + "client sent duplicate :version header"); + return NGX_HTTP_PARSE_INVALID_HEADER; } p = r->header_start; if (r->header_end - p < 8 || !(ngx_str5cmp(p, 'H', 'T', 'T', 'P', '/'))) { - return NGX_HTTP_PARSE_INVALID_REQUEST; + goto invalid; } ch = *(p + 5); if (ch < '1' || ch > '9') { - return NGX_HTTP_PARSE_INVALID_REQUEST; + goto invalid; } r->http_major = ch - '0'; @@ -2833,20 +2972,20 @@ } if (ch < '0' || ch > '9') { - return NGX_HTTP_PARSE_INVALID_REQUEST; + goto invalid; } r->http_major = r->http_major * 10 + ch - '0'; } if (*p != '.') { - return NGX_HTTP_PARSE_INVALID_REQUEST; + goto invalid; } ch = *(p + 1); if (ch < '0' || ch > '9') { - return NGX_HTTP_PARSE_INVALID_REQUEST; + goto invalid; } r->http_minor = ch - '0'; @@ -2856,7 +2995,7 @@ ch = *p; if (ch < '0' || ch > '9') { - return NGX_HTTP_PARSE_INVALID_REQUEST; + goto invalid; } r->http_minor = r->http_minor * 10 + ch - '0'; @@ -2867,6 +3006,14 @@ r->http_version = r->http_major * 1000 + r->http_minor; return NGX_OK; + +invalid: + + ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, + "client sent invalid http version: \"%*s\"", + r->header_end - r->header_start, r->header_start); + + return NGX_HTTP_PARSE_INVALID_HEADER; } @@ -2889,7 +3036,8 @@ p = ngx_pnalloc(r->pool, r->request_line.len + 1); if (p == NULL) { - ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); + ngx_http_spdy_close_stream(r->spdy_stream, + NGX_HTTP_INTERNAL_SERVER_ERROR); return NGX_ERROR; } @@ -2953,7 +3101,7 @@ } ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http header: \"%V: %V\"", &h[i].key, &h[i].value); + "spdy http header: \"%V: %V\"", &h[i].key, &h[i].value); } r->http_state = NGX_HTTP_PROCESS_REQUEST_STATE; @@ -3215,7 +3363,7 @@ if (ev->active || ev->disabled) { ngx_log_error(NGX_LOG_ALERT, sc->connection->log, 0, - "spdy fake read event was activated"); + "fake read event was activated"); } if (ev->timer_set) { @@ -3230,7 +3378,7 @@ if (ev->active || ev->disabled) { ngx_log_error(NGX_LOG_ALERT, sc->connection->log, 0, - "spdy fake write event was activated"); + "fake write event was activated"); } if (ev->timer_set) { | ||
[+] | Changed | nginx-1.7.1.tar.gz/src/http/ngx_http_spdy_filter_module.c ^ |
@@ -533,8 +533,7 @@ ngx_free(buf); if (rc != Z_OK) { - ngx_log_error(NGX_LOG_ALERT, c->log, 0, - "spdy deflate() failed: %d", rc); + ngx_log_error(NGX_LOG_ALERT, c->log, 0, "deflate() failed: %d", rc); return NGX_ERROR; } | ||
[+] | Changed | nginx-1.7.1.tar.gz/src/http/ngx_http_upstream.c ^ |
@@ -156,6 +156,8 @@ static void ngx_http_upstream_ssl_init_connection(ngx_http_request_t *, ngx_http_upstream_t *u, ngx_connection_t *c); static void ngx_http_upstream_ssl_handshake(ngx_connection_t *c); +static ngx_int_t ngx_http_upstream_ssl_name(ngx_http_request_t *r, + ngx_http_upstream_t *u, ngx_connection_t *c); #endif @@ -214,7 +216,8 @@ ngx_http_upstream_rewrite_refresh, 0, 0 }, { ngx_string("Set-Cookie"), - ngx_http_upstream_process_set_cookie, 0, + ngx_http_upstream_process_set_cookie, + offsetof(ngx_http_upstream_headers_in_t, cookies), ngx_http_upstream_rewrite_set_cookie, 0, 1 }, { ngx_string("Content-Disposition"), @@ -584,6 +587,10 @@ } else { +#if (NGX_HTTP_SSL) + u->ssl_name = u->resolved->host; +#endif + if (u->resolved->sockaddr) { if (ngx_http_upstream_create_round_robin_peer(r, u->resolved) @@ -670,6 +677,10 @@ return; } +#if (NGX_HTTP_SSL) + u->ssl_name = uscf->host; +#endif + if (uscf->peer.init(r, uscf) != NGX_OK) { ngx_http_upstream_finalize_request(r, u, NGX_HTTP_INTERNAL_SERVER_ERROR); @@ -1355,6 +1366,14 @@ c->sendfile = 0; u->output.sendfile = 0; + if (u->conf->ssl_server_name || u->conf->ssl_verify) { + if (ngx_http_upstream_ssl_name(r, u, c) != NGX_OK) { + ngx_http_upstream_finalize_request(r, u, + NGX_HTTP_INTERNAL_SERVER_ERROR); + return; + } + } + if (u->conf->ssl_session_reuse) { if (u->peer.set_session(&u->peer, u->peer.data) != NGX_OK) { ngx_http_upstream_finalize_request(r, u, @@ -1379,6 +1398,7 @@ static void ngx_http_upstream_ssl_handshake(ngx_connection_t *c) { + long rc; ngx_http_request_t *r; ngx_http_upstream_t *u; @@ -1387,6 +1407,24 @@ if (c->ssl->handshaked) { + if (u->conf->ssl_verify) { + rc = SSL_get_verify_result(c->ssl->connection); + + if (rc != X509_V_OK) { + ngx_log_error(NGX_LOG_ERR, c->log, 0, + "upstream SSL certificate verify error: (%l:%s)", + rc, X509_verify_cert_error_string(rc)); + goto failed; + } + + if (ngx_ssl_check_host(c, &u->ssl_name) != NGX_OK) { + ngx_log_error(NGX_LOG_ERR, c->log, 0, + "upstream SSL certificate does not match \"%V\"", + &u->ssl_name); + goto failed; + } + } + if (u->conf->ssl_session_reuse) { u->peer.save_session(&u->peer, u->peer.data); } @@ -1402,6 +1440,8 @@ return; } +failed: + c = r->connection; ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR); @@ -1409,6 +1449,97 @@ ngx_http_run_posted_requests(c); } + +static ngx_int_t +ngx_http_upstream_ssl_name(ngx_http_request_t *r, ngx_http_upstream_t *u, + ngx_connection_t *c) +{ + u_char *p, *last; + ngx_str_t name; + + if (u->conf->ssl_name) { + if (ngx_http_complex_value(r, u->conf->ssl_name, &name) != NGX_OK) { + return NGX_ERROR; + } + + } else { + name = u->ssl_name; + } + + if (name.len == 0) { + goto done; + } + + /* + * ssl name here may contain port, notably if derived from $proxy_host + * or $http_host; we have to strip it + */ + + p = name.data; + last = name.data + name.len; + + if (*p == '[') { + p = ngx_strlchr(p, last, ']'); + + if (p == NULL) { + p = name.data; + } + } + + p = ngx_strlchr(p, last, ':'); + + if (p != NULL) { + name.len = p - name.data; + } + + if (!u->conf->ssl_server_name) { + goto done; + } + +#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME + + /* as per RFC 6066, literal IPv4 and IPv6 addresses are not permitted */ + + if (name.len == 0 || *name.data == '[') { + goto done; + } + + if (ngx_inet_addr(name.data, name.len) != INADDR_NONE) { + goto done; + } + + /* + * SSL_set_tlsext_host_name() needs a null-terminated string, + * hence we explicitly null-terminate name here + */ + + p = ngx_pnalloc(r->pool, name.len + 1); + if (p == NULL) { + return NGX_ERROR; + } + + (void) ngx_cpystrn(p, name.data, name.len + 1); + + name.data = p; + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "upstream SSL server name: \"%s\"", name.data); + + if (SSL_set_tlsext_host_name(c->ssl->connection, name.data) == 0) { + ngx_ssl_error(NGX_LOG_ERR, r->connection->log, 0, + "SSL_set_tlsext_host_name(\"%s\") failed", name.data); + return NGX_ERROR; + } + +#endif + +done: + + u->ssl_name = name; + + return NGX_OK; +} + #endif @@ -3602,11 +3733,28 @@ ngx_http_upstream_process_set_cookie(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset) { -#if (NGX_HTTP_CACHE) - ngx_http_upstream_t *u; + ngx_array_t *pa; + ngx_table_elt_t **ph; + ngx_http_upstream_t *u; u = r->upstream; + pa = &u->headers_in.cookies; + + if (pa->elts == NULL) { + if (ngx_array_init(pa, r->pool, 1, sizeof(ngx_table_elt_t *)) != NGX_OK) + { + return NGX_ERROR; + } + } + + ph = ngx_array_push(pa); + if (ph == NULL) { + return NGX_ERROR; + } + + *ph = h; +#if (NGX_HTTP_CACHE) if (!(u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_SET_COOKIE)) { u->cacheable = 0; } @@ -4528,6 +4676,40 @@ } +ngx_int_t +ngx_http_upstream_cookie_variable(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) +{ + ngx_str_t *name = (ngx_str_t *) data; + + ngx_str_t cookie, s; + + if (r->upstream == NULL) { + v->not_found = 1; + return NGX_OK; + } + + s.len = name->len - (sizeof("upstream_cookie_") - 1); + s.data = name->data + sizeof("upstream_cookie_") - 1; + + if (ngx_http_parse_set_cookie_lines(&r->upstream->headers_in.cookies, + &s, &cookie) + == NGX_DECLINED) + { + v->not_found = 1; + return NGX_OK; + } + + v->len = cookie.len; + v->valid = 1; + v->no_cacheable = 0; + v->not_found = 0; + v->data = cookie.data; + + return NGX_OK; +} + + #if (NGX_HTTP_CACHE) ngx_int_t | ||
[+] | Changed | nginx-1.7.1.tar.gz/src/http/ngx_http_upstream.h ^ |
@@ -195,6 +195,10 @@ #if (NGX_HTTP_SSL) ngx_ssl_t *ssl; ngx_flag_t ssl_session_reuse; + + ngx_http_complex_value_t *ssl_name; + ngx_flag_t ssl_server_name; + ngx_flag_t ssl_verify; #endif ngx_str_t module; @@ -244,6 +248,7 @@ off_t content_length_n; ngx_array_t cache_control; + ngx_array_t cookies; unsigned connection_close:1; unsigned chunked:1; @@ -323,6 +328,10 @@ ngx_str_t schema; ngx_str_t uri; +#if (NGX_HTTP_SSL) + ngx_str_t ssl_name; +#endif + ngx_http_cleanup_pt *cleanup; unsigned store:1; @@ -355,6 +364,8 @@ } ngx_http_upstream_param_t; +ngx_int_t ngx_http_upstream_cookie_variable(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); ngx_int_t ngx_http_upstream_header_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); | ||
[+] | Changed | nginx-1.7.1.tar.gz/src/http/ngx_http_variables.c ^ |
@@ -13,8 +13,10 @@ static ngx_int_t ngx_http_variable_request(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); +#if 0 static void ngx_http_variable_request_set(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); +#endif static ngx_int_t ngx_http_variable_request_get_size(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); static void ngx_http_variable_request_set_size(ngx_http_request_t *r, @@ -64,6 +66,8 @@ ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_variable_https(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); +static void ngx_http_variable_set_args(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_variable_is_args(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_variable_document_root(ngx_http_request_t *r, @@ -223,7 +227,7 @@ NGX_HTTP_VAR_NOCACHEABLE, 0 }, { ngx_string("args"), - ngx_http_variable_request_set, + ngx_http_variable_set_args, ngx_http_variable_request, offsetof(ngx_http_request_t, args), NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE, 0 }, @@ -613,6 +617,17 @@ return NULL; } + if (ngx_strncmp(name->data, "upstream_cookie_", 16) == 0) { + + if (ngx_http_upstream_cookie_variable(r, vv, (uintptr_t) name) + == NGX_OK) + { + return vv; + } + + return NULL; + } + if (ngx_strncmp(name->data, "arg_", 4) == 0) { if (ngx_http_variable_argument(r, vv, (uintptr_t) name) == NGX_OK) { @@ -651,6 +666,8 @@ } +#if 0 + static void ngx_http_variable_request_set(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) @@ -663,6 +680,8 @@ s->data = v->data; } +#endif + static ngx_int_t ngx_http_variable_request_get_size(ngx_http_request_t *r, @@ -1360,6 +1379,16 @@ } +static void +ngx_http_variable_set_args(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) +{ + r->args.len = v->len; + r->args.data = v->data; + r->valid_unparsed_uri = 0; +} + + static ngx_int_t ngx_http_variable_is_args(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) @@ -2527,6 +2556,14 @@ continue; } + + if (ngx_strncmp(v[i].name.data, "upstream_cookie_", 16) == 0) { + v[i].get_handler = ngx_http_upstream_cookie_variable; + v[i].data = (uintptr_t) &v[i].name; + v[i].flags = NGX_HTTP_VAR_NOCACHEABLE; + + continue; + } if (ngx_strncmp(v[i].name.data, "arg_", 4) == 0) { v[i].get_handler = ngx_http_variable_argument; | ||
[+] | Changed | nginx-1.7.1.tar.gz/src/mail/ngx_mail_auth_http_module.c ^ |
@@ -1269,7 +1269,7 @@ l.len = b->last - b->pos; l.data = b->pos; ngx_log_debug1(NGX_LOG_DEBUG_MAIL, s->connection->log, 0, - "mail auth http header:\n\"%V\"", &l); + "mail auth http header:%N\"%V\"", &l); } #endif | ||
[+] | Changed | nginx-1.7.1.tar.gz/src/mail/ngx_mail_handler.c ^ |
@@ -22,6 +22,7 @@ void ngx_mail_init_connection(ngx_connection_t *c) { + size_t len; ngx_uint_t i; ngx_mail_port_t *port; struct sockaddr *sa; @@ -30,6 +31,7 @@ ngx_mail_in_addr_t *addr; ngx_mail_session_t *s; ngx_mail_addr_conf_t *addr_conf; + u_char text[NGX_SOCKADDR_STRLEN]; #if (NGX_HAVE_INET6) struct sockaddr_in6 *sin6; ngx_mail_in6_addr_t *addr6; @@ -127,8 +129,10 @@ c->data = s; s->connection = c; - ngx_log_error(NGX_LOG_INFO, c->log, 0, "*%uA client %V connected to %V", - c->number, &c->addr_text, s->addr_text); + len = ngx_sock_ntop(c->sockaddr, c->socklen, text, NGX_SOCKADDR_STRLEN, 1); + + ngx_log_error(NGX_LOG_INFO, c->log, 0, "*%uA client %*s connected to %V", + c->number, len, text, s->addr_text); ctx = ngx_palloc(c->pool, sizeof(ngx_mail_log_ctx_t)); if (ctx == NULL) { | ||
[+] | Changed | nginx-1.7.1.tar.gz/src/mail/ngx_mail_smtp_handler.c ^ |
@@ -679,6 +679,11 @@ return NGX_OK; } + if (s->args.nelts == 0) { + ngx_str_set(&s->out, smtp_invalid_argument); + return NGX_OK; + } + arg = s->args.elts; arg += s->args.nelts - 1; @@ -713,6 +718,11 @@ return NGX_OK; } + if (s->args.nelts == 0) { + ngx_str_set(&s->out, smtp_invalid_argument); + return NGX_OK; + } + arg = s->args.elts; arg += s->args.nelts - 1; | ||
[+] | Changed | nginx-1.7.1.tar.gz/src/os/unix/ngx_linux_config.h ^ |
@@ -94,6 +94,9 @@ #if (NGX_HAVE_FILE_AIO) +#if (NGX_HAVE_SYS_EVENTFD_H) +#include <sys/eventfd.h> +#endif #include <sys/syscall.h> #include <linux/aio_abi.h> typedef struct iocb ngx_aiocb_t; | ||
[+] | Changed | nginx-1.7.1.tar.gz/src/os/unix/ngx_posix_init.c ^ |
@@ -82,7 +82,7 @@ void ngx_os_status(ngx_log_t *log) { - ngx_log_error(NGX_LOG_NOTICE, log, 0, NGINX_VER); + ngx_log_error(NGX_LOG_NOTICE, log, 0, NGINX_VER_BUILD); #ifdef NGX_COMPILER ngx_log_error(NGX_LOG_NOTICE, log, 0, "built by " NGX_COMPILER); | ||
[+] | Changed | nginx-1.7.1.tar.gz/src/os/unix/ngx_process_cycle.c ^ |
@@ -710,11 +710,13 @@ * ngx_cycle->pool is already destroyed. */ - ngx_exit_log_file.fd = ngx_cycle->log->file->fd; - ngx_exit_log = *ngx_cycle->log; + ngx_exit_log = *ngx_log_get_file_log(ngx_cycle->log); + + ngx_exit_log_file.fd = ngx_exit_log.file->fd; ngx_exit_log.file = &ngx_exit_log_file; ngx_exit_log.next = NULL; + ngx_exit_log.writer = NULL; ngx_exit_cycle.log = &ngx_exit_log; ngx_exit_cycle.files = ngx_cycle->files; @@ -1065,11 +1067,12 @@ * ngx_cycle->pool is already destroyed. */ - ngx_exit_log_file.fd = ngx_cycle->log->file->fd; + ngx_exit_log = *ngx_log_get_file_log(ngx_cycle->log); - ngx_exit_log = *ngx_cycle->log; + ngx_exit_log_file.fd = ngx_exit_log.file->fd; ngx_exit_log.file = &ngx_exit_log_file; ngx_exit_log.next = NULL; + ngx_exit_log.writer = NULL; ngx_exit_cycle.log = &ngx_exit_log; ngx_exit_cycle.files = ngx_cycle->files; |