nginx-0.1.30-RELEASE import

*) 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 the bug had 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.
This commit is contained in:
Igor Sysoev 2005-05-14 18:42:03 +00:00
parent a599375d3b
commit 3362b8df04
14 changed files with 135 additions and 26 deletions

View File

@ -9,6 +9,69 @@
<title lang="en">nginx changelog</title> <title lang="en">nginx changelog</title>
<changes ver="0.1.30" date="14.05.2005">
<change type="bugfix">
<para lang="ru">
ÐÒÉ ÉÓÐÏÌØÚÏ×ÁÎÉÉ SSI ÒÁÂÏÞÉÊ ÐÒÏÃÅÓÓ ÍÏÇ ÚÁÃÉËÌÉÔØÓÑ.
</para>
<para lang="en">
the worker process may got caught in an endless loop if the SSI was used.
</para>
</change>
<change type="bugfix">
<para lang="ru">
ÐÒÉ ÉÓÐÏÌØÚÏ×ÁÎÉÉ SSL ÏÔ×ÅÔ ÍÏÇ ÐÅÒÅÄÁ×ÁÔØÓÑ ÎÅ ÄÏ ËÏÎÃÁ.
</para>
<para lang="en">
the response encrypted by SSL may not transferred complete.
</para>
</change>
<change type="bugfix">
<para lang="ru">
ÅÓÌÉ ÄÌÉÎÁ ÞÁÓÔÉ ÏÔ×ÅÔÁ, ÐÏÌÕÞÅÎÎÏÇÏ ÚÁ ÏÄÉÎ ÒÁÚ ÏÔ ÐÒÏËÓÉÒÕÅÍÏÇÏ ÉÌÉ
FastCGI ÓÅÒ×ÅÒÁ ÂÙÌÁ ÒÁ×ÎÁ 500 ÂÁÊÔ, ÔÏ nginx ×ÏÚ×ÒÁÝÁÌ ËÏÄ ÏÔ×ÅÔÁ 500;
× ÒÅÖÉÍÅ ÐÒÏËÓÉ ÏÛÉÂËÁ ÐÏÑ×ÉÌÁÓØ ÔÏÌØËÏ × 0.1.29.
</para>
<para lang="en">
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.
</para>
</change>
<change type="bugfix">
<para lang="ru">
nginx ÎÅ ÓÞÉÔÁÌ ÎÅ×ÅÒÎÙÍÉ ÄÉÒÅËÔÉ×Ù Ó 8-À ÉÌÉ 9-À ÐÁÒÁÍÅÔÒÁÍÉ.
</para>
<para lang="en">
nginx did not consider the directives with 8 or 9 parameters as invalid.
</para>
</change>
<change type="feature">
<para lang="ru">
ÄÉÒÅËÔÉ×Á return ÍÏÖÅÔ ×ÏÚ×ÒÁÝÁÔØ ËÏÄ ÏÔ×ÅÔÁ 204.
</para>
<para lang="en">
the "return" directive can return the 204 response code.
</para>
</change>
<change type="feature">
<para lang="ru">
ÄÉÒÅËÔÉ×Á ignore_invalid_headers.
</para>
<para lang="en">
the "ignore_invalid_headers" directive.
</para>
</change>
</changes>
<changes ver="0.1.29" date="12.05.2005"> <changes ver="0.1.29" date="12.05.2005">
<change type="feature"> <change type="feature">
@ -159,12 +222,12 @@ the "fastcgi_param" directive.
<change type="change"> <change type="change">
<para lang="ru"> <para lang="ru">
ÄÉÒÅËÔÉ×Ù fastcgi_set_var É fastcgi_params ÕÐÒÁÚÄÎÅÎÙ É ÄÏÌÖÎÙ ÂÙÔØ ÄÉÒÅËÔÉ×Ù fastcgi_root, fastcgi_set_var É fastcgi_params ÕÐÒÁÚÄÎÅÎÙ
ÚÁÍÅÎÙ ÄÉÒÅËÔÉ×ÁÍÉ fastcgi_param. É ÄÏÌÖÎÙ ÂÙÔØ ÚÁÍÅÎÙ ÄÉÒÅËÔÉ×ÁÍÉ fastcgi_param.
</para> </para>
<para lang="en"> <para lang="en">
the "fastcgi_set_var" and "fastcgi_params" directive are canceled and the "fastcgi_root", "fastcgi_set_var" and "fastcgi_params" directive
must be replaced with the fastcgi_param directives. are canceled and must be replaced with the fastcgi_param directives.
</para> </para>
</change> </change>

View File

@ -8,7 +8,7 @@
#define _NGINX_H_INCLUDED_ #define _NGINX_H_INCLUDED_
#define NGINX_VER "nginx/0.1.29" #define NGINX_VER "nginx/0.1.30"
#define NGINX_VAR "NGINX" #define NGINX_VAR "NGINX"
#define NGX_NEWPID_EXT ".newbin" #define NGX_NEWPID_EXT ".newbin"

View File

