diff options
Diffstat (limited to 'src/http')
-rw-r--r-- | src/http/modules/ngx_http_rewrite_module.c | 2 | ||||
-rw-r--r-- | src/http/modules/ngx_http_ssi_filter_module.c | 13 | ||||
-rw-r--r-- | src/http/ngx_http.c | 2 | ||||
-rw-r--r-- | src/http/ngx_http_core_module.c | 2 | ||||
-rw-r--r-- | src/http/ngx_http_postpone_filter_module.c | 16 | ||||
-rw-r--r-- | src/http/ngx_http_request.c | 16 | ||||
-rw-r--r-- | src/http/ngx_http_script.c | 19 | ||||
-rw-r--r-- | src/http/ngx_http_script.h | 2 | ||||
-rw-r--r-- | src/http/ngx_http_upstream.c | 7 | ||||
-rw-r--r-- | src/http/ngx_http_variables.c | 213 |
10 files changed, 277 insertions, 15 deletions
diff --git a/src/http/modules/ngx_http_rewrite_module.c b/src/http/modules/ngx_http_rewrite_module.c index 37266a4d8..c557314ee 100644 --- a/src/http/modules/ngx_http_rewrite_module.c +++ b/src/http/modules/ngx_http_rewrite_module.c @@ -395,7 +395,7 @@ ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) regex->size = sc.size; regex->args = sc.args; - if (sc.variables == 0) { + if (sc.variables == 0 && !sc.dup_capture) { regex->lengths = NULL; } diff --git a/src/http/modules/ngx_http_ssi_filter_module.c b/src/http/modules/ngx_http_ssi_filter_module.c index 15cb0c34c..dba3639df 100644 --- a/src/http/modules/ngx_http_ssi_filter_module.c +++ b/src/http/modules/ngx_http_ssi_filter_module.c @@ -734,6 +734,19 @@ ngx_http_ssi_output(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx) ngx_buf_t *b; ngx_chain_t *cl; +#if 1 + b = NULL; + for (cl = ctx->out; cl; cl = cl->next) { + if (cl->buf == b) { + ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, + "the same buf was used in ssi"); + ngx_debug_point(); + return NGX_ERROR; + } + b = cl->buf; + } +#endif + rc = ngx_http_next_body_filter(r, ctx->out); if (ctx->busy == NULL) { diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c index 5c1e0a041..a15b3e3cd 100644 --- a/src/http/ngx_http.c +++ b/src/http/ngx_http.c @@ -725,8 +725,6 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) ls->deferred_accept = in_addr[a].listen_conf->deferred_accept; #endif - ls->ctx = ctx; - hip = ngx_palloc(cf->pool, sizeof(ngx_http_in_port_t)); if (hip == NULL) { return NGX_CONF_ERROR; diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c index 4a9c2085b..487fd2684 100644 --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -1328,6 +1328,7 @@ ngx_http_internal_redirect(ngx_http_request_t *r, ngx_http_update_location_config(r); r->internal = 1; + r->method = NGX_HTTP_GET; ngx_http_handler(r); @@ -2528,6 +2529,7 @@ ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) static ngx_http_method_name_t ngx_methods_names[] = { { "GET", (uint32_t) ~NGX_HTTP_GET }, { "HEAD", (uint32_t) ~NGX_HTTP_HEAD }, + { "POST", (uint32_t) ~NGX_HTTP_POST }, { NULL, 0 } }; diff --git a/src/http/ngx_http_postpone_filter_module.c b/src/http/ngx_http_postpone_filter_module.c index 20a78a00c..76deaa4c8 100644 --- a/src/http/ngx_http_postpone_filter_module.c +++ b/src/http/ngx_http_postpone_filter_module.c @@ -89,6 +89,22 @@ ngx_http_postpone_filter(ngx_http_request_t *r, ngx_chain_t *in) return NGX_ERROR; } +#if 1 + { + ngx_chain_t *cl; + ngx_buf_t *b = NULL; + for (cl = pr->out; cl; cl = cl->next) { + if (cl->buf == b) { + ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, + "the same buf was used in postponed"); + ngx_debug_point(); + return NGX_ERROR; + } + b = cl->buf; + } + } +#endif + if (r != r->connection->data || r->postponed->request) { return NGX_AGAIN; } diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c index 615ae7511..d801e2ce5 100644 --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -201,11 +201,11 @@ ngx_http_init_connection(ngx_connection_t *c) } -static -void ngx_http_init_request(ngx_event_t *rev) +static void +ngx_http_init_request(ngx_event_t *rev) { - ngx_uint_t i; socklen_t len; + ngx_uint_t i; struct sockaddr_in sin; ngx_connection_t *c; ngx_http_request_t *r; @@ -274,7 +274,7 @@ void ngx_http_init_request(ngx_event_t *rev) /* AF_INET only */ - hip = c->servers; + hip = c->listening->servers; hia = hip->addrs; r->port = hip->port; @@ -311,7 +311,7 @@ void ngx_http_init_request(ngx_event_t *rev) r->in_addr = sin.sin_addr.s_addr; } - /* the last in_port->addrs address is "*" */ + /* the last address is "*" */ for ( /* void */ ; i < hip->naddrs - 1; i++) { if (hia[i].addr == r->in_addr) { @@ -1405,6 +1405,12 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc) || rc == NGX_HTTP_REQUEST_TIME_OUT || r->connection->error) { + if (rc == NGX_HTTP_CLIENT_CLOSED_REQUEST + && r->headers_out.status == 0) + { + r->headers_out.status = NGX_HTTP_CLIENT_CLOSED_REQUEST; + } + if (ngx_http_post_action(r) == NGX_OK) { return; } diff --git a/src/http/ngx_http_script.c b/src/http/ngx_http_script.c index 5a5245667..9826ecea5 100644 --- a/src/http/ngx_http_script.c +++ b/src/http/ngx_http_script.c @@ -91,6 +91,14 @@ ngx_http_script_compile(ngx_http_script_compile_t *sc) if (sc->source->data[i] >= '1' && sc->source->data[i] <= '9') { + n = sc->source->data[i] - '0'; + + if (sc->captures_mask & (1 << n)) { + sc->dup_capture = 1; + } + + sc->captures_mask |= 1 << n; + copy_capture = ngx_http_script_add_code(*sc->lengths, sizeof(ngx_http_script_copy_capture_code_t), NULL); @@ -100,7 +108,8 @@ ngx_http_script_compile(ngx_http_script_compile_t *sc) copy_capture->code = (ngx_http_script_code_pt) ngx_http_script_copy_capture_len_code; - copy_capture->n = 2 * (sc->source->data[i] - '0'); + copy_capture->n = 2 * n; + copy_capture = ngx_http_script_add_code(*sc->values, sizeof(ngx_http_script_copy_capture_code_t), @@ -110,14 +119,12 @@ ngx_http_script_compile(ngx_http_script_compile_t *sc) } copy_capture->code = ngx_http_script_copy_capture_code; - copy_capture->n = sc->source->data[i] - '0'; + copy_capture->n = 2 * n; - if (sc->ncaptures < copy_capture->n) { - sc->ncaptures = copy_capture->n; + if (sc->ncaptures < n) { + sc->ncaptures = n; } - copy_capture->n *= 2; - i++; continue; diff --git a/src/http/ngx_http_script.h b/src/http/ngx_http_script.h index 3ef4d42e3..c4aa408c0 100644 --- a/src/http/ngx_http_script.h +++ b/src/http/ngx_http_script.h @@ -47,6 +47,7 @@ typedef struct { ngx_uint_t variables; ngx_uint_t ncaptures; + ngx_uint_t captures_mask; ngx_uint_t size; void *main; @@ -54,6 +55,7 @@ typedef struct { unsigned compile_args:1; unsigned complete_lengths:1; unsigned complete_values:1; + unsigned dup_capture:1; unsigned args:1; } ngx_http_script_compile_t; diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c index 997038c9c..45e586f9d 100644 --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -170,6 +170,10 @@ ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = { ngx_http_upstream_ignore_header_line, 0, ngx_http_upstream_ignore_header_line, 0, 0 }, + { ngx_string("Keep-Alive"), + 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, 0 }, @@ -626,6 +630,8 @@ ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r, return; } + r->connection->log->action = "SSL handshaking to upstream"; + rc = ngx_ssl_handshake(c); if (rc == NGX_AGAIN) { @@ -852,7 +858,6 @@ ngx_http_upstream_send_request_handler(ngx_event_t *wev) "http upstream send request handler"); if (wev->timedout) { - c->log->action = "sending request to upstream"; ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_TIMEOUT); return; } diff --git a/src/http/ngx_http_variables.c b/src/http/ngx_http_variables.c index 69bfe3a5e..0f162a70e 100644 --- a/src/http/ngx_http_variables.c +++ b/src/http/ngx_http_variables.c @@ -49,6 +49,19 @@ static ngx_int_t ngx_http_variable_body_bytes_sent(ngx_http_request_t *r, static ngx_int_t ngx_http_variable_request_completion(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); +static ngx_int_t ngx_http_variable_sent_content_type(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); +static ngx_int_t ngx_http_variable_sent_content_length(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); +static ngx_int_t ngx_http_variable_sent_last_modified(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); +static ngx_int_t ngx_http_variable_sent_connection(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); +static ngx_int_t ngx_http_variable_sent_keep_alive(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); +static ngx_int_t ngx_http_variable_sent_transfer_encoding(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); + /* * TODO: @@ -59,6 +72,13 @@ static ngx_int_t ngx_http_variable_request_completion(ngx_http_request_t *r, * Apache SSI: DOCUMENT_NAME, LAST_MODIFIED, USER_NAME (file owner) */ +/* + * the $http_host, $http_user_agent, $http_referer, $http_via, + * and $http_x_forwarded_for variables may be handled by generic + * ngx_http_variable_unknown_header_in(), but for perfomance reasons + * they are handled using dedicated entries + */ + static ngx_http_variable_t ngx_http_core_variables[] = { { ngx_string("http_host"), NULL, ngx_http_variable_header, @@ -146,6 +166,27 @@ static ngx_http_variable_t ngx_http_core_variables[] = { ngx_http_variable_request_completion, 0, 0, 0 }, + { ngx_string("sent_http_content_type"), NULL, + ngx_http_variable_sent_content_type, 0, 0, 0 }, + + { ngx_string("sent_http_content_length"), NULL, + ngx_http_variable_sent_content_length, 0, 0, 0 }, + + { ngx_string("sent_http_last_modified"), NULL, + ngx_http_variable_sent_last_modified, 0, 0, 0 }, + + { ngx_string("sent_http_connection"), NULL, + ngx_http_variable_sent_connection, 0, 0, 0 }, + + { ngx_string("sent_http_keep_alive"), NULL, + ngx_http_variable_sent_keep_alive, 0, 0, 0 }, + + { ngx_string("sent_http_transfer_encoding"), NULL, + ngx_http_variable_sent_transfer_encoding, 0, 0, 0 }, + + { ngx_string("sent_http_cache_control"), NULL, ngx_http_variable_headers, + offsetof(ngx_http_request_t, headers_out.cache_control), 0, 0 }, + { ngx_string("limit_rate"), ngx_http_variable_request_set_size, ngx_http_variable_request, offsetof(ngx_http_request_t, limit_rate), @@ -847,6 +888,178 @@ ngx_http_variable_body_bytes_sent(ngx_http_request_t *r, static ngx_int_t +ngx_http_variable_sent_content_type(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) +{ + if (r->headers_out.content_type.len) { + v->len = r->headers_out.content_type.len; + v->valid = 1; + v->no_cachable = 0; + v->not_found = 0; + v->data = r->headers_out.content_type.data; + + } else { + v->not_found = 1; + } + + return NGX_OK; +} + + +static ngx_int_t +ngx_http_variable_sent_content_length(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) +{ + u_char *p; + + if (r->headers_out.content_length) { + v->len = r->headers_out.content_length->value.len; + v->valid = 1; + v->no_cachable = 0; + v->not_found = 0; + v->data = r->headers_out.content_length->value.data; + + return NGX_OK; + } + + if (r->headers_out.content_length_n >= 0) { + p = ngx_palloc(r->pool, NGX_OFF_T_LEN); + if (p == NULL) { + return NGX_ERROR; + } + + v->len = ngx_sprintf(p, "%O", r->headers_out.content_length_n) - p; + v->valid = 1; + v->no_cachable = 0; + v->not_found = 0; + v->data = p; + + return NGX_OK; + } + + v->not_found = 1; + + return NGX_OK; +} + + +static ngx_int_t +ngx_http_variable_sent_last_modified(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) +{ + u_char *p; + + if (r->headers_out.last_modified) { + v->len = r->headers_out.last_modified->value.len; + v->valid = 1; + v->no_cachable = 0; + v->not_found = 0; + v->data = r->headers_out.last_modified->value.data; + + return NGX_OK; + } + + if (r->headers_out.last_modified_time >= 0) { + p = ngx_palloc(r->pool, + sizeof("Last-Modified: Mon, 28 Sep 1970 06:00:00 GMT") - 1); + if (p == NULL) { + return NGX_ERROR; + } + + v->len = ngx_http_time(p, r->headers_out.last_modified_time) - p; + v->valid = 1; + v->no_cachable = 0; + v->not_found = 0; + v->data = p; + + return NGX_OK; + } + + v->not_found = 1; + + return NGX_OK; +} + + +static ngx_int_t +ngx_http_variable_sent_connection(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) +{ + size_t len; + char *p; + + if (r->keepalive) { + len = sizeof("keep-alive") - 1; + p = "keep-alive"; + + } else { + len = sizeof("close") - 1; + p = "close"; + } + + v->len = len; + v->valid = 1; + v->no_cachable = 0; + v->not_found = 0; + v->data = (u_char *) p; + + return NGX_OK; +} + + +static ngx_int_t +ngx_http_variable_sent_keep_alive(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) +{ + u_char *p; + ngx_http_core_loc_conf_t *clcf; + + if (r->keepalive) { + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + + if (clcf->keepalive_header) { + + p = ngx_palloc(r->pool, sizeof("timeout=") - 1 + NGX_TIME_T_LEN); + if (p == NULL) { + return NGX_ERROR; + } + + v->len = ngx_sprintf(p, "timeout=%T", clcf->keepalive_header) - p; + v->valid = 1; + v->no_cachable = 0; + v->not_found = 0; + v->data = p; + + return NGX_OK; + } + } + + v->not_found = 1; + + return NGX_OK; +} + + +static ngx_int_t +ngx_http_variable_sent_transfer_encoding(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) +{ + if (r->chunked) { + v->len = sizeof("chunked") - 1; + v->valid = 1; + v->no_cachable = 0; + v->not_found = 0; + v->data = (u_char *) "chunked"; + + } else { + v->not_found = 1; + } + + return NGX_OK; +} + + +static ngx_int_t ngx_http_variable_request_completion(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { |