nginx-0.1.27-RELEASE import

*) Feature: the "blocked" parameter of the "valid_referers" directive.

    *) Change: the errors while handling the request header now logged at
       "info" level. The server name and the "Host" and "Referer" header
       lines also logged.

    *) Change: the "Host" header line is also logged in error log.

    *) Feature: the proxy_pass_unparsed_uri directive. The special handling
       of the "://" symbols in URI, appeared in 0.1.11 version, now is
       canceled.

    *) Bugfix: nginx could not be built on FreeBSD and Linux, if the
       --without-ngx_http_auth_basic_module configuration parameter was
       used.
This commit is contained in:
Igor Sysoev 2005-03-28 14:43:02 +00:00
parent c4d120bb43
commit c04deca88f
14 changed files with 384 additions and 354 deletions

View File

@ -9,6 +9,65 @@
<title lang="en">nginx changelog</title>
<changes ver="0.1.27" date="28.03.2005">
<change type="feature">
<para lang="ru">
ÐÁÒÁÍÅÔÒ blocked × ÄÉÒÅËÔÉ×Å invalid_referers.
</para>
<para lang="en">
the "blocked" parameter of the "invalid_referers" directive.
</para>
</change>
<change type="change">
<para lang="ru">
ÏÛÉÂËÉ ÏÂÒÁÂÏÔËÉ ÚÁÇÏÌÏ×ËÁ ÚÁÐÒÏÓÁ ÔÅÐÅÒØ ÚÁÐÉÓÙ×ÁÀÔÓÑ ÎÁ ÕÒÏ×ÎÅ
info, × ÌÏÇ ÔÁËÖÅ ÚÁÐÉÓÙ×ÁÅÔÓÑ ÉÍÑ ÓÅÒ×ÅÒÁ É ÓÔÒÏËÉ ÚÁÇÏÌÏ×ËÁ
ÚÁÐÒÏÓÁ "Host" É "Referer".
</para>
<para lang="en">
the errors while handling the request header now logged at "info" level.
The server name and the "Host" and "Referer" header lines also logged.
</para>
</change>
<change type="change">
<para lang="ru">
ÐÒÉ ÚÁÐÉÓÉ ÏÛÉÂÏË × ÌÏÇ ÚÁÐÉÓÙ×ÁÅÔÓÑ ÔÁËÖÅ ÓÔÒÏËÁ ÚÁÇÏÌÏ×ËÁ ÚÁÐÒÏÓÁ "Host".
</para>
<para lang="en">
the "Host" header line is also logged in error log.
</para>
</change>
<change type="feature">
<para lang="ru">
ÄÉÒÅËÔÉ×Á proxy_pass_unparsed_uri.
óÐÅÃÉÁÌØÎÁÑ ÏÂÒÁÂÏÔËÁ ÓÉÍ×ÏÌÏ× "://" × URI, ××ÅÄ£ÎÎÁÑ × ×ÅÒÓÉÉ 0.1.11,
ÔÅÐÅÒØ ÕÐÒÁÚÄÎÅÎÁ.
</para>
<para lang="en">
the proxy_pass_unparsed_uri directive.
The special handling of the "://" symbols in URI, appeared in 0.1.11 version,
now is canceled.
</para>
</change>
<change type="bugfix">
<para lang="ru">
nginx ÎÅ ÓÏÂÉÒÁÌÓÑ ÎÁ FreeBSD É Linux, ÅÓÌÉ ÂÙÌ ÕËÁÚÁÎ ÐÁÒÁÍÅÔÒ ËÏÎÆÉÇÕÒÁÃÉÉ
--without-ngx_http_auth_basic_module.
</para>
<para lang="en">
nginx could not be built on FreeBSD and Linux, if the
--without-ngx_http_auth_basic_module configuration parameter was used.
</para>
</change>
</changes>
<changes ver="0.1.26" date="22.03.2005">
<change type="change">
@ -23,11 +82,11 @@ the invalid client header lines are now ignored and logged at the info level.
<change type="change">
<para lang="ru">
при записи ошибок в лог записывается так же имя хоста, при обращении
к которому, произошла ошибка.
ÐÒÉ ÚÁÐÉÓÉ ÏÛÉÂÏË × ÌÏÇ ÚÁÐÉÓÙ×ÁÅÔÓÑ ÔÁËÖÅ ÉÍÑ ÓÅÒ×ÅÒÁ, ÐÒÉ ÏÂÒÁÝÅÎÉÉ
Ë ËÏÔÏÒÏÍÕ ÐÒÏÉÚÏÛÌÁ ÏÛÉÂËÁ.
</para>
<para lang="en">
the host name is also logged in error log.
the server name is also logged in error log.
</para>
</change>

View File

@ -282,7 +282,7 @@ ngx_add_inherited_sockets(ngx_cycle_t *cycle)
if (s == NGX_ERROR) {
ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
"invalid socket number \"%s\" in "
NGINX_VAR " enviroment variable, "
NGINX_VAR " environment variable, "
"ignoring the rest of the variable", v);
break;
}

View File

