# HG changeset patch # User Igor Sysoev # Date 1116014400 -14400 # Node ID df7d3fff122b1a7961b055419f466d5ac234ee9d # Parent 4cb463ba8cce45417fc127a95f097611e5dd4f77 nginx 0.1.30 *) Bugfix: the worker process may got caught in an endless loop if the SSI was used. *) Bugfix: the response encrypted by SSL may not transferred complete. *) Bugfix: if the length of the response part received at once from proxied or FastCGI server was equal to 500, then nginx returns the 500 response code; in proxy mode the bug appeared in 0.1.29 only. *) Bugfix: nginx did not consider the directives with 8 or 9 parameters as invalid. *) Feature: the "return" directive can return the 204 response code. *) Feature: the "ignore_invalid_headers" directive. diff --git a/CHANGES b/CHANGES --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,22 @@ + +Changes with nginx 0.1.30 14 May 2005 + + *) Bugfix: the worker process may got caught in an endless loop if the + SSI was used. + + *) Bugfix: the response encrypted by SSL may not transferred complete. + + *) Bugfix: if the length of the response part received at once from + proxied or FastCGI server was equal to 500, then nginx returns the + 500 response code; in proxy mode the bug appeared in 0.1.29 only. + + *) Bugfix: nginx did not consider the directives with 8 or 9 parameters + as invalid. + + *) Feature: the "return" directive can return the 204 response code. + + *) Feature: the "ignore_invalid_headers" directive. + Changes with nginx 0.1.29 12 May 2005 @@ -42,8 +61,9 @@ Changes with nginx 0.1.29 *) Feature: the "fastcgi_param" directive. - *) Change: the "fastcgi_set_var" and "fastcgi_params" directive are - canceled and must be replaced with the fastcgi_param directives. + *) Change: the "fastcgi_root", "fastcgi_set_var" and "fastcgi_params" + directive are canceled and must be replaced with the fastcgi_param + directives. *) Feature: the "index" directive can use the variables. diff --git a/CHANGES.ru b/CHANGES.ru --- a/CHANGES.ru +++ b/CHANGES.ru @@ -1,3 +1,23 @@ + +Изменения в nginx 0.1.30 14.05.2005 + + *) Исправление: при использовании SSI рабочий процесс мог зациклиться. + + *) Исправление: при использовании SSL ответ мог передаваться не до + конца. + + *) Исправление: если длина части ответа, полученного за один раз от + проксируемого или FastCGI сервера была равна 500 байт, то nginx + возвращал код ответа 500; в режиме прокси ошибка появилась только в + 0.1.29. + + *) Исправление: nginx не считал неверными директивы с 8-ю или 9-ю + параметрами. + + *) Добавление: директива return может возвращать код ответа 204. + + *) Добавление: директива ignore_invalid_headers. + Изменения в nginx 0.1.29 12.05.2005 @@ -42,8 +62,8 @@ *) Добавление: директива fastcgi_param. - *) Изменение: директивы fastcgi_set_var и fastcgi_params упразднены и - должны быть замены директивами fastcgi_param. + *) Изменение: директивы fastcgi_root, fastcgi_set_var и fastcgi_params + упразднены и должны быть замены директивами fastcgi_param. *) Добавление: директива index может использовать переменные. 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_VER "nginx/0.1.29" +#define NGINX_VER "nginx/0.1.30" #define NGINX_VAR "NGINX" #define NGX_NEWPID_EXT ".newbin" diff --git a/src/core/ngx_conf_file.c b/src/core/ngx_conf_file.c --- a/src/core/ngx_conf_file.c +++ b/src/core/ngx_conf_file.c @@ -263,7 +263,7 @@ ngx_conf_handler(ngx_conf_t *cf, ngx_int valid = 0; } - } else if (cf->args->nelts <= 10 + } else if (cf->args->nelts <= NGX_CONF_MAX_ARGS && (cmd->type & argument_number[cf->args->nelts - 1])) { diff --git a/src/core/ngx_conf_file.h b/src/core/ngx_conf_file.h --- a/src/core/ngx_conf_file.h +++ b/src/core/ngx_conf_file.h @@ -27,6 +27,8 @@ #define NGX_CONF_TAKE6 0x00000040 #define NGX_CONF_TAKE7 0x00000080 +#define NGX_CONF_MAX_ARGS 8 + #define NGX_CONF_TAKE12 (NGX_CONF_TAKE1|NGX_CONF_TAKE2) #define NGX_CONF_TAKE13 (NGX_CONF_TAKE1|NGX_CONF_TAKE3) diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -361,8 +361,9 @@ ngx_ssl_send_chain(ngx_connection_t *c, return NGX_CHAIN_ERROR; } - if (n < 0) { - n = 0; + if (n == NGX_AGAIN) { + c->buffered = 1; + return in; } buf->pos += n; 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 @@ -144,6 +144,13 @@ static ngx_command_t ngx_http_core_comm offsetof(ngx_http_core_srv_conf_t, restrict_host_names), &ngx_http_restrict_host_names }, + { ngx_string("ignore_invalid_headers"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_HTTP_SRV_CONF_OFFSET, + offsetof(ngx_http_core_srv_conf_t, ignore_invalid_headers), + NULL }, + { ngx_string("location"), NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12, ngx_http_core_location, @@ -505,7 +512,10 @@ ngx_http_core_run_phases(ngx_http_reques continue; } - if (rc >= NGX_HTTP_SPECIAL_RESPONSE || rc == NGX_ERROR) { + if (rc >= NGX_HTTP_SPECIAL_RESPONSE + || rc == NGX_HTTP_NO_CONTENT + || rc == NGX_ERROR) + { ngx_http_finalize_request(r, rc); return; } @@ -1578,6 +1588,7 @@ ngx_http_core_create_srv_conf(ngx_conf_t cscf->client_header_timeout = NGX_CONF_UNSET_MSEC; cscf->client_header_buffer_size = NGX_CONF_UNSET_SIZE; cscf->restrict_host_names = NGX_CONF_UNSET_UINT; + cscf->ignore_invalid_headers = NGX_CONF_UNSET; return cscf; } @@ -1663,6 +1674,9 @@ ngx_http_core_merge_srv_conf(ngx_conf_t ngx_conf_merge_unsigned_value(conf->restrict_host_names, prev->restrict_host_names, 0); + ngx_conf_merge_value(conf->ignore_invalid_headers, + prev->ignore_invalid_headers, 1); + return NGX_CONF_OK; } 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 @@ -87,6 +87,8 @@ typedef struct { ngx_msec_t client_header_timeout; ngx_uint_t restrict_host_names; + + ngx_flag_t ignore_invalid_headers; } ngx_http_core_srv_conf_t; diff --git a/src/http/ngx_http_header_filter_module.c b/src/http/ngx_http_header_filter_module.c --- a/src/http/ngx_http_header_filter_module.c +++ b/src/http/ngx_http_header_filter_module.c @@ -48,7 +48,7 @@ static ngx_str_t ngx_http_status_lines[] ngx_null_string, /* "201 Created" */ ngx_null_string, /* "202 Accepted" */ ngx_null_string, /* "203 Non-Authoritative Information" */ - ngx_null_string, /* "204 No Content" */ + ngx_string("204 No Content"), ngx_null_string, /* "205 Reset Content" */ ngx_string("206 Partial Content"), @@ -167,8 +167,8 @@ ngx_http_header_filter(ngx_http_request_ if (r->headers_out.last_modified_time != -1) { if (r->headers_out.status != NGX_HTTP_OK - && r->headers_out.status != NGX_HTTP_NOT_MODIFIED - && r->headers_out.status != NGX_HTTP_PARTIAL_CONTENT) + && r->headers_out.status != NGX_HTTP_PARTIAL_CONTENT + && r->headers_out.status != NGX_HTTP_NOT_MODIFIED) { r->headers_out.last_modified_time = -1; r->headers_out.last_modified = NULL; @@ -193,6 +193,16 @@ ngx_http_header_filter(ngx_http_request_ /* 2XX */ status = r->headers_out.status - NGX_HTTP_OK; + if (r->headers_out.status == NGX_HTTP_NO_CONTENT) { + r->header_only = 1; + r->headers_out.content_type.len = 0; + r->headers_out.content_type.data = NULL; + r->headers_out.last_modified_time = -1; + r->headers_out.last_modified = NULL; + r->headers_out.content_length = NULL; + r->headers_out.content_length_n = -1; + } + } else if (r->headers_out.status < NGX_HTTP_BAD_REQUEST) { /* 3XX */ status = r->headers_out.status - NGX_HTTP_MOVED_PERMANENTLY diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c --- a/src/http/ngx_http_parse.c +++ b/src/http/ngx_http_parse.c @@ -529,6 +529,8 @@ ngx_http_parse_header_line(ngx_http_requ /* first char */ case sw_start: + r->invalid_header = 0; + switch (ch) { case CR: r->header_end = p; @@ -552,6 +554,8 @@ ngx_http_parse_header_line(ngx_http_requ break; } + r->invalid_header = 1; + break; } @@ -606,6 +610,8 @@ ngx_http_parse_header_line(ngx_http_requ break; } + r->invalid_header = 1; + break; /* space* before header value */ diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -725,6 +725,7 @@ ngx_http_process_request_headers(ngx_eve ngx_connection_t *c; ngx_http_header_t *hh; ngx_http_request_t *r; + ngx_http_core_srv_conf_t *cscf; ngx_http_core_main_conf_t *cmcf; c = rev->data; @@ -742,6 +743,7 @@ ngx_http_process_request_headers(ngx_eve } cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); + cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); hh = (ngx_http_header_t *) cmcf->headers_in_hash.buckets; rc = NGX_AGAIN; @@ -783,8 +785,7 @@ ngx_http_process_request_headers(ngx_eve if (rc == NGX_OK) { -#if 0 - if (r->invalid_header) { + if (r->invalid_header && cscf->ignore_invalid_headers) { /* there was error while a header line parsing */ @@ -796,7 +797,6 @@ ngx_http_process_request_headers(ngx_eve &header); continue; } -#endif /* a header line has been parsed successfully */ @@ -1406,7 +1406,9 @@ ngx_http_finalize_request(ngx_http_reque ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http finalize request: %d, \"%V\"", rc, &r->uri); - if (r->parent && rc >= NGX_HTTP_SPECIAL_RESPONSE) { + if (r->parent + && (rc >= NGX_HTTP_SPECIAL_RESPONSE || rc == NGX_HTTP_NO_CONTENT)) + { ngx_http_finalize_request(r, ngx_http_special_response_handler(r, rc)); return; } @@ -1450,7 +1452,7 @@ ngx_http_finalize_request(ngx_http_reque return; } - if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { + if (rc >= NGX_HTTP_SPECIAL_RESPONSE || rc == NGX_HTTP_NO_CONTENT) { if (r->connection->read->timer_set) { ngx_del_timer(r->connection->read); diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h --- a/src/http/ngx_http_request.h +++ b/src/http/ngx_http_request.h @@ -42,6 +42,7 @@ #define NGX_HTTP_OK 200 +#define NGX_HTTP_NO_CONTENT 204 #define NGX_HTTP_PARTIAL_CONTENT 206 #define NGX_HTTP_SPECIAL_RESPONSE 300 @@ -337,6 +338,8 @@ struct ngx_http_request_s { /* URI with "\0" or "%00" */ unsigned zero_in_uri:1; + unsigned invalid_header:1; + unsigned valid_location:1; unsigned valid_unparsed_uri:1; unsigned uri_changed:1; diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c --- a/src/http/ngx_http_special_response.c +++ b/src/http/ngx_http_special_response.c @@ -191,6 +191,10 @@ static char error_504_page[] = static ngx_str_t error_pages[] = { + ngx_null_string, /* 204 */ + +#define NGX_HTTP_LEVEL_200 1 + /* ngx_null_string, */ /* 300 */ ngx_string(error_301_page), ngx_string(error_302_page), @@ -290,17 +294,23 @@ ngx_http_special_response_handler(ngx_ht } } - if (error < NGX_HTTP_BAD_REQUEST) { + if (error == NGX_HTTP_NO_CONTENT) { + /* 204 */ + err = 0; + + } else if (error < NGX_HTTP_BAD_REQUEST) { /* 3XX */ err = error - NGX_HTTP_MOVED_PERMANENTLY; } else if (error < NGX_HTTP_NGX_CODES) { /* 4XX */ - err = error - NGX_HTTP_BAD_REQUEST + NGX_HTTP_LEVEL_300; + err = error - NGX_HTTP_BAD_REQUEST + NGX_HTTP_LEVEL_200 + + NGX_HTTP_LEVEL_300; } else { /* 49X, 5XX */ - err = error - NGX_HTTP_NGX_CODES + NGX_HTTP_LEVEL_300 + err = error - NGX_HTTP_NGX_CODES + NGX_HTTP_LEVEL_200 + + NGX_HTTP_LEVEL_300 + NGX_HTTP_LEVEL_400; switch (error) { case NGX_HTTP_TO_HTTPS: diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -779,12 +779,6 @@ ngx_http_upstream_process_header(ngx_eve return; } - if (n == NGX_HTTP_INTERNAL_SERVER_ERROR) { - ngx_http_upstream_finalize_request(r, u, - NGX_HTTP_INTERNAL_SERVER_ERROR); - return; - } - u->header_in.last += n; #if 0 diff --git a/src/http/ngx_http_write_filter_module.c b/src/http/ngx_http_write_filter_module.c --- a/src/http/ngx_http_write_filter_module.c +++ b/src/http/ngx_http_write_filter_module.c @@ -168,6 +168,7 @@ ngx_http_write_filter(ngx_http_request_t return NGX_OK; } +#if 0 /* * avoid the output if there are no incoming bufs but there are * the postponed requests or data @@ -176,6 +177,7 @@ ngx_http_write_filter(ngx_http_request_t if (in == NULL && r->postponed) { return NGX_OK; } +#endif if (c->write->delayed) { return NGX_AGAIN;