@ -263,7 +263,7 @@ ngx_conf_handler(ngx_conf_t *cf, ngx_int_t last)
valid = 0; valid = 0;
} }
} else if (cf->args->nelts <= 10 } else if (cf->args->nelts <= NGX_CONF_MAX_ARGS
&& (cmd->type && (cmd->type
& argument_number[cf->args->nelts - 1])) & argument_number[cf->args->nelts - 1]))
{ {

View File

@ -27,6 +27,8 @@
#define NGX_CONF_TAKE6 0x00000040 #define NGX_CONF_TAKE6 0x00000040
#define NGX_CONF_TAKE7 0x00000080 #define NGX_CONF_TAKE7 0x00000080
#define NGX_CONF_MAX_ARGS 8
#define NGX_CONF_TAKE12 (NGX_CONF_TAKE1|NGX_CONF_TAKE2) #define NGX_CONF_TAKE12 (NGX_CONF_TAKE1|NGX_CONF_TAKE2)
#define NGX_CONF_TAKE13 (NGX_CONF_TAKE1|NGX_CONF_TAKE3) #define NGX_CONF_TAKE13 (NGX_CONF_TAKE1|NGX_CONF_TAKE3)

View File

@ -361,8 +361,9 @@ ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
return NGX_CHAIN_ERROR; return NGX_CHAIN_ERROR;
} }
if (n < 0) { if (n == NGX_AGAIN) {
n = 0; c->buffered = 1;
return in;
} }
buf->pos += n; buf->pos += n;

View File

@ -144,6 +144,13 @@ static ngx_command_t ngx_http_core_commands[] = {
offsetof(ngx_http_core_srv_conf_t, restrict_host_names), offsetof(ngx_http_core_srv_conf_t, restrict_host_names),
&ngx_http_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_string("location"),
NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12, NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12,
ngx_http_core_location, ngx_http_core_location,
@ -505,7 +512,10 @@ ngx_http_core_run_phases(ngx_http_request_t *r)
continue; 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); ngx_http_finalize_request(r, rc);
return; return;
} }
@ -1578,6 +1588,7 @@ ngx_http_core_create_srv_conf(ngx_conf_t *cf)
cscf->client_header_timeout = NGX_CONF_UNSET_MSEC; cscf->client_header_timeout = NGX_CONF_UNSET_MSEC;
cscf->client_header_buffer_size = NGX_CONF_UNSET_SIZE; cscf->client_header_buffer_size = NGX_CONF_UNSET_SIZE;
cscf->restrict_host_names = NGX_CONF_UNSET_UINT; cscf->restrict_host_names = NGX_CONF_UNSET_UINT;
cscf->ignore_invalid_headers = NGX_CONF_UNSET;
return cscf; return cscf;
} }
@ -1663,6 +1674,9 @@ ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_unsigned_value(conf->restrict_host_names, ngx_conf_merge_unsigned_value(conf->restrict_host_names,
prev->restrict_host_names, 0); prev->restrict_host_names, 0);
ngx_conf_merge_value(conf->ignore_invalid_headers,
prev->ignore_invalid_headers, 1);
return NGX_CONF_OK; return NGX_CONF_OK;
} }

View File

@ -87,6 +87,8 @@ typedef struct {
ngx_msec_t client_header_timeout; ngx_msec_t client_header_timeout;
ngx_uint_t restrict_host_names; ngx_uint_t restrict_host_names;
ngx_flag_t ignore_invalid_headers;
} ngx_http_core_srv_conf_t; } ngx_http_core_srv_conf_t;

View File

@ -48,7 +48,7 @@ static ngx_str_t ngx_http_status_lines[] = {
ngx_null_string, /* "201 Created" */ ngx_null_string, /* "201 Created" */
ngx_null_string, /* "202 Accepted" */ ngx_null_string, /* "202 Accepted" */
ngx_null_string, /* "203 Non-Authoritative Information" */ 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_null_string, /* "205 Reset Content" */
ngx_string("206 Partial Content"), ngx_string("206 Partial Content"),
@ -167,8 +167,8 @@ ngx_http_header_filter(ngx_http_request_t *r)
if (r->headers_out.last_modified_time != -1) { if (r->headers_out.last_modified_time != -1) {
if (r->headers_out.status != NGX_HTTP_OK 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_time = -1;
r->headers_out.last_modified = NULL; r->headers_out.last_modified = NULL;
@ -193,6 +193,16 @@ ngx_http_header_filter(ngx_http_request_t *r)
/* 2XX */ /* 2XX */
status = r->headers_out.status - NGX_HTTP_OK; 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) { } else if (r->headers_out.status < NGX_HTTP_BAD_REQUEST) {
/* 3XX */ /* 3XX */
status = r->headers_out.status - NGX_HTTP_MOVED_PERMANENTLY status = r->headers_out.status - NGX_HTTP_MOVED_PERMANENTLY

View File

@ -529,6 +529,8 @@ ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b)
/* first char */ /* first char */
case sw_start: case sw_start:
r->invalid_header = 0;
switch (ch) { switch (ch) {
case CR: case CR:
r->header_end = p; r->header_end = p;
@ -552,6 +554,8 @@ ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b)
break; break;
} }
r->invalid_header = 1;
break; break;
} }
@ -606,6 +610,8 @@ ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b)
break; break;
} }
r->invalid_header = 1;
break; break;
/* space* before header value */ /* space* before header value */

View File

@ -725,6 +725,7 @@ ngx_http_process_request_headers(ngx_event_t *rev)
ngx_connection_t *c; ngx_connection_t *c;
ngx_http_header_t *hh; ngx_http_header_t *hh;
ngx_http_request_t *r; ngx_http_request_t *r;
ngx_http_core_srv_conf_t *cscf;
ngx_http_core_main_conf_t *cmcf; ngx_http_core_main_conf_t *cmcf;
c = rev->data; c = rev->data;
@ -742,6 +743,7 @@ ngx_http_process_request_headers(ngx_event_t *rev)
} }
cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); 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; hh = (ngx_http_header_t *) cmcf->headers_in_hash.buckets;
rc = NGX_AGAIN; rc = NGX_AGAIN;
@ -783,8 +785,7 @@ ngx_http_process_request_headers(ngx_event_t *rev)
if (rc == NGX_OK) { if (rc == NGX_OK) {
#if 0 if (r->invalid_header && cscf->ignore_invalid_headers) {
if (r->invalid_header) {
/* there was error while a header line parsing */ /* there was error while a header line parsing */
@ -796,7 +797,6 @@ ngx_http_process_request_headers(ngx_event_t *rev)
&header); &header);
continue; continue;
} }
#endif
/* a header line has been parsed successfully */ /* a header line has been parsed successfully */
@ -1406,7 +1406,9 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http finalize request: %d, \"%V\"", rc, &r->uri); "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)); ngx_http_finalize_request(r, ngx_http_special_response_handler(r, rc));
return; return;
} }
@ -1450,7 +1452,7 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
return; return;
} }
if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { if (rc >= NGX_HTTP_SPECIAL_RESPONSE || rc == NGX_HTTP_NO_CONTENT) {
if (r->connection->read->timer_set) { if (r->connection->read->timer_set) {
ngx_del_timer(r->connection->read); ngx_del_timer(r->connection->read);

View File

@ -42,6 +42,7 @@
#define NGX_HTTP_OK 200 #define NGX_HTTP_OK 200
#define NGX_HTTP_NO_CONTENT 204
#define NGX_HTTP_PARTIAL_CONTENT 206 #define NGX_HTTP_PARTIAL_CONTENT 206
#define NGX_HTTP_SPECIAL_RESPONSE 300 #define NGX_HTTP_SPECIAL_RESPONSE 300
@ -337,6 +338,8 @@ struct ngx_http_request_s {
/* URI with "\0" or "%00" */ /* URI with "\0" or "%00" */
unsigned zero_in_uri:1; unsigned zero_in_uri:1;
unsigned invalid_header:1;
unsigned valid_location:1; unsigned valid_location:1;
unsigned valid_unparsed_uri:1; unsigned valid_unparsed_uri:1;
unsigned uri_changed:1; unsigned uri_changed:1;

View File

@ -191,6 +191,10 @@ static char error_504_page[] =
static ngx_str_t error_pages[] = { static ngx_str_t error_pages[] = {
ngx_null_string, /* 204 */
#define NGX_HTTP_LEVEL_200 1
/* ngx_null_string, */ /* 300 */ /* ngx_null_string, */ /* 300 */
ngx_string(error_301_page), ngx_string(error_301_page),
ngx_string(error_302_page), ngx_string(error_302_page),
@ -290,17 +294,23 @@ ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
} }
} }
if (error < NGX_HTTP_BAD_REQUEST) { if (error == NGX_HTTP_NO_CONTENT) {
/* 204 */
err = 0;
} else if (error < NGX_HTTP_BAD_REQUEST) {
/* 3XX */ /* 3XX */
err = error - NGX_HTTP_MOVED_PERMANENTLY; err = error - NGX_HTTP_MOVED_PERMANENTLY;
} else if (error < NGX_HTTP_NGX_CODES) { } else if (error < NGX_HTTP_NGX_CODES) {
/* 4XX */ /* 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 { } else {
/* 49X, 5XX */ /* 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; + NGX_HTTP_LEVEL_400;
switch (error) { switch (error) {
case NGX_HTTP_TO_HTTPS: case NGX_HTTP_TO_HTTPS:

View File

@ -779,12 +779,6 @@ ngx_http_upstream_process_header(ngx_event_t *rev)
return; 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; u->header_in.last += n;
#if 0 #if 0

View File

@ -168,6 +168,7 @@ ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
return NGX_OK; return NGX_OK;
} }
#if 0
/* /*
* avoid the output if there are no incoming bufs but there are * avoid the output if there are no incoming bufs but there are
* the postponed requests or data * the postponed requests or data
@ -176,6 +177,7 @@ ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
if (in == NULL && r->postponed) { if (in == NULL && r->postponed) {
return NGX_OK; return NGX_OK;
} }
#endif
if (c->write->delayed) { if (c->write->delayed) {
return NGX_AGAIN; return NGX_AGAIN;