# HG changeset patch # User Igor Sysoev # Date 1234213200 -10800 # Node ID 33394d1255b058295bc596287d249ccd612fb41e # Parent 28335b73075091c0e231e7660b1c1fca1dc23ef8 nginx 0.7.34 *) Feature: the "off" parameter of the "if_modified_since" directive. *) Feature: now nginx sends an HELO/EHLO command after a XCLIENT command. Thanks to Maxim Dounin. *) Feature: Microsoft specific "AUTH LOGIN with User Name" mode support in mail proxy server. Thanks to Maxim Dounin. *) Bugfix: in a redirect rewrite directive original arguments were concatenated with new arguments by an "?" rather than an "&"; the bug had appeared in 0.1.18. Thanks to Maxim Dounin. *) Bugfix: nginx could not be built on AIX. diff --git a/CHANGES b/CHANGES --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,24 @@ +Changes with nginx 0.7.34 10 Feb 2009 + + *) Feature: the "off" parameter of the "if_modified_since" directive. + + *) Feature: now nginx sends an HELO/EHLO command after a XCLIENT + command. + Thanks to Maxim Dounin. + + *) Feature: Microsoft specific "AUTH LOGIN with User Name" mode support + in mail proxy server. + Thanks to Maxim Dounin. + + *) Bugfix: in a redirect rewrite directive original arguments were + concatenated with new arguments by an "?" rather than an "&"; + the bug had appeared in 0.1.18. + Thanks to Maxim Dounin. + + *) Bugfix: nginx could not be built on AIX. + + Changes with nginx 0.7.33 02 Feb 2009 *) Bugfix: a double response might be returned if the epoll or rtsig @@ -62,7 +82,8 @@ Changes with nginx 0.7.29 *) Bugfixes in subrequest processing; the bugs had appeared in 0.7.25. - *) Bugfix: a "100 Continue" response was issued for HTTP/1.0 requests; + *) Bugfix: a "100 Continue" response was issued for HTTP/1.0 + requests; Thanks to Maxim Dounin. *) Bugfix: in memory allocation in the ngx_http_gzip_filter_module on @@ -3422,8 +3443,8 @@ Changes with nginx 0.1.18 *) Bugfix: the proxy_set_x_var and fastcgi_set_var directives were not inherited. - *) Bugfix: in the redirect rewrite directive the arguments were - concatenated with URI by the "&" rather than the "?". + *) Bugfix: in a redirect rewrite directive arguments were concatenated + with URI by an "&" rather than an "?". *) Bugfix: the lines without trailing ";" in the file being included by the ngx_http_geo_module were silently ignored. diff --git a/CHANGES.ru b/CHANGES.ru --- a/CHANGES.ru +++ b/CHANGES.ru @@ -1,4 +1,24 @@ +Изменения в nginx 0.7.34 10.02.2009 + + *) Добавление: параметр off в директиве if_modified_since. + + *) Добавление: теперь после команды XCLIENT nginx посылает команду + HELO/EHLO. + Спасибо Максиму Дунину. + + *) Добавление: поддержка Microsoft-специфичного режима + "AUTH LOGIN with User Name" в почтовом прокси-сервере. + Спасибо Максиму Дунину. + + *) Исправление: в директиве rewrite, возвращающей редирект, старые + аргументы присоединялись к новым через символ "?" вместо "&"; + ошибка появилась в 0.1.18. + Спасибо Максиму Дунину. + + *) Исправление: nginx не собирался на AIX. + + Изменения в nginx 0.7.33 02.02.2009 *) Исправление: если на запрос с телом возвращался редирект, то ответ @@ -62,7 +82,8 @@ *) Исправления в обработке подзапросов; ошибки появились в 0.7.25. *) Исправление: ответ "100 Continue" выдавался для запросов версии - HTTP/1.0; Спасибо Максиму Дунину. + HTTP/1.0; + Спасибо Максиму Дунину. *) Исправление: в выделении памяти в модуле ngx_http_gzip_filter_module под Cygwin. diff --git a/src/core/nginx.h b/src/core/nginx.h --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -8,7 +8,7 @@ #define _NGINX_H_INCLUDED_ -#define NGINX_VERSION "0.7.33" +#define NGINX_VERSION "0.7.34" #define NGINX_VER "nginx/" NGINX_VERSION #define NGINX_VAR "NGINX" diff --git a/src/http/modules/ngx_http_not_modified_filter_module.c b/src/http/modules/ngx_http_not_modified_filter_module.c --- a/src/http/modules/ngx_http_not_modified_filter_module.c +++ b/src/http/modules/ngx_http_not_modified_filter_module.c @@ -61,6 +61,12 @@ ngx_int_t ngx_http_not_modified_header_f return ngx_http_next_header_filter(r); } + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + + if (clcf->if_modified_since == NGX_HTTP_IMS_OFF) { + return ngx_http_next_header_filter(r); + } + ims = ngx_http_parse_time(r->headers_in.if_modified_since->value.data, r->headers_in.if_modified_since->value.len); @@ -69,9 +75,7 @@ ngx_int_t ngx_http_not_modified_header_f if (ims != r->headers_out.last_modified_time) { - clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - - if (clcf->if_modified_since == 0 + if (clcf->if_modified_since == NGX_HTTP_IMS_EXACT || ims < r->headers_out.last_modified_time) { return ngx_http_next_header_filter(r); diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm --- a/src/http/modules/perl/nginx.pm +++ b/src/http/modules/perl/nginx.pm @@ -47,7 +47,7 @@ our @EXPORT = qw( HTTP_INSUFFICIENT_STORAGE ); -our $VERSION = '0.7.33'; +our $VERSION = '0.7.34'; require XSLoader; XSLoader::load('nginx', $VERSION); diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -112,8 +112,9 @@ static ngx_conf_enum_t ngx_http_core_sa static ngx_conf_enum_t ngx_http_core_if_modified_since[] = { - { ngx_string("exact"), 0 }, - { ngx_string("before"), 1 }, + { ngx_string("off"), NGX_HTTP_IMS_OFF }, + { ngx_string("exact"), NGX_HTTP_IMS_EXACT }, + { ngx_string("before"), NGX_HTTP_IMS_BEFORE }, { ngx_null_string, 0 } }; @@ -3052,7 +3053,7 @@ ngx_http_core_merge_loc_conf(ngx_conf_t ngx_conf_merge_uint_value(conf->satisfy, prev->satisfy, NGX_HTTP_SATISFY_ALL); ngx_conf_merge_uint_value(conf->if_modified_since, prev->if_modified_since, - 0); + NGX_HTTP_IMS_EXACT); ngx_conf_merge_value(conf->internal, prev->internal, 0); ngx_conf_merge_value(conf->client_body_in_file_only, prev->client_body_in_file_only, 0); diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h --- a/src/http/ngx_http_core_module.h +++ b/src/http/ngx_http_core_module.h @@ -28,6 +28,11 @@ #define NGX_HTTP_SATISFY_ANY 1 +#define NGX_HTTP_IMS_OFF 0 +#define NGX_HTTP_IMS_EXACT 1 +#define NGX_HTTP_IMS_BEFORE 2 + + typedef struct ngx_http_location_tree_node_s ngx_http_location_tree_node_t; typedef struct ngx_http_core_loc_conf_s ngx_http_core_loc_conf_t; diff --git a/src/http/ngx_http_script.c b/src/http/ngx_http_script.c --- a/src/http/ngx_http_script.c +++ b/src/http/ngx_http_script.c @@ -244,10 +244,21 @@ ngx_http_script_compile(ngx_http_script_ name.data = &sc->source->data[i]; - while (i < sc->source->len - && sc->source->data[i] != '$' - && !(sc->source->data[i] == '?' && sc->compile_args)) - { + while (i < sc->source->len) { + + if (sc->source->data[i] == '$') { + break; + } + + if (sc->source->data[i] == '?') { + + sc->args = 1; + + if (sc->compile_args) { + break; + } + } + i++; name.len++; } diff --git a/src/mail/ngx_mail.h b/src/mail/ngx_mail.h --- a/src/mail/ngx_mail.h +++ b/src/mail/ngx_mail.h @@ -140,6 +140,7 @@ typedef enum { ngx_smtp_helo_from, ngx_smtp_xclient, ngx_smtp_xclient_from, + ngx_smtp_xclient_helo, ngx_smtp_from, ngx_smtp_to } ngx_smtp_state_e; @@ -258,11 +259,12 @@ typedef struct { #define NGX_SMTP_STARTTLS 13 -#define NGX_MAIL_AUTH_PLAIN 0 -#define NGX_MAIL_AUTH_LOGIN 1 -#define NGX_MAIL_AUTH_APOP 2 -#define NGX_MAIL_AUTH_CRAM_MD5 3 -#define NGX_MAIL_AUTH_NONE 4 +#define NGX_MAIL_AUTH_PLAIN 0 +#define NGX_MAIL_AUTH_LOGIN 1 +#define NGX_MAIL_AUTH_LOGIN_USERNAME 2 +#define NGX_MAIL_AUTH_APOP 3 +#define NGX_MAIL_AUTH_CRAM_MD5 4 +#define NGX_MAIL_AUTH_NONE 5 #define NGX_MAIL_AUTH_PLAIN_ENABLED 0x0002 @@ -346,7 +348,7 @@ ngx_int_t ngx_mail_salt(ngx_mail_session ngx_int_t ngx_mail_auth_plain(ngx_mail_session_t *s, ngx_connection_t *c, ngx_uint_t n); ngx_int_t ngx_mail_auth_login_username(ngx_mail_session_t *s, - ngx_connection_t *c); + ngx_connection_t *c, ngx_uint_t n); ngx_int_t ngx_mail_auth_login_password(ngx_mail_session_t *s, ngx_connection_t *c); ngx_int_t ngx_mail_auth_cram_md5_salt(ngx_mail_session_t *s, diff --git a/src/mail/ngx_mail_handler.c b/src/mail/ngx_mail_handler.c --- a/src/mail/ngx_mail_handler.c +++ b/src/mail/ngx_mail_handler.c @@ -356,21 +356,22 @@ ngx_mail_auth_plain(ngx_mail_session_t * ngx_int_t -ngx_mail_auth_login_username(ngx_mail_session_t *s, ngx_connection_t *c) +ngx_mail_auth_login_username(ngx_mail_session_t *s, ngx_connection_t *c, + ngx_uint_t n) { ngx_str_t *arg; arg = s->args.elts; ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, - "mail auth login username: \"%V\"", &arg[0]); + "mail auth login username: \"%V\"", &arg[n]); - s->login.data = ngx_pnalloc(c->pool, ngx_base64_decoded_length(arg[0].len)); + s->login.data = ngx_pnalloc(c->pool, ngx_base64_decoded_length(arg[n].len)); if (s->login.data == NULL){ return NGX_ERROR; } - if (ngx_decode_base64(&s->login, &arg[0]) != NGX_OK) { + if (ngx_decode_base64(&s->login, &arg[n]) != NGX_OK) { ngx_log_error(NGX_LOG_INFO, c->log, 0, "client sent invalid base64 encoding in AUTH LOGIN command"); return NGX_MAIL_PARSE_INVALID_COMMAND; diff --git a/src/mail/ngx_mail_imap_handler.c b/src/mail/ngx_mail_imap_handler.c --- a/src/mail/ngx_mail_imap_handler.c +++ b/src/mail/ngx_mail_imap_handler.c @@ -205,7 +205,7 @@ ngx_mail_imap_auth_state(ngx_event_t *re break; case ngx_imap_auth_login_username: - rc = ngx_mail_auth_login_username(s, c); + rc = ngx_mail_auth_login_username(s, c, 0); tag = 0; s->out.len = sizeof(imap_password) - 1; @@ -370,6 +370,14 @@ ngx_mail_imap_authenticate(ngx_mail_sess return NGX_OK; + case NGX_MAIL_AUTH_LOGIN_USERNAME: + + s->out.len = sizeof(imap_password) - 1; + s->out.data = imap_password; + s->mail_state = ngx_imap_auth_login_password; + + return ngx_mail_auth_login_username(s, c, 1); + case NGX_MAIL_AUTH_PLAIN: s->out.len = sizeof(imap_plain_next) - 1; diff --git a/src/mail/ngx_mail_parse.c b/src/mail/ngx_mail_parse.c --- a/src/mail/ngx_mail_parse.c +++ b/src/mail/ngx_mail_parse.c @@ -848,6 +848,10 @@ ngx_mail_auth_parse(ngx_mail_session_t * return NGX_MAIL_AUTH_LOGIN; } + if (s->args.nelts == 2) { + return NGX_MAIL_AUTH_LOGIN_USERNAME; + } + return NGX_MAIL_PARSE_INVALID_COMMAND; } diff --git a/src/mail/ngx_mail_pop3_handler.c b/src/mail/ngx_mail_pop3_handler.c --- a/src/mail/ngx_mail_pop3_handler.c +++ b/src/mail/ngx_mail_pop3_handler.c @@ -226,7 +226,7 @@ ngx_mail_pop3_auth_state(ngx_event_t *re break; case ngx_pop3_auth_login_username: - rc = ngx_mail_auth_login_username(s, c); + rc = ngx_mail_auth_login_username(s, c, 0); s->out.len = sizeof(pop3_password) - 1; s->out.data = pop3_password; @@ -474,6 +474,14 @@ ngx_mail_pop3_auth(ngx_mail_session_t *s return NGX_OK; + case NGX_MAIL_AUTH_LOGIN_USERNAME: + + s->out.len = sizeof(pop3_password) - 1; + s->out.data = pop3_password; + s->mail_state = ngx_pop3_auth_login_password; + + return ngx_mail_auth_login_username(s, c, 1); + case NGX_MAIL_AUTH_PLAIN: s->out.len = sizeof(pop3_next) - 1; diff --git a/src/mail/ngx_mail_proxy_module.c b/src/mail/ngx_mail_proxy_module.c --- a/src/mail/ngx_mail_proxy_module.c +++ b/src/mail/ngx_mail_proxy_module.c @@ -539,9 +539,8 @@ ngx_mail_proxy_smtp_handler(ngx_event_t s->connection->log->action = "sending XCLIENT to upstream"; - line.len = sizeof("XCLIENT PROTO=SMTP HELO= ADDR= LOGIN= NAME=" + line.len = sizeof("XCLIENT ADDR= LOGIN= NAME=" CRLF) - 1 - + s->esmtp + s->smtp_helo.len + s->connection->addr_text.len + s->login.len + s->host.len; line.data = ngx_pnalloc(c->pool, line.len); @@ -551,15 +550,44 @@ ngx_mail_proxy_smtp_handler(ngx_event_t } line.len = ngx_sprintf(line.data, - "XCLIENT PROTO=%sSMTP%s%V ADDR=%V%s%V NAME=%V" CRLF, - (s->esmtp ? "E" : ""), - (s->smtp_helo.len ? " HELO=" : ""), &s->smtp_helo, + "XCLIENT ADDR=%V%s%V NAME=%V" CRLF, &s->connection->addr_text, (s->login.len ? " LOGIN=" : ""), &s->login, &s->host) - line.data; + if (s->smtp_helo.len) { + s->mail_state = ngx_smtp_xclient_helo; + + } else if (s->auth_method == NGX_MAIL_AUTH_NONE) { + s->mail_state = ngx_smtp_xclient_from; + + } else { + s->mail_state = ngx_smtp_xclient; + } + + break; + + case ngx_smtp_xclient_helo: + ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, + "mail proxy send client ehlo"); + + s->connection->log->action = "sending client HELO/EHLO to upstream"; + + line.len = sizeof("HELO " CRLF) - 1 + s->smtp_helo.len; + + line.data = ngx_pnalloc(c->pool, line.len); + if (line.data == NULL) { + ngx_mail_proxy_internal_server_error(s); + return; + } + + line.len = ngx_sprintf(line.data, + ((s->esmtp) ? "EHLO %V" CRLF : "HELO %V" CRLF), + &s->smtp_helo) + - line.data; + s->mail_state = (s->auth_method == NGX_MAIL_AUTH_NONE) ? - ngx_smtp_xclient_from : ngx_smtp_xclient; + ngx_smtp_helo_from : ngx_smtp_helo; break; @@ -772,6 +800,7 @@ ngx_mail_proxy_read_response(ngx_mail_se case ngx_smtp_xclient: case ngx_smtp_xclient_from: + case ngx_smtp_xclient_helo: if (p[0] == '2' && (p[1] == '2' || p[1] == '5') && p[2] == '0') { return NGX_OK; } diff --git a/src/mail/ngx_mail_smtp_handler.c b/src/mail/ngx_mail_smtp_handler.c --- a/src/mail/ngx_mail_smtp_handler.c +++ b/src/mail/ngx_mail_smtp_handler.c @@ -462,7 +462,7 @@ ngx_mail_smtp_auth_state(ngx_event_t *re break; case ngx_smtp_auth_login_username: - rc = ngx_mail_auth_login_username(s, c); + rc = ngx_mail_auth_login_username(s, c, 0); s->out.len = sizeof(smtp_password) - 1; s->out.data = smtp_password; @@ -611,6 +611,14 @@ ngx_mail_smtp_auth(ngx_mail_session_t *s return NGX_OK; + case NGX_MAIL_AUTH_LOGIN_USERNAME: + + s->out.len = sizeof(smtp_password) - 1; + s->out.data = smtp_password; + s->mail_state = ngx_smtp_auth_login_password; + + return ngx_mail_auth_login_username(s, c, 1); + case NGX_MAIL_AUTH_PLAIN: s->out.len = sizeof(smtp_next) - 1; diff --git a/src/os/unix/ngx_process.c b/src/os/unix/ngx_process.c --- a/src/os/unix/ngx_process.c +++ b/src/os/unix/ngx_process.c @@ -494,10 +494,16 @@ ngx_process_get_status(void) } if (WTERMSIG(status)) { +#ifdef WCOREDUMP ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "%s %P exited on signal %d%s", process, pid, WTERMSIG(status), WCOREDUMP(status) ? " (core dumped)" : ""); +#else + ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, + "%s %P exited on signal %d", + process, pid, WTERMSIG(status)); +#endif } else { ngx_log_error(NGX_LOG_NOTICE, ngx_cycle->log, 0,