diff options
author | Igor Sysoev <igor@sysoev.ru> | 2005-05-19 17:25:22 +0400 |
---|---|---|
committer | Igor Sysoev <igor@sysoev.ru> | 2005-05-19 17:25:22 +0400 |
commit | e31e90b3e10ca2afafccae9a57910133d93b2d37 (patch) | |
tree | 7177a8f48a555733b170bfcad4e9e7072ea8c027 /src | |
parent | b1a641cafa2ef042035155f68e5f571303853dfc (diff) |
nginx-0.1.32-RELEASE importrelease-0.1.32
*) Bugfix: the arguments were omitted in the redirects, issued by the
"rewrite" directive; the bug had appeared in 0.1.29.
*) Feature: the "if" directive supports the captures in regular
expressions.
*) Feature: the "set" directive supports the variables and the captures
of regular expressions.
*) Feature: the "X-Accel-Redirect" response header line is supported in
proxy and FastCGI mode.
Diffstat (limited to 'src')
-rw-r--r-- | src/core/nginx.h | 2 | ||||
-rw-r--r-- | src/core/ngx_inet.c | 2 | ||||
-rw-r--r-- | src/core/ngx_log.h | 1 | ||||
-rw-r--r-- | src/core/ngx_string.h | 6 | ||||
-rw-r--r-- | src/event/ngx_event_timer.c | 2 | ||||
-rw-r--r-- | src/http/modules/ngx_http_fastcgi_module.c | 2 | ||||
-rw-r--r-- | src/http/modules/ngx_http_proxy_module.c | 4 | ||||
-rw-r--r-- | src/http/modules/ngx_http_rewrite_module.c | 95 | ||||
-rw-r--r-- | src/http/ngx_http_script.c | 102 | ||||
-rw-r--r-- | src/http/ngx_http_script.h | 10 | ||||
-rw-r--r-- | src/http/ngx_http_upstream.c | 104 | ||||
-rw-r--r-- | src/http/ngx_http_upstream.h | 2 | ||||
-rw-r--r-- | src/http/ngx_http_variables.c | 61 | ||||
-rw-r--r-- | src/os/unix/ngx_os.h | 2 | ||||
-rw-r--r-- | src/os/unix/ngx_posix_config.h | 4 | ||||
-rw-r--r-- | src/os/unix/ngx_process.c | 18 | ||||
-rw-r--r-- | src/os/unix/ngx_setproctitle.h | 20 |
17 files changed, 334 insertions, 103 deletions
diff --git a/src/core/nginx.h b/src/core/nginx.h index 44c870bed..d1a5693b6 100644 --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -8,7 +8,7 @@ #define _NGINX_H_INCLUDED_ -#define NGINX_VER "nginx/0.1.31" +#define NGINX_VER "nginx/0.1.32" #define NGINX_VAR "NGINX" #define NGX_NEWPID_EXT ".newbin" diff --git a/src/core/ngx_inet.c b/src/core/ngx_inet.c index 1ae7829fa..e7bdc410d 100644 --- a/src/core/ngx_inet.c +++ b/src/core/ngx_inet.c @@ -419,7 +419,7 @@ ngx_inet_parse_host_port(ngx_inet_upstream_t *u) u->host.data = url->data; u->host_header = *url; - for (/* void */; i < url->len; i++) { + for ( /* void */ ; i < url->len; i++) { if (url->data[i] == ':') { u->port_text.data = &url->data[i] + 1; diff --git a/src/core/ngx_log.h b/src/core/ngx_log.h index 5952b5243..df0d52517 100644 --- a/src/core/ngx_log.h +++ b/src/core/ngx_log.h @@ -130,6 +130,7 @@ void ngx_cdecl ngx_log_debug_core(ngx_log_t *log, ngx_err_t err, #define ngx_log_debug7 ngx_log_debug #define ngx_log_debug8 ngx_log_debug + #else /* NO VARIADIC MACROS */ #define ngx_log_debug0(level, log, err, fmt) \ diff --git a/src/core/ngx_string.h b/src/core/ngx_string.h index 24a237903..c72a776dc 100644 --- a/src/core/ngx_string.h +++ b/src/core/ngx_string.h @@ -59,12 +59,12 @@ typedef struct { * while ZeroMemory() and bzero() are the calls. * icc may also inline several mov's of a zeroed register for small blocks. */ -#define ngx_memzero(buf, n) memset(buf, 0, n) -#define ngx_memset(buf, c, n) memset(buf, c, n) +#define ngx_memzero(buf, n) (void) memset(buf, 0, n) +#define ngx_memset(buf, c, n) (void) memset(buf, c, n) /* msvc and icc compile memcpy() to the inline "rep movs" */ -#define ngx_memcpy(dst, src, n) memcpy(dst, src, n) +#define ngx_memcpy(dst, src, n) (void) memcpy(dst, src, n) #define ngx_cpymem(dst, src, n) ((u_char *) memcpy(dst, src, n)) + (n) diff --git a/src/event/ngx_event_timer.c b/src/event/ngx_event_timer.c index fdec446c4..53bbc5f09 100644 --- a/src/event/ngx_event_timer.c +++ b/src/event/ngx_event_timer.c @@ -121,7 +121,7 @@ ngx_event_expire_timers(ngx_msec_t timer) ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, "event timer del: %d: %i", - ngx_event_ident(ev->data), ev->rbtree_key); + ngx_event_ident(ev->data), ev->rbtree_key); ngx_rbtree_delete((ngx_rbtree_t **) &ngx_event_timer_rbtree, &ngx_event_timer_sentinel, diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c index cf9d008a5..0e74528d7 100644 --- a/src/http/modules/ngx_http_fastcgi_module.c +++ b/src/http/modules/ngx_http_fastcgi_module.c @@ -33,7 +33,7 @@ typedef enum { ngx_http_fastcgi_st_padding_length, ngx_http_fastcgi_st_reserved, ngx_http_fastcgi_st_data, - ngx_http_fastcgi_st_padding, + ngx_http_fastcgi_st_padding } ngx_http_fastcgi_state_e; diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c index 5504610e6..a24be2444 100644 --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -542,7 +542,9 @@ ngx_http_proxy_create_request(ngx_http_request_t *r) while (*(uintptr_t *) le.ip) { lcode = *(ngx_http_script_len_code_pt *) le.ip; - lcode(&le); + + /* skip the header line name length */ + (void) lcode(&le); if (*(ngx_http_script_len_code_pt *) le.ip) { diff --git a/src/http/modules/ngx_http_rewrite_module.c b/src/http/modules/ngx_http_rewrite_module.c index 2dc7a7fff..47ff8c536 100644 --- a/src/http/modules/ngx_http_rewrite_module.c +++ b/src/http/modules/ngx_http_rewrite_module.c @@ -16,16 +16,10 @@ typedef struct { typedef struct { - ngx_str_t *name; - ngx_http_variable_value_t *value; -} ngx_http_rewrite_variable_t; - - -typedef struct { ngx_array_t *codes; /* uintptr_t */ ngx_array_t *referers; /* ngx_http_rewrite_referer_t */ - ngx_uint_t max_captures; + ngx_uint_t captures; ngx_uint_t stack_size; ngx_flag_t log; @@ -159,8 +153,8 @@ ngx_http_rewrite_handler(ngx_http_request_t *r) return NGX_HTTP_INTERNAL_SERVER_ERROR; } - if (cf->max_captures) { - e->captures = ngx_palloc(r->pool, cf->max_captures * sizeof(int)); + if (cf->captures) { + e->captures = ngx_palloc(r->pool, cf->captures * sizeof(int)); if (e->captures == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } @@ -542,10 +536,10 @@ ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) if (regex->ncaptures) { regex->ncaptures = (regex->ncaptures + 1) * 3; - } - if (lcf->max_captures < regex->ncaptures) { - lcf->max_captures = regex->ncaptures; + if (lcf->captures < regex->ncaptures) { + lcf->captures = regex->ncaptures; + } } regex_end = ngx_http_script_add_code(lcf->codes, @@ -735,7 +729,7 @@ static char * ngx_http_rewrite_if_condition(ngx_conf_t *cf, ngx_http_rewrite_loc_conf_t *lcf) { ngx_str_t *value, err; - ngx_uint_t cur, last; + ngx_uint_t cur, last, n; ngx_http_script_regex_code_t *regex; u_char errstr[NGX_MAX_CONF_ERRSTR]; @@ -823,6 +817,16 @@ ngx_http_rewrite_if_condition(ngx_conf_t *cf, ngx_http_rewrite_loc_conf_t *lcf) regex->test = 1; regex->name = value[last]; + n = ngx_regex_capture_count(regex->regex); + + if (n) { + regex->ncaptures = (n + 1) * 3; + + if (lcf->captures < regex->ncaptures) { + lcf->captures = regex->ncaptures; + } + } + return NGX_CONF_OK; } @@ -977,11 +981,13 @@ ngx_http_rewrite_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_rewrite_loc_conf_t *lcf = conf; - ngx_int_t n, index; - ngx_str_t *value; - ngx_http_variable_t *v; - ngx_http_script_var_code_t *var; - ngx_http_script_value_code_t *val; + ngx_int_t n, index; + ngx_str_t *value; + ngx_http_variable_t *v; + ngx_http_script_compile_t sc; + ngx_http_script_var_code_t *var; + ngx_http_script_value_code_t *val; + ngx_http_script_complex_value_code_t *complex; value = cf->args->elts; @@ -1007,22 +1013,49 @@ ngx_http_rewrite_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) v->handler = ngx_http_rewrite_var; v->data = index; - val = ngx_http_script_start_code(cf->pool, &lcf->codes, - sizeof(ngx_http_script_value_code_t)); - if (val == NULL) { - return NGX_CONF_ERROR; - } + n = ngx_http_script_variables_count(&value[2]); + + if (n == 0) { + val = ngx_http_script_start_code(cf->pool, &lcf->codes, + sizeof(ngx_http_script_value_code_t)); + if (val == NULL) { + return NGX_CONF_ERROR; + } - n = ngx_atoi(value[2].data, value[2].len); + n = ngx_atoi(value[2].data, value[2].len); - if (n == NGX_ERROR) { - n = 0; - } + if (n == NGX_ERROR) { + n = 0; + } + + val->code = ngx_http_script_value_code; + val->value = (uintptr_t) n; + val->text_len = (uintptr_t) value[2].len; + val->text_data = (uintptr_t) value[2].data; + + } else { + complex = ngx_http_script_start_code(cf->pool, &lcf->codes, + sizeof(ngx_http_script_complex_value_code_t)); + if (complex == NULL) { + return NGX_CONF_ERROR; + } + + complex->code = ngx_http_script_complex_value_code; + complex->lengths = NULL; + + ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); + + sc.cf = cf; + sc.source = &value[2]; + sc.lengths = &complex->lengths; + sc.values = &lcf->codes; + sc.variables = n; + sc.complete_lengths = 1; - val->code = ngx_http_script_value_code; - val->value = (uintptr_t) n; - val->text_len = (uintptr_t) value[2].len; - val->text_data = (uintptr_t) value[2].data; + if (ngx_http_script_compile(&sc) != NGX_OK) { + return NGX_CONF_ERROR; + } + } var = ngx_http_script_start_code(cf->pool, &lcf->codes, sizeof(ngx_http_script_var_code_t)); diff --git a/src/http/ngx_http_script.c b/src/http/ngx_http_script.c index 362807aae..ea1e56b34 100644 --- a/src/http/ngx_http_script.c +++ b/src/http/ngx_http_script.c @@ -405,17 +405,21 @@ ngx_http_script_copy_capture_len_code(ngx_http_script_engine_t *e) e->ip += sizeof(ngx_http_script_copy_capture_code_t); - if ((e->args || e->quote) - && (e->request->quoted_uri || e->request->plus_in_uri)) - { - return e->captures[code->n + 1] - e->captures[code->n] - + ngx_escape_uri(NULL, - &e->line->data[e->captures[code->n]], + if (code->n < e->ncaptures) { + if ((e->args || e->quote) + && (e->request->quoted_uri || e->request->plus_in_uri)) + { + return e->captures[code->n + 1] - e->captures[code->n] + + ngx_escape_uri(NULL, + &e->line.data[e->captures[code->n]], e->captures[code->n + 1] - e->captures[code->n], NGX_ESCAPE_ARGS); - } else { - return e->captures[code->n + 1] - e->captures[code->n]; + } else { + return e->captures[code->n + 1] - e->captures[code->n]; + } } + + return 0; } @@ -428,17 +432,19 @@ ngx_http_script_copy_capture_code(ngx_http_script_engine_t *e) e->ip += sizeof(ngx_http_script_copy_capture_code_t); - if ((e->args || e->quote) - && (e->request->quoted_uri || e->request->plus_in_uri)) - { - e->pos = (u_char *) ngx_escape_uri(e->pos, - &e->line->data[e->captures[code->n]], + if (code->n < e->ncaptures) { + if ((e->args || e->quote) + && (e->request->quoted_uri || e->request->plus_in_uri)) + { + e->pos = (u_char *) ngx_escape_uri(e->pos, + &e->line.data[e->captures[code->n]], e->captures[code->n + 1] - e->captures[code->n], NGX_ESCAPE_ARGS); - } else { - e->pos = ngx_cpymem(e->pos, - &e->line->data[e->captures[code->n]], - e->captures[code->n + 1] - e->captures[code->n]); + } else { + e->pos = ngx_cpymem(e->pos, + &e->line.data[e->captures[code->n]], + e->captures[code->n + 1] - e->captures[code->n]); + } } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, @@ -476,20 +482,23 @@ ngx_http_script_regex_start_code(ngx_http_script_engine_t *e) "http script regex: \"%V\"", &code->name); if (code->uri) { - e->line = &r->uri; + e->line = r->uri; } else { e->sp--; - e->line = &e->sp->text; + e->line = e->sp->text; } - rc = ngx_regex_exec(code->regex, e->line, e->captures, code->ncaptures); + rc = ngx_regex_exec(code->regex, &e->line, e->captures, code->ncaptures); if (rc == NGX_REGEX_NO_MATCHED) { if (e->log) { ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, - "\"%V\" does not match \"%V\"", &code->name, e->line); + "\"%V\" does not match \"%V\"", + &code->name, &e->line); } + e->ncaptures = 0; + if (code->test) { e->sp->value = 0; e->sp->text.len = 0; @@ -507,7 +516,7 @@ ngx_http_script_regex_start_code(ngx_http_script_engine_t *e) if (rc < 0) { ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, ngx_regex_exec_n " failed: %d on \"%V\" using \"%V\"", - rc, e->line, &code->name); + rc, &e->line, &code->name); e->ip = ngx_http_script_exit; e->status = NGX_HTTP_INTERNAL_SERVER_ERROR; @@ -516,9 +525,11 @@ ngx_http_script_regex_start_code(ngx_http_script_engine_t *e) if (e->log) { ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, - "\"%V\" matches \"%V\"", &code->name, e->line); + "\"%V\" matches \"%V\"", &code->name, &e->line); } + e->ncaptures = code->ncaptures; + if (code->test) { e->sp->value = 1; e->sp->text.len = 1; @@ -570,6 +581,7 @@ ngx_http_script_regex_start_code(ngx_http_script_engine_t *e) le.ip = code->lengths->elts; le.request = r; le.captures = e->captures; + le.ncaptures = e->ncaptures; len = 1; /* reserve 1 byte for possible "?" */ @@ -581,7 +593,7 @@ ngx_http_script_regex_start_code(ngx_http_script_engine_t *e) e->buf.len = len; } - if (code->args && code->add_args && r->args.len) { + if (code->add_args && r->args.len) { e->buf.len += r->args.len + 1; } @@ -724,6 +736,48 @@ ngx_http_script_if_code(ngx_http_script_engine_t *e) void +ngx_http_script_complex_value_code(ngx_http_script_engine_t *e) +{ + size_t len; + ngx_http_script_engine_t le; + ngx_http_script_len_code_pt lcode; + ngx_http_script_complex_value_code_t *code; + + code = (ngx_http_script_complex_value_code_t *) e->ip; + + e->ip += sizeof(ngx_http_script_complex_value_code_t); + + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, + "http script complex value"); + + ngx_memzero(&le, sizeof(ngx_http_script_engine_t)); + + le.ip = code->lengths->elts; + le.request = e->request; + le.captures = e->captures; + le.ncaptures = e->ncaptures; + + for (len = 0; *(uintptr_t *) le.ip; len += lcode(&le)) { + lcode = *(ngx_http_script_len_code_pt *) le.ip; + } + + e->buf.len = len; + e->buf.data = ngx_palloc(e->request->pool, len); + if (e->buf.data == NULL) { + e->ip = ngx_http_script_exit; + e->status = NGX_HTTP_INTERNAL_SERVER_ERROR; + return; + } + + e->pos = e->buf.data; + + e->sp->value = 0; + e->sp->text = e->buf; + e->sp++; +} + + +void ngx_http_script_value_code(ngx_http_script_engine_t *e) { ngx_http_script_value_code_t *code; diff --git a/src/http/ngx_http_script.h b/src/http/ngx_http_script.h index 21927c1f7..cf80f22b4 100644 --- a/src/http/ngx_http_script.h +++ b/src/http/ngx_http_script.h @@ -19,7 +19,7 @@ typedef struct { ngx_http_variable_value_t *sp; ngx_str_t buf; - ngx_str_t *line; + ngx_str_t line; /* the start of the rewritten arguments */ u_char *args; @@ -29,6 +29,7 @@ typedef struct { unsigned log:1; int *captures; + ngx_uint_t ncaptures; ngx_int_t status; ngx_http_request_t *request; @@ -130,6 +131,12 @@ typedef struct { typedef struct { ngx_http_script_code_pt code; + ngx_array_t *lengths; +} ngx_http_script_complex_value_code_t; + + +typedef struct { + ngx_http_script_code_pt code; uintptr_t value; uintptr_t text_len; uintptr_t text_data; @@ -155,6 +162,7 @@ void ngx_http_script_copy_capture_code(ngx_http_script_engine_t *e); void ngx_http_script_start_args_code(ngx_http_script_engine_t *e); void ngx_http_script_return_code(ngx_http_script_engine_t *e); void ngx_http_script_if_code(ngx_http_script_engine_t *e); +void ngx_http_script_complex_value_code(ngx_http_script_engine_t *e); void ngx_http_script_value_code(ngx_http_script_engine_t *e); void ngx_http_script_set_var_code(ngx_http_script_engine_t *e); void ngx_http_script_var_code(ngx_http_script_engine_t *e); diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c index 0928fbd85..51ffbc0dc 100644 --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -77,71 +77,80 @@ ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = { { ngx_string("Status"), ngx_http_upstream_process_header_line, offsetof(ngx_http_upstream_headers_in_t, status), - /* STUB */ ngx_http_upstream_ignore_header_line, 0 }, + /* STUB */ ngx_http_upstream_ignore_header_line, 0, 0 }, { ngx_string("Content-Type"), ngx_http_upstream_process_header_line, offsetof(ngx_http_upstream_headers_in_t, content_type), - ngx_http_upstream_copy_content_type, 0 }, + ngx_http_upstream_copy_content_type, 0, 0 }, { ngx_string("Content-Length"), ngx_http_upstream_process_header_line, offsetof(ngx_http_upstream_headers_in_t, content_length), - ngx_http_upstream_copy_content_length, 0 }, + ngx_http_upstream_copy_content_length, 0, 0 }, { ngx_string("Date"), ngx_http_upstream_process_header_line, offsetof(ngx_http_upstream_headers_in_t, date), ngx_http_upstream_conditional_copy_header_line, - offsetof(ngx_http_upstream_conf_t, pass_date) }, + offsetof(ngx_http_upstream_conf_t, pass_date), 0 }, { ngx_string("Server"), ngx_http_upstream_process_header_line, offsetof(ngx_http_upstream_headers_in_t, server), ngx_http_upstream_conditional_copy_header_line, - offsetof(ngx_http_upstream_conf_t, pass_server) }, + offsetof(ngx_http_upstream_conf_t, pass_server), 0 }, { ngx_string("Location"), ngx_http_upstream_ignore_header_line, 0, - ngx_http_upstream_rewrite_location, 0 }, + ngx_http_upstream_rewrite_location, 0, 0 }, { ngx_string("Refresh"), ngx_http_upstream_ignore_header_line, 0, - ngx_http_upstream_rewrite_refresh, 0 }, + ngx_http_upstream_rewrite_refresh, 0, 0 }, + + { ngx_string("Set-Cookie"), + ngx_http_upstream_ignore_header_line, 0, + ngx_http_upstream_copy_header_line, 0, 1 }, { ngx_string("Cache-Control"), ngx_http_upstream_process_multi_header_lines, offsetof(ngx_http_upstream_headers_in_t, cache_control), ngx_http_upstream_copy_multi_header_lines, - offsetof(ngx_http_headers_out_t, cache_control) }, + offsetof(ngx_http_headers_out_t, cache_control), 1 }, { ngx_string("Connection"), ngx_http_upstream_ignore_header_line, 0, - ngx_http_upstream_ignore_header_line, 0 }, + ngx_http_upstream_ignore_header_line, 0, 0 }, { ngx_string("X-Pad"), ngx_http_upstream_ignore_header_line, 0, - ngx_http_upstream_ignore_header_line, 0 }, + ngx_http_upstream_ignore_header_line, 0, 0 }, { ngx_string("X-Powered-By"), ngx_http_upstream_ignore_header_line, 0, ngx_http_upstream_conditional_copy_header_line, - offsetof(ngx_http_upstream_conf_t, pass_x_powered_by) }, + offsetof(ngx_http_upstream_conf_t, pass_x_powered_by), 0 }, { ngx_string("X-Accel-Expires"), ngx_http_upstream_process_header_line, offsetof(ngx_http_upstream_headers_in_t, x_accel_expires), ngx_http_upstream_conditional_copy_header_line, - offsetof(ngx_http_upstream_conf_t, pass_x_accel_expires) }, + offsetof(ngx_http_upstream_conf_t, pass_x_accel_expires), 0 }, + + { ngx_string("X-Accel-Redirect"), + ngx_http_upstream_process_header_line, + offsetof(ngx_http_upstream_headers_in_t, x_accel_redirect), + ngx_http_upstream_ignore_header_line, 0, 0 }, #if (NGX_HTTP_GZIP) { ngx_string("Content-Encoding"), ngx_http_upstream_process_header_line, offsetof(ngx_http_upstream_headers_in_t, content_encoding), - ngx_http_upstream_copy_content_encoding, 0 }, + ngx_http_upstream_copy_content_encoding, 0, 0 }, #endif - { ngx_null_string, NULL, 0, NULL, 0 } + { ngx_null_string, NULL, 0, NULL, 0, 0 } }; @@ -698,14 +707,18 @@ ngx_http_upstream_send_request_handler(ngx_event_t *wev) static void ngx_http_upstream_process_header(ngx_event_t *rev) { - ssize_t n; - ngx_int_t rc; - ngx_uint_t i; - ngx_connection_t *c; - ngx_http_request_t *r; - ngx_http_upstream_t *u; - ngx_http_err_page_t *err_page; - ngx_http_core_loc_conf_t *clcf; + ssize_t n; + ngx_int_t rc; + ngx_uint_t i, key; + ngx_list_part_t *part; + ngx_table_elt_t *h; + ngx_connection_t *c; + ngx_http_request_t *r; + ngx_http_upstream_t *u; + ngx_http_err_page_t *err_page; + ngx_http_core_loc_conf_t *clcf; + ngx_http_upstream_header_t *hh; + ngx_http_upstream_main_conf_t *umcf; c = rev->data; r = c->data; @@ -875,6 +888,48 @@ ngx_http_upstream_process_header(ngx_event_t *rev) } } + if (r->upstream->headers_in.x_accel_redirect) { + ngx_http_upstream_finalize_request(r, u, NGX_DECLINED); + + umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module); + hh = (ngx_http_upstream_header_t *) umcf->headers_in_hash.buckets; + + part = &r->upstream->headers_in.headers.part; + h = part->elts; + + for (i = 0; /* void */; i++) { + + if (i >= part->nelts) { + if (part->next == NULL) { + break; + } + + part = part->next; + h = part->elts; + i = 0; + } + + key = h[i].hash % umcf->headers_in_hash.hash_size; + + if (hh[key].redirect + && hh[key].name.len == h[i].key.len + && ngx_strcasecmp(hh[key].name.data, h[i].key.data) == 0) + { + if (hh[key].copy_handler(r, &h[i], hh[key].conf) != NGX_OK) { + ngx_http_upstream_finalize_request(r, u, + NGX_HTTP_INTERNAL_SERVER_ERROR); + return; + } + + } + } + + ngx_http_internal_redirect(r, + &r->upstream->headers_in.x_accel_redirect->value, + NULL); + return; + } + ngx_http_upstream_send_response(r, u); } @@ -1307,6 +1362,11 @@ ngx_http_upstream_finalize_request(ngx_http_request_t *r, #endif r->log_handler = u->saved_log_handler; + + if (rc == NGX_DECLINED) { + return; + } + r->connection->log->action = "sending to client"; if (rc == 0 && r->main == NULL) { diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h index cf2aeaa0e..00a64aca6 100644 --- a/src/http/ngx_http_upstream.h +++ b/src/http/ngx_http_upstream.h @@ -87,6 +87,7 @@ typedef struct { ngx_uint_t offset; ngx_http_header_handler_pt copy_handler; ngx_uint_t conf; + ngx_uint_t redirect; /* unsigned redirect:1; */ } ngx_http_upstream_header_t; @@ -101,6 +102,7 @@ typedef struct { ngx_table_elt_t *expires; ngx_table_elt_t *etag; ngx_table_elt_t *x_accel_expires; + ngx_table_elt_t *x_accel_redirect; ngx_table_elt_t *content_type; ngx_table_elt_t *content_length; diff --git a/src/http/ngx_http_variables.c b/src/http/ngx_http_variables.c index 488efcc05..12ab5154b 100644 --- a/src/http/ngx_http_variables.c +++ b/src/http/ngx_http_variables.c @@ -15,6 +15,8 @@ static ngx_http_variable_value_t * static ngx_http_variable_value_t * ngx_http_variable_header(ngx_http_request_t *r, uintptr_t data); static ngx_http_variable_value_t * + ngx_http_variable_headers(ngx_http_request_t *r, uintptr_t data); +static ngx_http_variable_value_t * ngx_http_variable_unknown_header(ngx_http_request_t *r, uintptr_t data); static ngx_http_variable_value_t * ngx_http_variable_host(ngx_http_request_t *r, uintptr_t data); @@ -63,6 +65,9 @@ static ngx_http_variable_t ngx_http_core_variables[] = { offsetof(ngx_http_request_t, headers_in.x_forwarded_for), 0 }, #endif + { ngx_string("http_cookie"), ngx_http_variable_headers, + offsetof(ngx_http_request_t, headers_in.cookies), 0 }, + { ngx_string("content_length"), ngx_http_variable_header, offsetof(ngx_http_request_t, headers_in.content_length), 0 }, @@ -334,6 +339,62 @@ ngx_http_variable_header(ngx_http_request_t *r, uintptr_t data) static ngx_http_variable_value_t * +ngx_http_variable_headers(ngx_http_request_t *r, uintptr_t data) +{ + u_char *p; + ngx_uint_t i; + ngx_array_t *a; + ngx_table_elt_t **h; + ngx_http_variable_value_t *vv; + + a = (ngx_array_t *) ((char *) r + data); + + if (a->nelts == 0) { + return NGX_HTTP_VAR_NOT_FOUND; + } + + vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); + if (vv == NULL) { + return NULL; + } + + vv->value = 0; + + h = a->elts; + + if (a->nelts == 1) { + vv->text = (*h)->value; + return vv; + } + + vv->text.len = (size_t) - (ssize_t) (sizeof("; ") - 1); + + for (i = 0; i < a->nelts; i++) { + vv->text.len += h[i]->value.len + sizeof("; ") - 1; + } + + vv->text.data = ngx_palloc(r->pool, vv->text.len); + if (vv->text.data == NULL) { + return NULL; + } + + p = vv->text.data; + + for (i = 0; /* void */ ; i++) { + p = ngx_cpymem(p, h[i]->value.data, h[i]->value.len); + + if (i == a->nelts - 1) { + break; + } + + *p++ = ';'; *p++ = ' '; + } + + return vv; +} + + +static ngx_http_variable_value_t * ngx_http_variable_unknown_header(ngx_http_request_t *r, uintptr_t data) { ngx_str_t *var = (ngx_str_t *) data; diff --git a/src/os/unix/ngx_os.h b/src/os/unix/ngx_os.h index e39aab0ef..97a29e69f 100644 --- a/src/os/unix/ngx_os.h +++ b/src/os/unix/ngx_os.h @@ -31,7 +31,7 @@ typedef struct { } ngx_os_io_t; -void ngx_debug_init(); +void ngx_debug_init(void); ngx_int_t ngx_os_init(ngx_log_t *log); void ngx_os_status(ngx_log_t *log); ngx_int_t ngx_daemon(ngx_log_t *log); diff --git a/src/os/unix/ngx_posix_config.h b/src/os/unix/ngx_posix_config.h index 0862726c3..592ff7668 100644 --- a/src/os/unix/ngx_posix_config.h +++ b/src/os/unix/ngx_posix_config.h @@ -8,13 +8,13 @@ #define _NGX_POSIX_CONFIG_H_INCLUDED_ -#if 0 +#if (NGX_HPUX) #define _XOPEN_SOURCE #define _XOPEN_SOURCE_EXTENDED 1 #endif -#if 0 +#if (NGX_TRU64) #define _REENTRANT #endif diff --git a/src/os/unix/ngx_process.c b/src/os/unix/ngx_process.c index 0562a4644..f9689c9af 100644 --- a/src/os/unix/ngx_process.c +++ b/src/os/unix/ngx_process.c @@ -23,9 +23,9 @@ ngx_int_t ngx_last_process; ngx_process_t ngx_processes[NGX_MAX_PROCESSES]; -ngx_pid_t ngx_spawn_process(ngx_cycle_t *cycle, - ngx_spawn_proc_pt proc, void *data, - char *name, ngx_int_t respawn) +ngx_pid_t +ngx_spawn_process(ngx_cycle_t *cycle, ngx_spawn_proc_pt proc, void *data, + char *name, ngx_int_t respawn) { u_long on; ngx_pid_t pid; @@ -185,14 +185,16 @@ ngx_pid_t ngx_spawn_process(ngx_cycle_t *cycle, } -ngx_pid_t ngx_execute(ngx_cycle_t *cycle, ngx_exec_ctx_t *ctx) +ngx_pid_t +ngx_execute(ngx_cycle_t *cycle, ngx_exec_ctx_t *ctx) { return ngx_spawn_process(cycle, ngx_execute_proc, ctx, ctx->name, NGX_PROCESS_DETACHED); } -static void ngx_execute_proc(ngx_cycle_t *cycle, void *data) +static void +ngx_execute_proc(ngx_cycle_t *cycle, void *data) { ngx_exec_ctx_t *ctx = data; @@ -206,7 +208,8 @@ static void ngx_execute_proc(ngx_cycle_t *cycle, void *data) } -void ngx_process_get_status() +void +ngx_process_get_status(void) { int status; char *process; @@ -301,7 +304,8 @@ void ngx_process_get_status() } -void ngx_debug_point() +void +ngx_debug_point(void) { ngx_core_conf_t *ccf; diff --git a/src/os/unix/ngx_setproctitle.h b/src/os/unix/ngx_setproctitle.h index 107725a0a..22f7e3ea6 100644 --- a/src/os/unix/ngx_setproctitle.h +++ b/src/os/unix/ngx_setproctitle.h @@ -16,30 +16,36 @@ #define ngx_setproctitle setproctitle -#elif !defined NGX_SETPROCTITLE_USES_ENV +#else /* !NGX_HAVE_SETPROCTITLE */ -#define NGX_SETPROCTITLE_USES_ENV 1 +#if !defined NGX_SETPROCTITLE_USES_ENV #if (NGX_SOLARIS) +#define NGX_SETPROCTITLE_USES_ENV 1 #define NGX_SETPROCTITLE_PAD ' ' +ngx_int_t ngx_init_setproctitle(ngx_log_t *log); +void ngx_setproctitle(char *title); + #elif (NGX_LINUX) || (NGX_DARWIN) +#define NGX_SETPROCTITLE_USES_ENV 1 #define NGX_SETPROCTITLE_PAD '\0' -#endif - ngx_int_t ngx_init_setproctitle(ngx_log_t *log); void ngx_setproctitle(char *title); - -#else /* !NGX_SETPROCTITLE_USES_ENV */ +#else #define ngx_init_setproctitle(log) #define ngx_setproctitle(title) -#endif +#endif /* OSes */ + +#endif /* NGX_SETPROCTITLE_USES_ENV */ + +#endif /* NGX_HAVE_SETPROCTITLE */ #endif /* _NGX_SETPROCTITLE_H_INCLUDED_ */ |