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:
Igor Sysoev 2006-06-28 16:00:26 +00:00
parent f115ebe9c3
commit ef809b86c3
29 changed files with 1490 additions and 230 deletions

View file

@ -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"

View file

@ -99,7 +99,6 @@ typedef struct {
unsigned uri_part:1;
unsigned port_only:1;
unsigned virtual:1;
} ngx_inet_upstream_t;

View file

@ -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;

View file

@ -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);

View file

@ -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

View file

@ -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, "");

View file

@ -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 */

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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;
}

View file

@ -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]);

View file

@ -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;

View file

@ -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,

View file

@ -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;
}

View file

@ -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);

View file

@ -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;

View file

@ -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;
}

View file

@ -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;

View file

@ -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;
}