@ -36,6 +36,7 @@ typedef struct {
ngx_flag_t log;
ngx_flag_t no_referer;
ngx_flag_t blocked_referer;
} ngx_http_rewrite_loc_conf_t;
@ -378,6 +379,7 @@ ngx_http_rewrite_regex_start_code(ngx_http_rewrite_engine_t *e)
if (code->uri) {
if (!code->break_cycle) {
r->uri_changed = 1;
r->valid_unparsed_uri = 1;
}
if (rc && (r->quoted_uri || r->plus_in_uri)) {
@ -715,6 +717,7 @@ ngx_http_rewrite_invalid_referer_code(ngx_http_rewrite_engine_t *e)
e->sp++;
return;
} else {
e->sp->value = 1;
e->sp->text.len = 1;
@ -731,12 +734,22 @@ ngx_http_rewrite_invalid_referer_code(ngx_http_rewrite_engine_t *e)
if (len < sizeof("http://i.ru") - 1
|| (ngx_strncasecmp(ref, "http://", 7) != 0))
{
e->sp->value = 1;
e->sp->text.len = 1;
e->sp->text.data = (u_char *) "1";
e->sp++;
if (cf->blocked_referer) {
e->sp->value = 0;
e->sp->text.len = 0;
e->sp->text.data = (u_char *) "0";
e->sp++;
return;
return;
} else {
e->sp->value = 1;
e->sp->text.len = 1;
e->sp->text.data = (u_char *) "1";
e->sp++;
return;
}
}
len -= 7;
@ -853,6 +866,7 @@ ngx_http_rewrite_create_loc_conf(ngx_conf_t *cf)
conf->stack_size = NGX_CONF_UNSET_UINT;
conf->log = NGX_CONF_UNSET;
conf->no_referer = NGX_CONF_UNSET;
conf->blocked_referer = NGX_CONF_UNSET;
return conf;
}
@ -873,12 +887,17 @@ ngx_http_rewrite_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
if (conf->referers == NULL) {
conf->referers = prev->referers;
ngx_conf_merge_value(conf->no_referer, prev->no_referer, 0);
ngx_conf_merge_value(conf->blocked_referer, prev->blocked_referer, 0);
}
if (conf->no_referer == NGX_CONF_UNSET) {
conf->no_referer = 0;
}
if (conf->blocked_referer == NGX_CONF_UNSET) {
conf->blocked_referer = 0;
}
if (conf->codes == NULL) {
return NGX_CONF_OK;
}
@ -1540,6 +1559,11 @@ ngx_http_rewrite_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
continue;
}
if (ngx_strcmp(value[i].data, "blocked") == 0) {
lcf->blocked_referer = 1;
continue;
}
if (ngx_strcmp(value[i].data, "server_names") == 0) {
server_names = 1;
continue;

View File

@ -107,6 +107,13 @@ static ngx_command_t ngx_http_proxy_commands[] = {
offsetof(ngx_http_proxy_loc_conf_t, preserve_host),
NULL },
{ ngx_string("proxy_pass_unparsed_uri"),
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, pass_unparsed_uri),
NULL },
{ ngx_string("proxy_set_x_url"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
@ -802,7 +809,6 @@ u_char *ngx_http_proxy_log_error(ngx_log_t *log, u_char *buf, size_t len)
{
u_char *p;
ngx_int_t escape;
ngx_str_t uri;
ngx_http_request_t *r;
ngx_peer_connection_t *peer;
ngx_http_proxy_log_ctx_t *ctx;
@ -814,7 +820,7 @@ u_char *ngx_http_proxy_log_error(ngx_log_t *log, u_char *buf, size_t len)
peer = &ctx->proxy->upstream->peer;
p = ngx_snprintf(buf, len,
" while %s, client: %V, host: %V, URL: \"%V\","
" while %s, client: %V, server: %V, URL: \"%V\","
" upstream: http://%V%s%V",
ctx->proxy->action,
&r->connection->addr_text,
@ -826,6 +832,13 @@ u_char *ngx_http_proxy_log_error(ngx_log_t *log, u_char *buf, size_t len)
len -= p - buf;
buf = p;
if (ctx->proxy->lcf->pass_unparsed_uri && r->valid_unparsed_uri) {
p = ngx_cpymem(buf, r->unparsed_uri.data + 1, r->unparsed_uri.len - 1);
len -= p - buf;
return ngx_http_log_error_info(r, p, len);
}
if (r->quoted_uri) {
escape = 2 * ngx_escape_uri(NULL, r->uri.data + uc->location->len,
r->uri.len - uc->location->len,
@ -841,14 +854,15 @@ u_char *ngx_http_proxy_log_error(ngx_log_t *log, u_char *buf, size_t len)
r->uri.len - uc->location->len, NGX_ESCAPE_URI);
buf += r->uri.len - uc->location->len + escape;
if (r->args.len == 0) {
return buf;
}
len -= r->uri.len - uc->location->len + escape;
return ngx_snprintf(buf, len, "?%V", &r->args);
if (r->args.len) {
p = ngx_snprintf(buf, len, "?%V", &r->args);
len -= p - buf;
buf = p;
}
return ngx_http_log_error_info(r, buf, len);
}
p = ngx_palloc(r->pool, r->uri.len - uc->location->len + escape);
@ -859,17 +873,23 @@ u_char *ngx_http_proxy_log_error(ngx_log_t *log, u_char *buf, size_t len)
ngx_escape_uri(p, r->uri.data + uc->location->len,
r->uri.len - uc->location->len, NGX_ESCAPE_URI);
uri.len = r->uri.len - uc->location->len + escape;
uri.data = p;
p = ngx_cpymem(buf, p, r->uri.len - uc->location->len + escape);
} else {
uri.len = r->uri.len - uc->location->len;
uri.data = r->uri.data + uc->location->len;
p = ngx_cpymem(buf, r->uri.data + uc->location->len,
r->uri.len - uc->location->len);
}
return ngx_snprintf(buf, len, "%V%s%V",
&uri, r->args.len ? "?" : "", &r->args);
len -= p - buf;
buf = p;
if (r->args.len) {
p = ngx_snprintf(buf, len, "?%V", &r->args);
len -= p - buf;
buf = p;
}
return ngx_http_log_error_info(r, buf, len);
}
@ -1109,6 +1129,7 @@ static void *ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
conf->send_timeout = NGX_CONF_UNSET_MSEC;
conf->send_lowat = NGX_CONF_UNSET_SIZE;
conf->pass_unparsed_uri = NGX_CONF_UNSET;
conf->preserve_host = NGX_CONF_UNSET;
conf->set_x_url = NGX_CONF_UNSET;
conf->set_x_real_ip = NGX_CONF_UNSET;
@ -1149,6 +1170,15 @@ static char *ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf,
ngx_conf_merge_msec_value(conf->send_timeout, prev->send_timeout, 60000);
ngx_conf_merge_size_value(conf->send_lowat, prev->send_lowat, 0);
ngx_conf_merge_value(conf->pass_unparsed_uri, prev->pass_unparsed_uri, 0);
if (conf->pass_unparsed_uri && conf->upstream->location->len > 1) {
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
"\"proxy_pass_unparsed_uri\" can be set for "
"location \"/\" or given by regular expression.");
return NGX_CONF_ERROR;
}
ngx_conf_merge_value(conf->preserve_host, prev->preserve_host, 0);
ngx_conf_merge_value(conf->set_x_url, prev->set_x_url, 0);
ngx_conf_merge_value(conf->set_x_real_ip, prev->set_x_real_ip, 0);

View File

@ -80,6 +80,7 @@ typedef struct {
ngx_flag_t set_x_url;
ngx_flag_t set_x_real_ip;
ngx_flag_t add_x_forwarded_for;
ngx_flag_t pass_unparsed_uri;
ngx_flag_t pass_server;
ngx_flag_t pass_x_accel_expires;
ngx_flag_t ignore_expires;

View File

@ -86,7 +86,7 @@ int ngx_http_proxy_request_upstream(ngx_http_proxy_ctx_t *p)
static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_proxy_ctx_t *p)
{
size_t len, loc_len;
size_t len;
ngx_uint_t i, escape, *index;
ngx_buf_t *b;
ngx_chain_t *chain;
@ -95,7 +95,6 @@ static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_proxy_ctx_t *p)
ngx_http_request_t *r;
ngx_http_variable_t *var;
ngx_http_variable_value_t *value;
ngx_http_core_loc_conf_t *clcf;
ngx_http_core_main_conf_t *cmcf;
ngx_http_proxy_upstream_conf_t *uc;
@ -107,32 +106,30 @@ static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_proxy_ctx_t *p)
index = NULL;
#endif
escape = 0;
if (p->upstream->method) {
len = http_methods[p->upstream->method - 1].len;
len = http_methods[p->upstream->method - 1].len + uc->uri.len;
} else {
len = r->method_name.len;
len = r->method_name.len + uc->uri.len;
}
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
if (p->lcf->pass_unparsed_uri && r->valid_unparsed_uri) {
len += r->unparsed_uri.len - 1;
#if (NGX_PCRE)
loc_len = (clcf->regex) ? 1 : clcf->name.len;
#else
loc_len = clcf->name.len;
#endif
if (r->quoted_uri) {
escape = 2 * ngx_escape_uri(NULL, r->uri.data + loc_len,
r->uri.len - loc_len, NGX_ESCAPE_URI);
} else {
escape = 0;
if (r->quoted_uri) {
escape = 2 * ngx_escape_uri(NULL, r->uri.data + uc->location->len,
r->uri.len - uc->location->len,
NGX_ESCAPE_URI);
}
len += r->uri.len - uc->location->len + escape
+ sizeof("?") - 1 + r->args.len;
}
len += uc->uri.len
+ r->uri.len - loc_len + escape
+ sizeof("?") - 1 + r->args.len
+ sizeof(http_version) - 1
len += sizeof(http_version) - 1
+ sizeof(connection_close_header) - 1
+ sizeof(CRLF) - 1;
@ -269,19 +266,24 @@ static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_proxy_ctx_t *p)
b->last = ngx_cpymem(b->last, uc->uri.data, uc->uri.len);
if (escape) {
ngx_escape_uri(b->last, r->uri.data + loc_len,
r->uri.len - loc_len, NGX_ESCAPE_URI);
b->last += r->uri.len - loc_len + escape;
if (p->lcf->pass_unparsed_uri && r->valid_unparsed_uri) {
b->last = ngx_cpymem(b->last, r->unparsed_uri.data + 1,
r->unparsed_uri.len - 1);
} else {
b->last = ngx_cpymem(b->last, r->uri.data + loc_len,
r->uri.len - loc_len);
}
if (escape) {
ngx_escape_uri(b->last, r->uri.data + uc->location->len,
r->uri.len - uc->location->len, NGX_ESCAPE_URI);
b->last += r->uri.len - uc->location->len + escape;
if (r->args.len > 0) {
*b->last++ = '?';
b->last = ngx_cpymem(b->last, r->args.data, r->args.len);
} else {
b->last = ngx_cpymem(b->last, r->uri.data + uc->location->len,
r->uri.len - uc->location->len);
}
if (r->args.len > 0) {
*b->last++ = '?';
b->last = ngx_cpymem(b->last, r->args.data, r->args.len);
}
}
b->last = ngx_cpymem(b->last, http_version, sizeof(http_version) - 1);

View File

@ -68,6 +68,8 @@ void ngx_http_empty_handler(ngx_event_t *wev);
ngx_int_t ngx_http_send_last(ngx_http_request_t *r);
void ngx_http_close_request(ngx_http_request_t *r, int error);
void ngx_http_close_connection(ngx_connection_t *c);
u_char * ngx_http_log_error_info(ngx_http_request_t *r, u_char *buf,
size_t len);
ngx_int_t ngx_http_read_client_request_body(ngx_http_request_t *r,

View File

@ -415,8 +415,10 @@ ngx_http_handler(ngx_http_request_t *r)
r->connection->write->event_handler = ngx_http_core_phase_event_handler;
r->valid_unparsed_uri = 1;
r->uri_changed = 1;
r->uri_changes = 11;
r->phase = NGX_HTTP_REWRITE_PHASE;
r->phase_handler = 0;

View File

@ -544,9 +544,9 @@ ngx_http_log_header_out_getlen(ngx_http_request_t *r, uintptr_t data)
/*
* No header pointer was found.
* However, some headers: "Date", "Server", "Content-Length",
* and "Last-Modified" have a special handling in the header filter
* but we do not set up their pointers in the filter because
* they are too seldom needed to be logged.
* and "Last-Modified" have a special handling in the header filter,
* but we do not set up their pointers in the filter,
* because they are too seldom needed to be logged.
*/
if (data == offsetof(ngx_http_headers_out_t, date)) {
@ -592,9 +592,9 @@ ngx_http_log_header_out(ngx_http_request_t *r, u_char *buf,
/*
* No header pointer was found.
* However, some headers: "Date", "Server", "Content-Length",
* and "Last-Modified" have a special handling in the header filter
* but we do not set up their pointers in the filter because
* they are too seldom needed to be logged.
* and "Last-Modified" have a special handling in the header filter,
* but we do not set up their pointers in the filter,
* because they are too seldom needed to be logged.
*/
if (op->data == offsetof(ngx_http_headers_out_t, date)) {

View File

@ -705,8 +705,6 @@ ngx_int_t ngx_http_parse_complex_uri(ngx_http_request_t *r)
u_char c, ch, decoded, *p, *u;
enum {
sw_usual = 0,
sw_colon,
sw_colon_slash,
sw_slash,
sw_dot,
sw_dot_dot,
@ -774,10 +772,6 @@ ngx_int_t ngx_http_parse_complex_uri(ngx_http_request_t *r)
case '?':
r->args_start = p;
goto done;
case ':':
state = sw_colon;
*u++ = ch;
break;
case '.':
r->uri_ext = u + 1;
*u++ = ch;
@ -789,67 +783,6 @@ ngx_int_t ngx_http_parse_complex_uri(ngx_http_request_t *r)
ch = *p++;
break;
case sw_colon:
switch(ch) {
#if (NGX_WIN32)
case '\\':
state = sw_colon_slash;
*u++ = '/';
break;
#endif
case '/':
state = sw_colon_slash;
*u++ = ch;
break;
case ':':
*u++ = ch;
break;
case '%':
quoted_state = state;
state = sw_quoted;
break;
case '?':
r->args_start = p;
goto done;
default:
state = sw_usual;
*u++ = ch;
break;
}
ch = *p++;
break;
case sw_colon_slash:
switch(ch) {
#if (NGX_WIN32)
case '\\':
state = sw_slash;
*u++ = '/';
break;
#endif
case '/':
state = sw_slash;
*u++ = ch;
break;
case '.':
state = sw_dot;
*u++ = ch;
break;
case '%':
quoted_state = state;
state = sw_quoted;
break;
case '?':
r->args_start = p;
goto done;
default:
state = sw_usual;
*u++ = ch;
break;
}
ch = *p++;
break;
case sw_slash:
switch(ch) {
#if (NGX_WIN32)

View File

@ -33,24 +33,19 @@ static void ngx_http_keepalive_handler(ngx_event_t *ev);
static void ngx_http_set_lingering_close(ngx_http_request_t *r);
static void ngx_http_lingering_close_handler(ngx_event_t *ev);
static void ngx_http_client_error(ngx_http_request_t *r,
int client_error, int error);
static u_char *ngx_http_log_error(ngx_log_t *log, u_char *buf, size_t len);
/* NGX_HTTP_PARSE_... errors */
static char *ngx_http_client_errors[] = {
static char *client_header_errors[] = {
"client %V sent invalid method \"%V\"",
"client %V sent invalid request \"%V\"",
"client %V sent too long URI in request \"%V\"",
"client %V sent invalid method in HTTP/0.9 request \"%V\"",
/* NGX_HTTP_PARSE_INVALID_METHOD */
"client sent invalid method",
"client %V sent invalid header, URL: \"%V\"",
"client %V sent too long header line, URL: \"%V\"",
"client %V sent HTTP/1.1 request without \"Host\" header, URL: \"%V\"",
"client %V sent invalid \"Content-Length\" header, URL: \"%V\"",
"client %V sent POST method without \"Content-Length\" header, URL: \"%V\"",
/* NGX_HTTP_PARSE_INVALID_REQUEST */
"client sent invalid request",
/* NGX_HTTP_PARSE_INVALID_09_METHOD */
"client sent invalid method in HTTP/0.9 request"
};
@ -199,6 +194,7 @@ void ngx_http_init_request(ngx_event_t *rev)
ngx_http_request_t *r;
ngx_http_in_port_t *in_port;
ngx_http_in_addr_t *in_addr;
ngx_http_log_ctx_t *ctx;
ngx_http_connection_t *hc;
ngx_http_server_name_t *server_name;
ngx_http_core_srv_conf_t *cscf;
@ -359,7 +355,7 @@ void ngx_http_init_request(ngx_event_t *rev)
/*
* The majority of browsers do not send the "close notify" alert.
* Among them are MSIE, Mozilla, Netscape 4, Konqueror, and Links.
* And what is more MSIE ignores the server's alert.
* And what is more, MSIE ignores the server's alert.
*
* Opera always sends the alert.
*/
@ -439,6 +435,9 @@ void ngx_http_init_request(ngx_event_t *rev)
r->http_state = NGX_HTTP_READING_REQUEST_STATE;
ctx = c->log->data;
ctx->request = r;
#if (NGX_STAT_STUB)
ngx_atomic_inc(ngx_stat_reading);
r->stat_reading = 1;
@ -467,7 +466,10 @@ ngx_http_ssl_handshake(ngx_event_t *rev)
"http check ssl handshake");
if (rev->timedout) {
ngx_http_client_error(r, 0, NGX_HTTP_REQUEST_TIME_OUT);
ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
c->timedout = 1;
ngx_http_close_request(r, NGX_HTTP_REQUEST_TIME_OUT);
ngx_http_close_connection(c);
return;
}
@ -528,7 +530,10 @@ ngx_http_process_request_line(ngx_event_t *rev)
"http process request line");
if (rev->timedout) {
ngx_http_client_error(r, 0, NGX_HTTP_REQUEST_TIME_OUT);
ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
c->timedout = 1;
ngx_http_close_request(r, NGX_HTTP_REQUEST_TIME_OUT);
ngx_http_close_connection(c);
return;
}
@ -572,14 +577,10 @@ ngx_http_process_request_line(ngx_event_t *rev)
rc = ngx_http_parse_complex_uri(r);
if (rc == NGX_HTTP_INTERNAL_SERVER_ERROR) {
ngx_http_close_request(r, rc);
ngx_http_close_connection(c);
return;
}
if (rc != NGX_OK) {
ngx_http_client_error(r, rc, NGX_HTTP_BAD_REQUEST);
if (rc == NGX_HTTP_PARSE_INVALID_REQUEST) {
ngx_log_error(NGX_LOG_INFO, c->log, 0,
"client sent invalid request");
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
return;
}
@ -632,9 +633,6 @@ ngx_http_process_request_line(ngx_event_t *rev)
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
"http exten: \"%V\"", &r->exten);
ctx = c->log->data;
ctx->request = r;
if (r->http_version < NGX_HTTP_VERSION_10) {
rev->event_handler = ngx_http_block_read;
ngx_http_handler(r);
@ -665,33 +663,15 @@ ngx_http_process_request_line(ngx_event_t *rev)
ngx_http_process_request_headers(rev);
return;
}
} else if (rc != NGX_AGAIN) {
if (rc != NGX_AGAIN) {
/* there was error while a request line parsing */
ngx_http_client_error(r, rc, NGX_HTTP_BAD_REQUEST);
#if 0
for (p = r->request_start; p < r->header_in->last; p++) {
if (*p == CR || *p == LF) {
break;
}
}
r->request_line.len = p - r->request_start;
r->request_line.data = r->request_start;
if (rc == NGX_HTTP_PARSE_INVALID_METHOD) {
r->http_version = NGX_HTTP_VERSION_10;
}
ngx_http_client_error(r, rc,
(rc == NGX_HTTP_PARSE_INVALID_METHOD) ?
NGX_HTTP_NOT_IMPLEMENTED:
NGX_HTTP_BAD_REQUEST);
#endif
ngx_log_error(NGX_LOG_INFO, c->log, 0,
ngx_http_client_errors[rc - NGX_HTTP_CLIENT_ERROR]);
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
return;
}
@ -708,8 +688,15 @@ ngx_http_process_request_line(ngx_event_t *rev)
}
if (rv == NGX_DECLINED) {
ngx_http_client_error(r, NGX_HTTP_PARSE_TOO_LONG_URI,
NGX_HTTP_REQUEST_URI_TOO_LARGE);
ctx = c->log->data;
ctx->request = r;
r->request_line.len = r->header_in->end - r->request_start;
r->request_line.data = r->request_start;
ngx_log_error(NGX_LOG_INFO, c->log, 0,
"client sent too long URI");
ngx_http_finalize_request(r, NGX_HTTP_REQUEST_URI_TOO_LARGE);
return;
}
}
@ -734,7 +721,10 @@ ngx_http_process_request_headers(ngx_event_t *rev)
"http process request header line");
if (rev->timedout) {
ngx_http_client_error(r, 0, NGX_HTTP_REQUEST_TIME_OUT);
ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
c->timedout = 1;
ngx_http_close_request(r, NGX_HTTP_REQUEST_TIME_OUT);
ngx_http_close_connection(c);
return;
}
@ -755,8 +745,13 @@ ngx_http_process_request_headers(ngx_event_t *rev)
}
if (rv == NGX_DECLINED) {
ngx_http_client_error(r, NGX_HTTP_PARSE_TOO_LONG_HEADER,
NGX_HTTP_BAD_REQUEST);
header.len = r->header_in->end - r->header_name_start;
header.data = r->header_name_start;
ngx_log_error(NGX_LOG_INFO, c->log, 0,
"client sent too long header line: \"%V\"",
&header);
ngx_http_close_request(r, NGX_HTTP_BAD_REQUEST);
ngx_http_close_connection(c);
return;
}
}
@ -779,8 +774,8 @@ ngx_http_process_request_headers(ngx_event_t *rev)
header.len = r->header_end - r->header_name_start;
header.data = r->header_name_start;
ngx_log_error(NGX_LOG_INFO, rev->log, 0,
"client sent invalid header: \"%V\", ignored,",
ngx_log_error(NGX_LOG_INFO, c->log, 0,
"client sent invalid header line: \"%V\"",
&header);
continue;
}
@ -838,8 +833,9 @@ ngx_http_process_request_headers(ngx_event_t *rev)
&h->key, &h->value);
continue;
}
} else if (rc == NGX_HTTP_PARSE_HEADER_DONE) {
if (rc == NGX_HTTP_PARSE_HEADER_DONE) {
/* a whole header has been parsed successfully */
@ -853,7 +849,6 @@ ngx_http_process_request_headers(ngx_event_t *rev)
rc = ngx_http_process_request_header(r);
if (rc != NGX_OK) {
ngx_http_client_error(r, rc, NGX_HTTP_BAD_REQUEST);
return;
}
@ -871,37 +866,25 @@ ngx_http_process_request_headers(ngx_event_t *rev)
rev->event_handler = ngx_http_block_read;
ngx_http_handler(r);
return;
} else if (rc != NGX_AGAIN) {
/* there was error while a header line parsing */
#if (NGX_DEBUG)
if (rc == NGX_HTTP_PARSE_INVALID_HEADER
&& (rev->log->log_level & NGX_LOG_DEBUG_HTTP))
{
u_char *p;
for (p = r->header_name_start;
p < r->header_in->last - 1;
p++)
{
if (*p == LF) {
break;
}
}
*p = '\0';
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, rev->log, 0,
"http invalid header: \"%s\"",
r->header_name_start);
}
#endif
ngx_http_client_error(r, rc, NGX_HTTP_BAD_REQUEST);
return;
}
/* NGX_AGAIN: a header line parsing is still not complete */
if (rc == NGX_AGAIN) {
/* a header line parsing is still not complete */
continue;
}
/* rc == NGX_HTTP_PARSE_INVALID_HEADER: "\r" is not followed by "\n" */
header.len = r->header_end - r->header_name_start;
header.data = r->header_name_start;
ngx_log_error(NGX_LOG_INFO, c->log, 0,
"client sent invalid header line: \"%V\\r...\"",
&header);
ngx_http_close_request(r, NGX_HTTP_BAD_REQUEST);
ngx_http_close_connection(c);
return;
}
}
@ -1108,8 +1091,9 @@ ngx_http_alloc_large_header_buffer(ngx_http_request_t *r,
static ngx_int_t
ngx_http_process_request_header(ngx_http_request_t *r)
{
u_char *ua, *user_agent, ch;
size_t len;
size_t len;
u_char *ua, *user_agent, ch;
ngx_http_core_srv_conf_t *cscf;
if (r->headers_in.host) {
for (len = 0; len < r->headers_in.host->value.len; len++) {
@ -1121,16 +1105,33 @@ ngx_http_process_request_header(ngx_http_request_t *r)
r->headers_in.host->value.data[len] = ngx_tolower(ch);
}
r->headers_in.host_name_len = len;
if (ngx_http_find_virtual_server(r) != NGX_OK) {
return NGX_HTTP_PARSE_INVALID_HOST;
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
"client sent invalid \"Host\" header");
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
if (cscf->restrict_host_names == NGX_HTTP_RESTRICT_HOST_CLOSE) {
ngx_http_close_request(r, NGX_HTTP_BAD_REQUEST);
ngx_http_close_connection(r->connection);
return NGX_ERROR;
}
ngx_http_finalize_request(r, NGX_HTTP_INVALID_HOST);
return NGX_ERROR;
}
} else {
if (r->http_version > NGX_HTTP_VERSION_10) {
return NGX_HTTP_PARSE_NO_HOST_HEADER;
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
"client sent HTTP/1.1 request without \"Host\" header");
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
return NGX_ERROR;
}
r->headers_in.host_name_len = 0;
}
@ -1140,16 +1141,25 @@ ngx_http_process_request_header(ngx_http_request_t *r)
r->headers_in.content_length->value.len);
if (r->headers_in.content_length_n == NGX_ERROR) {
return NGX_HTTP_PARSE_INVALID_CL_HEADER;
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
"client sent invalid \"Content-Length\" header");
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
return NGX_ERROR;
}
}
if (r->method == NGX_HTTP_POST && r->headers_in.content_length_n == -1) {
return NGX_HTTP_PARSE_POST_WO_CL_HEADER;
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
"client sent POST method without \"Content-Length\" header");
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
return NGX_ERROR;
}
if (r->plain_http) {
return NGX_HTTP_PARSE_HTTP_TO_HTTPS;
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
"client sent plain HTTP request to HTTPS port");
ngx_http_finalize_request(r, NGX_HTTP_TO_HTTPS);
return NGX_ERROR;
}
if (r->headers_in.connection) {
@ -1457,7 +1467,11 @@ ngx_http_writer(ngx_event_t *wev)
if (wev->timedout) {
if (!wev->delayed) {
ngx_http_client_error(r, 0, NGX_HTTP_REQUEST_TIME_OUT);
ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT,
"client timed out");
c->timedout = 1;
ngx_http_close_request(r, NGX_HTTP_REQUEST_TIME_OUT);
ngx_http_close_connection(c);
return;
}
@ -2267,105 +2281,11 @@ ngx_http_close_connection(ngx_connection_t *c)
}
static void
ngx_http_client_error(ngx_http_request_t *r, int client_error, int error)
{
u_char *p;
ngx_http_log_ctx_t *ctx;
ngx_http_core_srv_conf_t *cscf;
ctx = r->connection->log->data;
if (error == NGX_HTTP_REQUEST_TIME_OUT) {
ngx_log_error(NGX_LOG_INFO, r->connection->log, NGX_ETIMEDOUT,
"client timed out");
r->connection->timedout = 1;
ngx_http_close_request(r, error);
ngx_http_close_connection(r->connection);
return;
}
r->connection->log->handler = NULL;
if (ctx->request) {
switch (client_error) {
case NGX_HTTP_PARSE_INVALID_HOST:
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"client %V sent invalid \"Host\" header \"%V\", URL: \"%V\"",
ctx->client, &r->headers_in.host->value,
&ctx->request->unparsed_uri);
error = NGX_HTTP_INVALID_HOST;
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
if (cscf->restrict_host_names == NGX_HTTP_RESTRICT_HOST_CLOSE) {
ngx_http_close_request(r, error);
ngx_http_close_connection(r->connection);
return;
}
break;
case NGX_HTTP_PARSE_HTTP_TO_HTTPS:
error = NGX_HTTP_TO_HTTPS;
if (ctx->request->headers_in.referer) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"client %V sent plain HTTP request to HTTPS port, "
"URL: \"%V\", referrer \"%V\"",
ctx->client, &ctx->request->unparsed_uri,
&ctx->request->headers_in.referer->value);
} else {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"client %V sent plain HTTP request to HTTPS port, "
"URL: \"%V\"", ctx->client, &ctx->request->unparsed_uri);
}
break;
default:
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
client_header_errors[client_error - NGX_HTTP_CLIENT_ERROR],
ctx->client, &ctx->request->unparsed_uri);
}
} else {
if (error == NGX_HTTP_REQUEST_URI_TOO_LARGE) {
r->request_line.len = r->header_in->end - r->request_start;
r->request_line.data = r->request_start;
} else {
if (r->request_line.data == NULL) {
for (p = r->request_start; p < r->header_in->last; p++) {
if (*p == CR || *p == LF) {
break;
}
}
r->request_line.len = p - r->request_start;
r->request_line.data = r->request_start;
}
}
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
client_header_errors[client_error - NGX_HTTP_CLIENT_ERROR],
ctx->client, &r->request_line);
}
r->connection->log->handler = ngx_http_log_error;
ngx_http_finalize_request(r, error);
}
static u_char *
ngx_http_log_error(ngx_log_t *log, u_char *buf, size_t len)
{
u_char *p;
ngx_http_request_t *r;
ngx_http_log_ctx_t *ctx;
p = buf;
@ -2375,29 +2295,71 @@ ngx_http_log_error(ngx_log_t *log, u_char *buf, size_t len)
if (log->action) {
p = ngx_snprintf(p, len, " while %s", log->action);
len -= p - buf;
buf = p;
}
p = ngx_snprintf(p, len, ", client: %V", ctx->client);
p = ngx_snprintf(buf, len, ", client: %V", ctx->client);
if (ctx->request == NULL) {
r = ctx->request;
if (r == NULL) {
return p;
}
len -= p - buf;
buf = p;
if (ctx->request->server_name.data) {
p = ngx_snprintf(p, len, ", host: %V", &ctx->request->server_name);
if (r->server_name.data) {
p = ngx_snprintf(buf, len, ", server: %V", &r->server_name);
len -= p - buf;
buf = p;
}
p = ngx_snprintf(p, len, ", URL: \"%V\"", &ctx->request->unparsed_uri);
if (r->unparsed_uri.data) {
p = ngx_snprintf(buf, len, ", URL: \"%V\"", &r->unparsed_uri);
len -= p - buf;
buf = p;
if (ctx->request->headers_in.referer == NULL) {
return p;
} else {
if (r->request_line.data == NULL && r->request_start) {
for (p = r->request_start; p < r->header_in->last; p++) {
if (*p == CR || *p == LF) {
break;
}
}
r->request_line.len = p - r->request_start;
r->request_line.data = r->request_start;
}
if (r->request_line.len) {
p = ngx_snprintf(buf, len, ", request: \"%V\"", &r->request_line);
len -= p - buf;
buf = p;
}
}
len -= p - buf;
return ngx_snprintf(p, len, ", referrer: \"%V\"",
&ctx->request->headers_in.referer->value);
return ngx_http_log_error_info(r, buf, len);
}
u_char *
ngx_http_log_error_info(ngx_http_request_t *r, u_char *buf, size_t len)
{
u_char *p;
if (r->headers_in.host) {
p = ngx_snprintf(buf, len, ", host: \"%V\"",
&r->headers_in.host->value);
len -= p - buf;
buf = p;
}
if (r->headers_in.referer) {
p = ngx_snprintf(buf, len, ", referrer: \"%V\"",
&r->headers_in.referer->value);
buf = p;
}
return buf;
}

View File

@ -32,18 +32,10 @@
#define NGX_HTTP_CLIENT_ERROR 10
#define NGX_HTTP_PARSE_INVALID_METHOD 10
#define NGX_HTTP_PARSE_INVALID_REQUEST 11
#define NGX_HTTP_PARSE_TOO_LONG_URI 12
#define NGX_HTTP_PARSE_INVALID_09_METHOD 13
#define NGX_HTTP_PARSE_INVALID_09_METHOD 12
#define NGX_HTTP_PARSE_HEADER_ERROR 14
#define NGX_HTTP_PARSE_INVALID_HEADER 14
#define NGX_HTTP_PARSE_TOO_LONG_HEADER 15
#define NGX_HTTP_PARSE_NO_HOST_HEADER 16
#define NGX_HTTP_PARSE_INVALID_CL_HEADER 17
#define NGX_HTTP_PARSE_POST_WO_CL_HEADER 18
#define NGX_HTTP_PARSE_INVALID_HOST 19
#define NGX_HTTP_PARSE_HTTP_TO_HTTPS 20
#define NGX_HTTP_PARSE_HEADER_ERROR 13
#define NGX_HTTP_PARSE_INVALID_HEADER 13
#define NGX_HTTP_OK 200
@ -338,6 +330,7 @@ struct ngx_http_request_s {
/* URI with "\0" or "%00" */
unsigned zero_in_uri:1;
unsigned valid_unparsed_uri:1;
unsigned uri_changed:1;
unsigned uri_changes:4;

View File

@ -1136,7 +1136,6 @@ ngx_http_upstream_log_error(ngx_log_t *log, u_char *buf, size_t len)
{
u_char *p;
ngx_int_t escape;
ngx_str_t uri;
ngx_http_log_ctx_t *ctx;
ngx_http_request_t *r;
ngx_http_upstream_t *u;
@ -1148,7 +1147,7 @@ ngx_http_upstream_log_error(ngx_log_t *log, u_char *buf, size_t len)
peer = &u->peer;
p = ngx_snprintf(buf, len,
" while %s, client: %V, host: %V, URL: \"%V\","
" while %s, client: %V, server: %V, URL: \"%V\","
" upstream: %V%V%s%V",
log->action,
&r->connection->addr_text,
@ -1176,14 +1175,15 @@ ngx_http_upstream_log_error(ngx_log_t *log, u_char *buf, size_t len)
r->uri.len - u->location->len, NGX_ESCAPE_URI);
buf += r->uri.len - u->location->len + escape;
if (r->args.len == 0) {
return buf;
}
len -= r->uri.len - u->location->len + escape;
return ngx_snprintf(buf, len, "?%V", &r->args);
if (r->args.len) {
p = ngx_snprintf(buf, len, "?%V", &r->args);
len -= p - buf;
buf = p;
}
return ngx_http_log_error_info(r, buf, len);
}
p = ngx_palloc(r->pool, r->uri.len - u->location->len + escape);
@ -1194,17 +1194,23 @@ ngx_http_upstream_log_error(ngx_log_t *log, u_char *buf, size_t len)
ngx_escape_uri(p, r->uri.data + u->location->len,
r->uri.len - u->location->len, NGX_ESCAPE_URI);
uri.len = r->uri.len - u->location->len + escape;
uri.data = p;
p = ngx_cpymem(buf, p, r->uri.len - u->location->len + escape);
} else {
uri.len = r->uri.len - u->location->len;
uri.data = r->uri.data + u->location->len;
p = ngx_cpymem(buf, r->uri.data + u->location->len,
r->uri.len - u->location->len);
}
return ngx_snprintf(buf, len, "%V%s%V",
&uri, r->args.len ? "?" : "", &r->args);
len -= p - buf;
buf = p;
if (r->args.len) {
p = ngx_snprintf(buf, len, "?%V", &r->args);
len -= p - buf;
buf = p;
}
return ngx_http_log_error_info(r, buf, len);
}

View File

@ -632,7 +632,14 @@ ngx_master_exit(ngx_cycle_t *cycle)
ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exit");
/*
* we do not destroy cycle->pool here because a signal handler
* that uses cycle->log can be called at this point
*/
#if 0
ngx_destroy_pool(cycle->pool);
#endif
exit(0);
}
@ -718,6 +725,10 @@ ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data)
* we do not destroy cycle->pool here because a signal handler
* that uses cycle->log can be called at this point
*/
#if 0
ngx_destroy_pool(cycle->pool);
#endif
exit(0);
}
@ -736,6 +747,11 @@ ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data)
* we do not destroy cycle->pool here because a signal handler
* that uses cycle->log can be called at this point
*/
#if 0
ngx_destroy_pool(cycle->pool);
#endif
exit(0);
}