mirror of
https://github.com/nginx/nginx.git
synced 2026-08-28 12:45:21 +00:00
nginx-0.3.50-RELEASE import
*) Change: the "proxy_redirect_errors" and "fastcgi_redirect_errors"
directives was renamed to the "proxy_intercept_errors" and
"fastcgi_intercept_errors" directives.
*) Feature: the ngx_http_charset_module supports the recoding from the
single byte encodings to the UTF-8 encoding and back.
*) Feature: the "X-Accel-Charset" response header line is supported in
proxy and FastCGI mode.
*) Bugfix: the "\" escape symbol in the "\"" and "\'" pairs in the SSI
command was removed only if the command also has the "$" symbol.
*) Bugfix: the "<!--" string might be added on some conditions in the
SSI after inclusion.
*) Bugfix: if the "Content-Length: 0" header line was in response, then
in nonbuffered proxying mode the client connection was not closed.
This commit is contained in:
parent
f115ebe9c3
commit
ef809b86c3
29 changed files with 1490 additions and 230 deletions
|
|
@ -8,7 +8,7 @@
|
|||
#define _NGINX_H_INCLUDED_
|
||||
|
||||
|
||||
#define NGINX_VER "nginx/0.3.49"
|
||||
#define NGINX_VER "nginx/0.3.50"
|
||||
|
||||
#define NGINX_VAR "NGINX"
|
||||
#define NGX_OLDPID_EXT ".oldbin"
|
||||
|
|
|
|||
|
|
@ -99,7 +99,6 @@ typedef struct {
|
|||
|
||||
unsigned uri_part:1;
|
||||
unsigned port_only:1;
|
||||
unsigned virtual:1;
|
||||
} ngx_inet_upstream_t;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -750,16 +750,82 @@ ngx_decode_base64(ngx_str_t *dst, ngx_str_t *src)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* ngx_utf_decode() decodes two and more bytes UTF sequences only
|
||||
* the return values:
|
||||
* 0x80 - 0x10ffff valid character
|
||||
* 0x10ffff - 0xfffffffd invalid sequence
|
||||
* 0xfffffffe incomplete sequence
|
||||
* 0xffffffff error
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
ngx_utf_decode(u_char **p, size_t n)
|
||||
{
|
||||
size_t len;
|
||||
uint32_t u, i, valid;
|
||||
|
||||
u = **p;
|
||||
|
||||
if (u > 0xf0) {
|
||||
|
||||
u &= 0x07;
|
||||
valid = 0xffff;
|
||||
len = 3;
|
||||
|
||||
} else if (u > 0xe0) {
|
||||
|
||||
u &= 0x0f;
|
||||
valid = 0x7ff;
|
||||
len = 2;
|
||||
|
||||
} else if (u > 0xc0) {
|
||||
|
||||
u &= 0x1f;
|
||||
valid = 0x7f;
|
||||
len = 1;
|
||||
|
||||
} else {
|
||||
(*p)++;
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
if (n - 1 < len) {
|
||||
return 0xfffffffe;
|
||||
}
|
||||
|
||||
(*p)++;
|
||||
|
||||
while (len) {
|
||||
i = *(*p)++;
|
||||
|
||||
if (i < 0x80) {
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
u = (u << 6) | (i & 0x3f);
|
||||
|
||||
len--;
|
||||
}
|
||||
|
||||
if (u > valid) {
|
||||
return u;
|
||||
}
|
||||
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
|
||||
size_t
|
||||
ngx_utf_length(ngx_str_t *utf)
|
||||
ngx_utf_length(u_char *p, size_t n)
|
||||
{
|
||||
u_char c;
|
||||
size_t len;
|
||||
ngx_uint_t i;
|
||||
|
||||
for (len = 0, i = 0; i < utf->len; len++, i++) {
|
||||
for (len = 0, i = 0; i < n; len++, i++) {
|
||||
|
||||
c = utf->data[i];
|
||||
c = p[i];
|
||||
|
||||
if (c < 0x80) {
|
||||
continue;
|
||||
|
|
@ -775,7 +841,7 @@ ngx_utf_length(ngx_str_t *utf)
|
|||
|
||||
/* invalid utf */
|
||||
|
||||
return utf->len;
|
||||
return n;
|
||||
}
|
||||
|
||||
return len;
|
||||
|
|
|
|||
|
|
@ -146,7 +146,8 @@ void ngx_md5_text(u_char *text, u_char *md5);
|
|||
void ngx_encode_base64(ngx_str_t *dst, ngx_str_t *src);
|
||||
ngx_int_t ngx_decode_base64(ngx_str_t *dst, ngx_str_t *src);
|
||||
|
||||
size_t ngx_utf_length(ngx_str_t *utf);
|
||||
uint32_t ngx_utf_decode(u_char **p, size_t n);
|
||||
size_t ngx_utf_length(u_char *p, size_t n);
|
||||
u_char * ngx_utf_cpystrn(u_char *dst, u_char *src, size_t n);
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -319,7 +319,7 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
|
|||
NGX_ESCAPE_HTML);
|
||||
|
||||
if (r->utf8) {
|
||||
entry->utf_len = ngx_utf_length(&entry->name);
|
||||
entry->utf_len = ngx_utf_length(entry->name.data, entry->name.len);
|
||||
} else {
|
||||
entry->utf_len = len;
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -156,6 +156,10 @@ static ngx_conf_deprecated_t ngx_conf_deprecated_fastcgi_header_buffer_size = {
|
|||
ngx_conf_deprecated, "fastcgi_header_buffer_size", "fastcgi_buffer_size"
|
||||
};
|
||||
|
||||
static ngx_conf_deprecated_t ngx_conf_deprecated_fastcgi_redirect_errors = {
|
||||
ngx_conf_deprecated, "fastcgi_redirect_errors", "fastcgi_intercept_errors"
|
||||
};
|
||||
|
||||
|
||||
static ngx_conf_bitmask_t ngx_http_fastcgi_next_upstream_masks[] = {
|
||||
{ ngx_string("error"), NGX_HTTP_UPSTREAM_FT_ERROR },
|
||||
|
|
@ -240,12 +244,19 @@ static ngx_command_t ngx_http_fastcgi_commands[] = {
|
|||
offsetof(ngx_http_fastcgi_loc_conf_t, upstream.pass_request_body),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("fastcgi_intercept_errors"),
|
||||
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_fastcgi_loc_conf_t, upstream.intercept_errors),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("fastcgi_redirect_errors"),
|
||||
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_fastcgi_loc_conf_t, upstream.redirect_errors),
|
||||
NULL },
|
||||
offsetof(ngx_http_fastcgi_loc_conf_t, upstream.intercept_errors),
|
||||
&ngx_conf_deprecated_fastcgi_redirect_errors },
|
||||
|
||||
{ ngx_string("fastcgi_read_timeout"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
||||
|
|
@ -1534,7 +1545,7 @@ ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf)
|
|||
conf->upstream.pass_request_headers = NGX_CONF_UNSET;
|
||||
conf->upstream.pass_request_body = NGX_CONF_UNSET;
|
||||
|
||||
conf->upstream.redirect_errors = NGX_CONF_UNSET;
|
||||
conf->upstream.intercept_errors = NGX_CONF_UNSET;
|
||||
|
||||
/* "fastcgi_cyclic_temp_file" is disabled */
|
||||
conf->upstream.cyclic_temp_file = 0;
|
||||
|
|
@ -1708,8 +1719,8 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
ngx_conf_merge_value(conf->upstream.pass_request_body,
|
||||
prev->upstream.pass_request_body, 1);
|
||||
|
||||
ngx_conf_merge_value(conf->upstream.redirect_errors,
|
||||
prev->upstream.redirect_errors, 0);
|
||||
ngx_conf_merge_value(conf->upstream.intercept_errors,
|
||||
prev->upstream.intercept_errors, 0);
|
||||
|
||||
|
||||
ngx_conf_merge_str_value(conf->index, prev->index, "");
|
||||
|
|
|
|||
|
|
@ -16,17 +16,20 @@ typedef struct {
|
|||
ngx_array_t *ops; /* array of ngx_http_log_op_t */
|
||||
} ngx_http_log_fmt_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_array_t formats; /* array of ngx_http_log_fmt_t */
|
||||
ngx_uint_t combined_used; /* unsigned combined_used:1 */
|
||||
} ngx_http_log_main_conf_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_open_file_t *file;
|
||||
time_t disk_full_time;
|
||||
ngx_array_t *ops; /* array of ngx_http_log_op_t */
|
||||
} ngx_http_log_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_array_t *logs; /* array of ngx_http_log_t */
|
||||
ngx_uint_t off; /* unsigned off:1 */
|
||||
|
|
|
|||
|
|
@ -524,7 +524,7 @@ ngx_http_memcached_create_loc_conf(ngx_conf_t *cf)
|
|||
conf->upstream.busy_buffers_size = 0;
|
||||
conf->upstream.max_temp_file_size = 0;
|
||||
conf->upstream.temp_file_write_size = 0;
|
||||
conf->upstream.redirect_errors = 1;
|
||||
conf->upstream.intercept_errors = 1;
|
||||
conf->upstream.redirect_404 = 1;
|
||||
conf->upstream.pass_request_headers = 0;
|
||||
conf->upstream.pass_request_body = 0;
|
||||
|
|
|
|||
|
|
@ -115,6 +115,10 @@ static ngx_conf_deprecated_t ngx_conf_deprecated_proxy_header_buffer_size = {
|
|||
ngx_conf_deprecated, "proxy_header_buffer_size", "proxy_buffer_size"
|
||||
};
|
||||
|
||||
static ngx_conf_deprecated_t ngx_conf_deprecated_proxy_redirect_errors = {
|
||||
ngx_conf_deprecated, "proxy_redirect_errors", "proxy_intercept_errors"
|
||||
};
|
||||
|
||||
|
||||
static ngx_conf_bitmask_t ngx_http_proxy_next_upstream_masks[] = {
|
||||
{ ngx_string("error"), NGX_HTTP_UPSTREAM_FT_ERROR },
|
||||
|
|
@ -178,12 +182,19 @@ static ngx_command_t ngx_http_proxy_commands[] = {
|
|||
offsetof(ngx_http_proxy_loc_conf_t, upstream.send_lowat),
|
||||
&ngx_http_proxy_lowat_post },
|
||||
|
||||
{ ngx_string("proxy_intercept_errors"),
|
||||
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.intercept_errors),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("proxy_redirect_errors"),
|
||||
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.redirect_errors),
|
||||
NULL },
|
||||
offsetof(ngx_http_proxy_loc_conf_t, upstream.intercept_errors),
|
||||
&ngx_conf_deprecated_proxy_redirect_errors },
|
||||
|
||||
{ ngx_string("proxy_set_header"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
|
||||
|
|
@ -1486,7 +1497,7 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
|
|||
conf->upstream.pass_request_headers = NGX_CONF_UNSET;
|
||||
conf->upstream.pass_request_body = NGX_CONF_UNSET;
|
||||
|
||||
conf->upstream.redirect_errors = NGX_CONF_UNSET;
|
||||
conf->upstream.intercept_errors = NGX_CONF_UNSET;
|
||||
|
||||
/* "proxy_cyclic_temp_file" is disabled */
|
||||
conf->upstream.cyclic_temp_file = 0;
|
||||
|
|
@ -1670,8 +1681,8 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
ngx_conf_merge_value(conf->upstream.pass_request_body,
|
||||
prev->upstream.pass_request_body, 1);
|
||||
|
||||
ngx_conf_merge_value(conf->upstream.redirect_errors,
|
||||
prev->upstream.redirect_errors, 0);
|
||||
ngx_conf_merge_value(conf->upstream.intercept_errors,
|
||||
prev->upstream.intercept_errors, 0);
|
||||
|
||||
ngx_conf_merge_value(conf->redirect, prev->redirect, 1);
|
||||
|
||||
|
|
|
|||
|
|
@ -145,7 +145,6 @@ ngx_http_range_header_filter(ngx_http_request_t *r)
|
|||
|| r->headers_in.range->value.len < 7
|
||||
|| ngx_strncasecmp(r->headers_in.range->value.data, "bytes=", 6) != 0)
|
||||
{
|
||||
|
||||
r->headers_out.accept_ranges = ngx_list_push(&r->headers_out.headers);
|
||||
if (r->headers_out.accept_ranges == NULL) {
|
||||
return NGX_ERROR;
|
||||
|
|
|
|||
|
|
@ -788,7 +788,8 @@ ngx_http_ssi_output(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx)
|
|||
|
||||
while (ctx->busy) {
|
||||
|
||||
b = ctx->busy->buf;
|
||||
cl = ctx->busy;
|
||||
b = cl->buf;
|
||||
|
||||
if (ngx_buf_size(b) != 0) {
|
||||
break;
|
||||
|
|
@ -804,7 +805,6 @@ ngx_http_ssi_output(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx)
|
|||
b->shadow->pos = b->shadow->last;
|
||||
}
|
||||
|
||||
cl = ctx->busy;
|
||||
ctx->busy = cl->next;
|
||||
|
||||
if (ngx_buf_in_memory(b) || b->in_file) {
|
||||
|
|
@ -942,9 +942,7 @@ ngx_http_ssi_parse(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx)
|
|||
case ssi_sharp_state:
|
||||
switch (ch) {
|
||||
case '#':
|
||||
if (ctx->copy_start) {
|
||||
ctx->saved = 0;
|
||||
}
|
||||
ctx->saved = 0;
|
||||
looked = 0;
|
||||
state = ssi_precommand_state;
|
||||
break;
|
||||
|
|
@ -1417,11 +1415,11 @@ ngx_http_ssi_evaluate_string(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
|||
|
||||
if (n == 0) {
|
||||
|
||||
if (!(flags & NGX_HTTP_SSI_ADD_PREFIX)) {
|
||||
return NGX_OK;
|
||||
}
|
||||
data = text->data;
|
||||
p = data;
|
||||
|
||||
if ((flags & NGX_HTTP_SSI_ADD_PREFIX) && text->data[0] != '/') {
|
||||
|
||||
if (text->data[0] != '/') {
|
||||
for (prefix = r->uri.len; prefix; prefix--) {
|
||||
if (r->uri.data[prefix - 1] == '/') {
|
||||
break;
|
||||
|
|
@ -1437,13 +1435,35 @@ ngx_http_ssi_evaluate_string(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
|||
}
|
||||
|
||||
p = ngx_copy(data, r->uri.data, prefix);
|
||||
ngx_memcpy(p, text->data, text->len);
|
||||
|
||||
text->len = len;
|
||||
text->data = data;
|
||||
}
|
||||
}
|
||||
|
||||
quoted = 0;
|
||||
|
||||
for (i = 0 ; i < text->len; i++) {
|
||||
ch = text->data[i];
|
||||
|
||||
if (!quoted) {
|
||||
|
||||
if (ch == '\\') {
|
||||
quoted = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
} else {
|
||||
quoted = 0;
|
||||
|
||||
if (ch != '\\' && ch != '\'' && ch != '"' && ch != '$') {
|
||||
*p++ = '\\';
|
||||
}
|
||||
}
|
||||
|
||||
*p++ = ch;
|
||||
}
|
||||
|
||||
text->len = p - data;
|
||||
text->data = data;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
|
@ -2140,6 +2160,7 @@ ngx_http_ssi_date_gmt_local_variable(ngx_http_request_t *r,
|
|||
|
||||
v->len = ngx_sprintf(v->data, "%T", tp->sec + (gmt ? 0 : tp->gmtoff))
|
||||
- v->data;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -594,10 +594,6 @@ ngx_http_userid_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
|
|||
ngx_http_userid_ctx_t *ctx;
|
||||
ngx_http_userid_conf_t *conf;
|
||||
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->not_found = 0;
|
||||
|
||||
ctx = ngx_http_get_module_ctx(r, ngx_http_userid_filter_module);
|
||||
|
||||
uid = (uint32_t *) ((char *) ctx + data);
|
||||
|
|
@ -615,6 +611,10 @@ ngx_http_userid_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->not_found = 0;
|
||||
|
||||
ngx_sprintf(v->data, "%V=%08XD%08XD%08XD%08XD",
|
||||
&conf->name, uid[0], uid[1], uid[2], uid[3]);
|
||||
|
||||
|
|
|
|||
|
|
@ -519,6 +519,7 @@ static void
|
|||
ngx_http_core_run_phases(ngx_http_request_t *r)
|
||||
{
|
||||
ngx_int_t rc;
|
||||
ngx_str_t path;
|
||||
ngx_http_handler_pt *h;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
ngx_http_core_main_conf_t *cmcf;
|
||||
|
|
@ -642,11 +643,10 @@ ngx_http_core_run_phases(ngx_http_request_t *r)
|
|||
|
||||
if (r->uri.data[r->uri.len - 1] == '/' && !r->zero_in_uri) {
|
||||
|
||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"directory index of \"%V%V\" is forbidden",
|
||||
&clcf->root, &r->uri);
|
||||
if (ngx_http_map_uri_to_path(r, &path, 0) != NULL) {
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"directory index of \"%V\" is forbidden", &path);
|
||||
}
|
||||
|
||||
ngx_http_finalize_request(r, NGX_HTTP_FORBIDDEN);
|
||||
return;
|
||||
|
|
@ -960,11 +960,14 @@ ngx_http_set_content_type(ngx_http_request_t *r)
|
|||
r->exten.data, r->exten.len);
|
||||
|
||||
if (type) {
|
||||
r->headers_out.content_type_len = type->len;
|
||||
r->headers_out.content_type = *type;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
}
|
||||
|
||||
r->headers_out.content_type_len = clcf->default_type.len;
|
||||
r->headers_out.content_type = clcf->default_type;
|
||||
|
||||
return NGX_OK;
|
||||
|
|
@ -1156,6 +1159,14 @@ ngx_http_subrequest(ngx_http_request_t *r,
|
|||
ngx_http_core_srv_conf_t *cscf;
|
||||
ngx_http_postponed_request_t *pr, *p;
|
||||
|
||||
r->main->subrequests--;
|
||||
|
||||
if (r->main->subrequests == 0) {
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"subrequests cycle");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
sr = ngx_pcalloc(r->pool, sizeof(ngx_http_request_t));
|
||||
if (sr == NULL) {
|
||||
return NGX_ERROR;
|
||||
|
|
|
|||
|
|
@ -247,7 +247,9 @@ ngx_http_header_filter(ngx_http_request_t *r)
|
|||
len += sizeof("Content-Type: ") - 1
|
||||
+ r->headers_out.content_type.len + 2;
|
||||
|
||||
if (r->headers_out.charset.len) {
|
||||
if (r->headers_out.content_type_len == r->headers_out.content_type.len
|
||||
&& r->headers_out.charset.len)
|
||||
{
|
||||
len += sizeof("; charset=") - 1 + r->headers_out.charset.len;
|
||||
}
|
||||
}
|
||||
|
|
@ -380,7 +382,9 @@ ngx_http_header_filter(ngx_http_request_t *r)
|
|||
b->last = ngx_copy(b->last, r->headers_out.content_type.data,
|
||||
r->headers_out.content_type.len);
|
||||
|
||||
if (r->headers_out.charset.len) {
|
||||
if (r->headers_out.content_type_len == r->headers_out.content_type.len
|
||||
&& r->headers_out.charset.len)
|
||||
{
|
||||
b->last = ngx_cpymem(b->last, "; charset=",
|
||||
sizeof("; charset=") - 1);
|
||||
b->last = ngx_copy(b->last, r->headers_out.charset.data,
|
||||
|
|
|
|||
|
|
@ -337,13 +337,13 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
|
|||
r->quoted_uri = 1;
|
||||
state = sw_uri;
|
||||
break;
|
||||
case '+':
|
||||
r->plus_in_uri = 1;
|
||||
break;
|
||||
case '?':
|
||||
r->args_start = p + 1;
|
||||
state = sw_uri;
|
||||
break;
|
||||
case '+':
|
||||
r->plus_in_uri = 1;
|
||||
break;
|
||||
case '\0':
|
||||
r->zero_in_uri = 1;
|
||||
break;
|
||||
|
|
@ -366,9 +366,6 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
|
|||
r->uri_end = p;
|
||||
r->http_minor = 9;
|
||||
goto done;
|
||||
case '+':
|
||||
r->plus_in_uri = 1;
|
||||
break;
|
||||
case '\0':
|
||||
r->zero_in_uri = 1;
|
||||
break;
|
||||
|
|
@ -828,6 +825,8 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r)
|
|||
r->uri_ext = u + 1;
|
||||
*u++ = ch;
|
||||
break;
|
||||
case '+':
|
||||
r->plus_in_uri = 1;
|
||||
default:
|
||||
*u++ = ch;
|
||||
break;
|
||||
|
|
@ -853,6 +852,8 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r)
|
|||
case '?':
|
||||
r->args_start = p;
|
||||
goto done;
|
||||
case '+':
|
||||
r->plus_in_uri = 1;
|
||||
default:
|
||||
state = sw_usual;
|
||||
*u++ = ch;
|
||||
|
|
@ -881,6 +882,8 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r)
|
|||
case '?':
|
||||
r->args_start = p;
|
||||
goto done;
|
||||
case '+':
|
||||
r->plus_in_uri = 1;
|
||||
default:
|
||||
state = sw_usual;
|
||||
*u++ = ch;
|
||||
|
|
@ -917,6 +920,8 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r)
|
|||
*u++ = ch;
|
||||
break;
|
||||
#endif
|
||||
case '+':
|
||||
r->plus_in_uri = 1;
|
||||
default:
|
||||
state = sw_usual;
|
||||
*u++ = ch;
|
||||
|
|
@ -952,6 +957,8 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r)
|
|||
case '?':
|
||||
r->args_start = p;
|
||||
goto done;
|
||||
case '+':
|
||||
r->plus_in_uri = 1;
|
||||
default:
|
||||
state = sw_usual;
|
||||
*u++ = ch;
|
||||
|
|
@ -992,8 +999,6 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r)
|
|||
|
||||
if (ch == '\0') {
|
||||
r->zero_in_uri = 1;
|
||||
*u++ = ch;
|
||||
ch = *p++;
|
||||
}
|
||||
|
||||
state = quoted_state;
|
||||
|
|
@ -1003,10 +1008,15 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r)
|
|||
c = (u_char) (ch | 0x20);
|
||||
if (c >= 'a' && c <= 'f') {
|
||||
ch = (u_char) ((decoded << 4) + c - 'a' + 10);
|
||||
|
||||
if (ch == '?') {
|
||||
*u++ = ch;
|
||||
ch = *p++;
|
||||
|
||||
} else if (ch == '+') {
|
||||
r->plus_in_uri = 1;
|
||||
}
|
||||
|
||||
state = quoted_state;
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -667,6 +667,7 @@ ngx_http_process_request_line(ngx_event_t *rev)
|
|||
r->read_event_handler = ngx_http_block_read;
|
||||
|
||||
r->uri_changes = NGX_HTTP_MAX_URI_CHANGES + 1;
|
||||
r->subrequests = NGX_HTTP_MAX_SUBREQUESTS + 1;
|
||||
|
||||
ngx_http_handler(r);
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
|
||||
#define NGX_HTTP_MAX_URI_CHANGES 10
|
||||
#define NGX_HTTP_MAX_SUBREQUESTS 50
|
||||
|
||||
/* must be 2^n */
|
||||
#define NGX_HTTP_LC_HEADER_LEN 32
|
||||
|
|
@ -228,10 +229,13 @@ typedef struct {
|
|||
ngx_table_elt_t *expires;
|
||||
ngx_table_elt_t *etag;
|
||||
|
||||
ngx_str_t *override_charset;
|
||||
|
||||
size_t content_type_len;
|
||||
ngx_str_t content_type;
|
||||
ngx_str_t charset;
|
||||
ngx_array_t ranges;
|
||||
|
||||
ngx_array_t ranges;
|
||||
ngx_array_t cache_control;
|
||||
|
||||
off_t content_length_n;
|
||||
|
|
@ -446,6 +450,8 @@ struct ngx_http_request_s {
|
|||
unsigned stat_writing:1;
|
||||
#endif
|
||||
|
||||
unsigned subrequests:8;
|
||||
|
||||
/* used to parse HTTP headers */
|
||||
ngx_uint_t state;
|
||||
u_char *uri_start;
|
||||
|
|
|
|||
|
|
@ -49,6 +49,8 @@ static ngx_int_t ngx_http_upstream_process_limit_rate(ngx_http_request_t *r,
|
|||
ngx_table_elt_t *h, ngx_uint_t offset);
|
||||
static ngx_int_t ngx_http_upstream_process_buffering(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, ngx_uint_t offset);
|
||||
static ngx_int_t ngx_http_upstream_process_charset(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, ngx_uint_t offset);
|
||||
static ngx_int_t ngx_http_upstream_copy_header_line(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, ngx_uint_t offset);
|
||||
static ngx_int_t
|
||||
|
|
@ -199,6 +201,10 @@ ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = {
|
|||
ngx_http_upstream_process_buffering, 0,
|
||||
ngx_http_upstream_ignore_header_line, 0, 0 },
|
||||
|
||||
{ ngx_string("X-Accel-Charset"),
|
||||
ngx_http_upstream_process_charset, 0,
|
||||
ngx_http_upstream_ignore_header_line, 0, 0 },
|
||||
|
||||
#if (NGX_HTTP_GZIP)
|
||||
{ ngx_string("Content-Encoding"),
|
||||
ngx_http_upstream_process_header_line,
|
||||
|
|
@ -1080,7 +1086,7 @@ ngx_http_upstream_process_header(ngx_event_t *rev)
|
|||
|
||||
|
||||
if (u->headers_in.status_n >= NGX_HTTP_BAD_REQUEST
|
||||
&& u->conf->redirect_errors
|
||||
&& u->conf->intercept_errors
|
||||
&& r->err_ctx == NULL)
|
||||
{
|
||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||
|
|
@ -1515,7 +1521,7 @@ ngx_http_upstream_process_non_buffered_body(ngx_event_t *ev)
|
|||
|
||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||
|
||||
do_write = ev->write;
|
||||
do_write = ev->write || u->length == 0;
|
||||
|
||||
for ( ;; ) {
|
||||
|
||||
|
|
@ -1559,6 +1565,7 @@ ngx_http_upstream_process_non_buffered_body(ngx_event_t *ev)
|
|||
}
|
||||
|
||||
if (size && u->peer.connection->read->ready) {
|
||||
|
||||
n = u->peer.connection->recv(u->peer.connection, b->last, size);
|
||||
|
||||
if (n == NGX_AGAIN) {
|
||||
|
|
@ -2125,6 +2132,16 @@ ngx_http_upstream_process_buffering(ngx_http_request_t *r, ngx_table_elt_t *h,
|
|||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_upstream_process_charset(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||
ngx_uint_t offset)
|
||||
{
|
||||
r->headers_out.override_charset = &h->value;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_upstream_copy_header_line(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||
ngx_uint_t offset)
|
||||
|
|
@ -2184,8 +2201,33 @@ static ngx_int_t
|
|||
ngx_http_upstream_copy_content_type(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||
ngx_uint_t offset)
|
||||
{
|
||||
u_char *p, *last;
|
||||
|
||||
r->headers_out.content_type_len = h->value.len;
|
||||
r->headers_out.content_type = h->value;
|
||||
|
||||
for (p = h->value.data; *p; p++) {
|
||||
|
||||
if (*p != ';') {
|
||||
continue;
|
||||
}
|
||||
|
||||
last = p;
|
||||
|
||||
while (*++p == ' ') { /* void */ }
|
||||
|
||||
if (ngx_strncasecmp(p, "charset=", 8) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
p += 8;
|
||||
|
||||
r->headers_out.content_type_len = last - h->value.data;
|
||||
|
||||
r->headers_out.charset.len = h->value.data + h->value.len - p;
|
||||
r->headers_out.charset.data = p;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ typedef struct {
|
|||
ngx_flag_t pass_request_body;
|
||||
|
||||
ngx_flag_t ignore_client_abort;
|
||||
ngx_flag_t redirect_errors;
|
||||
ngx_flag_t intercept_errors;
|
||||
ngx_flag_t cyclic_temp_file;
|
||||
|
||||
ngx_path_t *temp_path;
|
||||
|
|
|
|||
|
|
@ -354,6 +354,9 @@ ngx_http_get_indexed_variable(ngx_http_request_t *r, ngx_uint_t index)
|
|||
return &r->variables[index];
|
||||
}
|
||||
|
||||
r->variables[index].valid = 0;
|
||||
r->variables[index].not_found = 1;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue