#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>
#if (NGX_HTTP_CACHE)
static ngx_int_t ngx_http_upstream_cache(ngx_http_request_t *r,
ngx_http_upstream_t *u);
static ngx_int_t ngx_http_upstream_cache_get(ngx_http_request_t *r,
ngx_http_upstream_t *u, ngx_http_file_cache_t **cache);
static ngx_int_t ngx_http_upstream_cache_send(ngx_http_request_t *r,
ngx_http_upstream_t *u);
static ngx_int_t ngx_http_upstream_cache_background_update(
ngx_http_request_t *r, ngx_http_upstream_t *u);
static ngx_int_t ngx_http_upstream_cache_check_range(ngx_http_request_t *r,
ngx_http_upstream_t *u);
static ngx_int_t ngx_http_upstream_cache_status(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_upstream_cache_last_modified(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_upstream_cache_etag(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
#endif
static void ngx_http_upstream_init_request(ngx_http_request_t *r);
static void ngx_http_upstream_resolve_handler(ngx_resolver_ctx_t *ctx);
static void ngx_http_upstream_rd_check_broken_connection(ngx_http_request_t *r);
static void ngx_http_upstream_wr_check_broken_connection(ngx_http_request_t *r);
static void ngx_http_upstream_check_broken_connection(ngx_http_request_t *r,
ngx_event_t *ev);
static void ngx_http_upstream_connect(ngx_http_request_t *r,
ngx_http_upstream_t *u);
static ngx_int_t ngx_http_upstream_reinit(ngx_http_request_t *r,
ngx_http_upstream_t *u);
static void ngx_http_upstream_send_request(ngx_http_request_t *r,
ngx_http_upstream_t *u, ngx_uint_t do_write);
static ngx_int_t ngx_http_upstream_send_request_body(ngx_http_request_t *r,
ngx_http_upstream_t *u, ngx_uint_t do_write);
static void ngx_http_upstream_send_request_handler(ngx_http_request_t *r,
ngx_http_upstream_t *u);
static void ngx_http_upstream_read_request_handler(ngx_http_request_t *r);
static void ngx_http_upstream_process_header(ngx_http_request_t *r,
ngx_http_upstream_t *u);
static ngx_int_t ngx_http_upstream_test_next(ngx_http_request_t *r,
ngx_http_upstream_t *u);
static ngx_int_t ngx_http_upstream_intercept_errors(ngx_http_request_t *r,
ngx_http_upstream_t *u);
static ngx_int_t ngx_http_upstream_test_connect(ngx_connection_t *c);
static ngx_int_t ngx_http_upstream_process_headers(ngx_http_request_t *r,
ngx_http_upstream_t *u);
static ngx_int_t ngx_http_upstream_process_trailers(ngx_http_request_t *r,
ngx_http_upstream_t *u);
static void ngx_http_upstream_send_response(ngx_http_request_t *r,
ngx_http_upstream_t *u);
static void ngx_http_upstream_upgrade(ngx_http_request_t *r,
ngx_http_upstream_t *u);
static void ngx_http_upstream_upgraded_read_downstream(ngx_http_request_t *r);
static void ngx_http_upstream_upgraded_write_downstream(ngx_http_request_t *r);
static void ngx_http_upstream_upgraded_read_upstream(ngx_http_request_t *r,
ngx_http_upstream_t *u);
static void ngx_http_upstream_upgraded_write_upstream(ngx_http_request_t *r,
ngx_http_upstream_t *u);
static void ngx_http_upstream_process_upgraded(ngx_http_request_t *r,
ngx_uint_t from_upstream, ngx_uint_t do_write);
static void
ngx_http_upstream_process_non_buffered_downstream(ngx_http_request_t *r);
static void
ngx_http_upstream_process_non_buffered_upstream(ngx_http_request_t *r,
ngx_http_upstream_t *u);
static void
ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r,
ngx_uint_t do_write);
#if (NGX_THREADS)
static ngx_int_t ngx_http_upstream_thread_handler(ngx_thread_task_t *task,
ngx_file_t *file);
static void ngx_http_upstream_thread_event_handler(ngx_event_t *ev);
#endif
static ngx_int_t ngx_http_upstream_output_filter(void *data,
ngx_chain_t *chain);
static void ngx_http_upstream_process_downstream(ngx_http_request_t *r);
static void ngx_http_upstream_process_upstream(ngx_http_request_t *r,
ngx_http_upstream_t *u);
static void ngx_http_upstream_process_request(ngx_http_request_t *r,
ngx_http_upstream_t *u);
static void ngx_http_upstream_store(ngx_http_request_t *r,
ngx_http_upstream_t *u);
static void ngx_http_upstream_dummy_handler(ngx_http_request_t *r,
ngx_http_upstream_t *u);
static void ngx_http_upstream_next(ngx_http_request_t *r,
ngx_http_upstream_t *u, ngx_uint_t ft_type);
static void ngx_http_upstream_cleanup(void *data);
static void ngx_http_upstream_finalize_request(ngx_http_request_t *r,
ngx_http_upstream_t *u, ngx_int_t rc);
static ngx_int_t ngx_http_upstream_process_header_line(ngx_http_request_t *r,
ngx_table_elt_t *h, ngx_uint_t offset);
static ngx_int_t
ngx_http_upstream_process_multi_header_lines(ngx_http_request_t *r,
ngx_table_elt_t *h, ngx_uint_t offset);
static ngx_int_t ngx_http_upstream_process_content_length(ngx_http_request_t *r,
ngx_table_elt_t *h, ngx_uint_t offset);
static ngx_int_t ngx_http_upstream_process_last_modified(ngx_http_request_t *r,
ngx_table_elt_t *h, ngx_uint_t offset);
static ngx_int_t ngx_http_upstream_process_set_cookie(ngx_http_request_t *r,
ngx_table_elt_t *h, ngx_uint_t offset);
static ngx_int_t
ngx_http_upstream_process_cache_control(ngx_http_request_t *r,
ngx_table_elt_t *h, ngx_uint_t offset);
static ngx_int_t ngx_http_upstream_ignore_header_line(ngx_http_request_t *r,
ngx_table_elt_t *h, ngx_uint_t offset);
static ngx_int_t ngx_http_upstream_process_expires(ngx_http_request_t *r,
ngx_table_elt_t *h, ngx_uint_t offset);
static ngx_int_t ngx_http_upstream_process_accel_expires(ngx_http_request_t *r,
ngx_table_elt_t *h, ngx_uint_t offset);
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_process_connection(ngx_http_request_t *r,
ngx_table_elt_t *h, ngx_uint_t offset);
static ngx_int_t
ngx_http_upstream_process_transfer_encoding(ngx_http_request_t *r,
ngx_table_elt_t *h, ngx_uint_t offset);
static ngx_int_t ngx_http_upstream_process_vary(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
ngx_http_upstream_copy_multi_header_lines(ngx_http_request_t *r,
ngx_table_elt_t *h, ngx_uint_t offset);
static ngx_int_t ngx_http_upstream_copy_content_type(ngx_http_request_t *r,
ngx_table_elt_t *h, ngx_uint_t offset);
static ngx_int_t ngx_http_upstream_copy_last_modified(ngx_http_request_t *r,
ngx_table_elt_t *h, ngx_uint_t offset);
static ngx_int_t ngx_http_upstream_rewrite_location(ngx_http_request_t *r,
ngx_table_elt_t *h, ngx_uint_t offset);
static ngx_int_t ngx_http_upstream_rewrite_refresh(ngx_http_request_t *r,
ngx_table_elt_t *h, ngx_uint_t offset);
static ngx_int_t ngx_http_upstream_rewrite_set_cookie(ngx_http_request_t *r,
ngx_table_elt_t *h, ngx_uint_t offset);
static ngx_int_t ngx_http_upstream_copy_allow_ranges(ngx_http_request_t *r,
ngx_table_elt_t *h, ngx_uint_t offset);
static ngx_int_t ngx_http_upstream_add_variables(ngx_conf_t *cf);
static ngx_int_t ngx_http_upstream_addr_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_upstream_status_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_upstream_response_time_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_upstream_response_length_variable(
ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_upstream_header_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_upstream_trailer_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_upstream_cookie_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static char *ngx_http_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy);
static char *ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static ngx_int_t ngx_http_upstream_set_local(ngx_http_request_t *r,
ngx_http_upstream_t *u, ngx_http_upstream_local_t *local);
static void *ngx_http_upstream_create_main_conf(ngx_conf_t *cf);
static char *ngx_http_upstream_init_main_conf(ngx_conf_t *cf, void *conf);
#if (NGX_HTTP_SSL)
static void ngx_http_upstream_ssl_init_connection(ngx_http_request_t *,
ngx_http_upstream_t *u, ngx_connection_t *c);
static void ngx_http_upstream_ssl_handshake_handler(ngx_connection_t *c);
static void ngx_http_upstream_ssl_handshake(ngx_http_request_t *,
ngx_http_upstream_t *u, ngx_connection_t *c);
static void ngx_http_upstream_ssl_save_session(ngx_connection_t *c);
static ngx_int_t ngx_http_upstream_ssl_name(ngx_http_request_t *r,
ngx_http_upstream_t *u, ngx_connection_t *c);
static ngx_int_t ngx_http_upstream_ssl_certificate(ngx_http_request_t *r,
ngx_http_upstream_t *u, ngx_connection_t *c);
#endif
static ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = …;
static ngx_command_t ngx_http_upstream_commands[] = …;
static ngx_http_module_t ngx_http_upstream_module_ctx = …;
ngx_module_t ngx_http_upstream_module = …;
static ngx_http_variable_t ngx_http_upstream_vars[] = …;
static ngx_http_upstream_next_t ngx_http_upstream_next_errors[] = …;
ngx_conf_bitmask_t ngx_http_upstream_cache_method_mask[] = …;
ngx_conf_bitmask_t ngx_http_upstream_ignore_headers_masks[] = …;
ngx_int_t
ngx_http_upstream_create(ngx_http_request_t *r)
{ … }
void
ngx_http_upstream_init(ngx_http_request_t *r)
{ … }
static void
ngx_http_upstream_init_request(ngx_http_request_t *r)
{ … }
#if (NGX_HTTP_CACHE)
static ngx_int_t
ngx_http_upstream_cache(ngx_http_request_t *r, ngx_http_upstream_t *u)
{ … }
static ngx_int_t
ngx_http_upstream_cache_get(ngx_http_request_t *r, ngx_http_upstream_t *u,
ngx_http_file_cache_t **cache)
{ … }
static ngx_int_t
ngx_http_upstream_cache_send(ngx_http_request_t *r, ngx_http_upstream_t *u)
{ … }
static ngx_int_t
ngx_http_upstream_cache_background_update(ngx_http_request_t *r,
ngx_http_upstream_t *u)
{ … }
static ngx_int_t
ngx_http_upstream_cache_check_range(ngx_http_request_t *r,
ngx_http_upstream_t *u)
{ … }
#endif
static void
ngx_http_upstream_resolve_handler(ngx_resolver_ctx_t *ctx)
{ … }
static void
ngx_http_upstream_handler(ngx_event_t *ev)
{ … }
static void
ngx_http_upstream_rd_check_broken_connection(ngx_http_request_t *r)
{ … }
static void
ngx_http_upstream_wr_check_broken_connection(ngx_http_request_t *r)
{ … }
static void
ngx_http_upstream_check_broken_connection(ngx_http_request_t *r,
ngx_event_t *ev)
{ … }
static void
ngx_http_upstream_connect(ngx_http_request_t *r, ngx_http_upstream_t *u)
{ … }
#if (NGX_HTTP_SSL)
static void
ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r,
ngx_http_upstream_t *u, ngx_connection_t *c)
{
ngx_int_t rc;
ngx_http_core_loc_conf_t *clcf;
if (ngx_http_upstream_test_connect(c) != NGX_OK) {
ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
return;
}
if (ngx_ssl_create_connection(u->conf->ssl, c,
NGX_SSL_BUFFER|NGX_SSL_CLIENT)
!= NGX_OK)
{
ngx_http_upstream_finalize_request(r, u,
NGX_HTTP_INTERNAL_SERVER_ERROR);
return;
}
if (u->conf->ssl_server_name || u->conf->ssl_verify) {
if (ngx_http_upstream_ssl_name(r, u, c) != NGX_OK) {
ngx_http_upstream_finalize_request(r, u,
NGX_HTTP_INTERNAL_SERVER_ERROR);
return;
}
}
if (u->conf->ssl_certificate
&& u->conf->ssl_certificate->value.len
&& (u->conf->ssl_certificate->lengths
|| u->conf->ssl_certificate_key->lengths))
{
if (ngx_http_upstream_ssl_certificate(r, u, c) != NGX_OK) {
ngx_http_upstream_finalize_request(r, u,
NGX_HTTP_INTERNAL_SERVER_ERROR);
return;
}
}
if (u->conf->ssl_session_reuse) {
c->ssl->save_session = ngx_http_upstream_ssl_save_session;
if (u->peer.set_session(&u->peer, u->peer.data) != NGX_OK) {
ngx_http_upstream_finalize_request(r, u,
NGX_HTTP_INTERNAL_SERVER_ERROR);
return;
}
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
if (clcf->tcp_nodelay && ngx_tcp_nodelay(c) != NGX_OK) {
ngx_http_upstream_finalize_request(r, u,
NGX_HTTP_INTERNAL_SERVER_ERROR);
return;
}
}
r->connection->log->action = "SSL handshaking to upstream";
rc = ngx_ssl_handshake(c);
if (rc == NGX_AGAIN) {
if (!c->write->timer_set) {
ngx_add_timer(c->write, u->conf->connect_timeout);
}
c->ssl->handler = ngx_http_upstream_ssl_handshake_handler;
return;
}
ngx_http_upstream_ssl_handshake(r, u, c);
}
static void
ngx_http_upstream_ssl_handshake_handler(ngx_connection_t *c)
{
ngx_http_request_t *r;
ngx_http_upstream_t *u;
r = c->data;
u = r->upstream;
c = r->connection;
ngx_http_set_log_request(c->log, r);
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
"http upstream ssl handshake: \"%V?%V\"",
&r->uri, &r->args);
ngx_http_upstream_ssl_handshake(r, u, u->peer.connection);
ngx_http_run_posted_requests(c);
}
static void
ngx_http_upstream_ssl_handshake(ngx_http_request_t *r, ngx_http_upstream_t *u,
ngx_connection_t *c)
{
long rc;
if (c->ssl->handshaked) {
if (u->conf->ssl_verify) {
rc = SSL_get_verify_result(c->ssl->connection);
if (rc != X509_V_OK) {
ngx_log_error(NGX_LOG_ERR, c->log, 0,
"upstream SSL certificate verify error: (%l:%s)",
rc, X509_verify_cert_error_string(rc));
goto failed;
}
if (ngx_ssl_check_host(c, &u->ssl_name) != NGX_OK) {
ngx_log_error(NGX_LOG_ERR, c->log, 0,
"upstream SSL certificate does not match \"%V\"",
&u->ssl_name);
goto failed;
}
}
if (!c->ssl->sendfile) {
c->sendfile = 0;
u->output.sendfile = 0;
}
c->write->handler = ngx_http_upstream_handler;
c->read->handler = ngx_http_upstream_handler;
ngx_http_upstream_send_request(r, u, 1);
return;
}
if (c->write->timedout) {
ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_TIMEOUT);
return;
}
failed:
ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
}
static void
ngx_http_upstream_ssl_save_session(ngx_connection_t *c)
{
ngx_http_request_t *r;
ngx_http_upstream_t *u;
if (c->idle) {
return;
}
r = c->data;
u = r->upstream;
c = r->connection;
ngx_http_set_log_request(c->log, r);
u->peer.save_session(&u->peer, u->peer.data);
}
static ngx_int_t
ngx_http_upstream_ssl_name(ngx_http_request_t *r, ngx_http_upstream_t *u,
ngx_connection_t *c)
{
u_char *p, *last;
ngx_str_t name;
if (u->conf->ssl_name) {
if (ngx_http_complex_value(r, u->conf->ssl_name, &name) != NGX_OK) {
return NGX_ERROR;
}
} else {
name = u->ssl_name;
}
if (name.len == 0) {
goto done;
}
p = name.data;
last = name.data + name.len;
if (*p == '[') {
p = ngx_strlchr(p, last, ']');
if (p == NULL) {
p = name.data;
}
}
p = ngx_strlchr(p, last, ':');
if (p != NULL) {
name.len = p - name.data;
}
if (!u->conf->ssl_server_name) {
goto done;
}
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
if (name.len == 0 || *name.data == '[') {
goto done;
}
if (ngx_inet_addr(name.data, name.len) != INADDR_NONE) {
goto done;
}
p = ngx_pnalloc(r->pool, name.len + 1);
if (p == NULL) {
return NGX_ERROR;
}
(void) ngx_cpystrn(p, name.data, name.len + 1);
name.data = p;
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"upstream SSL server name: \"%s\"", name.data);
if (SSL_set_tlsext_host_name(c->ssl->connection,
(char *) name.data)
== 0)
{
ngx_ssl_error(NGX_LOG_ERR, r->connection->log, 0,
"SSL_set_tlsext_host_name(\"%s\") failed", name.data);
return NGX_ERROR;
}
#endif
done:
u->ssl_name = name;
return NGX_OK;
}
static ngx_int_t
ngx_http_upstream_ssl_certificate(ngx_http_request_t *r,
ngx_http_upstream_t *u, ngx_connection_t *c)
{
ngx_str_t cert, key;
if (ngx_http_complex_value(r, u->conf->ssl_certificate, &cert)
!= NGX_OK)
{
return NGX_ERROR;
}
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
"http upstream ssl cert: \"%s\"", cert.data);
if (*cert.data == '\0') {
return NGX_OK;
}
if (ngx_http_complex_value(r, u->conf->ssl_certificate_key, &key)
!= NGX_OK)
{
return NGX_ERROR;
}
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
"http upstream ssl key: \"%s\"", key.data);
if (ngx_ssl_connection_certificate(c, r->pool, &cert, &key,
u->conf->ssl_passwords)
!= NGX_OK)
{
return NGX_ERROR;
}
return NGX_OK;
}
#endif
static ngx_int_t
ngx_http_upstream_reinit(ngx_http_request_t *r, ngx_http_upstream_t *u)
{ … }
static void
ngx_http_upstream_send_request(ngx_http_request_t *r, ngx_http_upstream_t *u,
ngx_uint_t do_write)
{ … }
static ngx_int_t
ngx_http_upstream_send_request_body(ngx_http_request_t *r,
ngx_http_upstream_t *u, ngx_uint_t do_write)
{ … }
static void
ngx_http_upstream_send_request_handler(ngx_http_request_t *r,
ngx_http_upstream_t *u)
{ … }
static void
ngx_http_upstream_read_request_handler(ngx_http_request_t *r)
{ … }
static void
ngx_http_upstream_process_header(ngx_http_request_t *r, ngx_http_upstream_t *u)
{ … }
static ngx_int_t
ngx_http_upstream_test_next(ngx_http_request_t *r, ngx_http_upstream_t *u)
{ … }
static ngx_int_t
ngx_http_upstream_intercept_errors(ngx_http_request_t *r,
ngx_http_upstream_t *u)
{ … }
static ngx_int_t
ngx_http_upstream_test_connect(ngx_connection_t *c)
{ … }
static ngx_int_t
ngx_http_upstream_process_headers(ngx_http_request_t *r, ngx_http_upstream_t *u)
{ … }
static ngx_int_t
ngx_http_upstream_process_trailers(ngx_http_request_t *r,
ngx_http_upstream_t *u)
{ … }
static void
ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
{ … }
static void
ngx_http_upstream_upgrade(ngx_http_request_t *r, ngx_http_upstream_t *u)
{ … }
static void
ngx_http_upstream_upgraded_read_downstream(ngx_http_request_t *r)
{ … }
static void
ngx_http_upstream_upgraded_write_downstream(ngx_http_request_t *r)
{ … }
static void
ngx_http_upstream_upgraded_read_upstream(ngx_http_request_t *r,
ngx_http_upstream_t *u)
{ … }
static void
ngx_http_upstream_upgraded_write_upstream(ngx_http_request_t *r,
ngx_http_upstream_t *u)
{ … }
static void
ngx_http_upstream_process_upgraded(ngx_http_request_t *r,
ngx_uint_t from_upstream, ngx_uint_t do_write)
{ … }
static void
ngx_http_upstream_process_non_buffered_downstream(ngx_http_request_t *r)
{ … }
static void
ngx_http_upstream_process_non_buffered_upstream(ngx_http_request_t *r,
ngx_http_upstream_t *u)
{ … }
static void
ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r,
ngx_uint_t do_write)
{ … }
ngx_int_t
ngx_http_upstream_non_buffered_filter_init(void *data)
{ … }
ngx_int_t
ngx_http_upstream_non_buffered_filter(void *data, ssize_t bytes)
{ … }
#if (NGX_THREADS)
static ngx_int_t
ngx_http_upstream_thread_handler(ngx_thread_task_t *task, ngx_file_t *file)
{
ngx_str_t name;
ngx_event_pipe_t *p;
ngx_connection_t *c;
ngx_thread_pool_t *tp;
ngx_http_request_t *r;
ngx_http_core_loc_conf_t *clcf;
r = file->thread_ctx;
p = r->upstream->pipe;
if (r->aio) {
c = r->connection;
#if (NGX_HTTP_V2)
if (r->stream) {
c = r->stream->connection->connection;
}
#endif
if (task == c->sendfile_task) {
return NGX_OK;
}
}
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
tp = clcf->thread_pool;
if (tp == NULL) {
if (ngx_http_complex_value(r, clcf->thread_pool_value, &name)
!= NGX_OK)
{
return NGX_ERROR;
}
tp = ngx_thread_pool_get((ngx_cycle_t *) ngx_cycle, &name);
if (tp == NULL) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"thread pool \"%V\" not found", &name);
return NGX_ERROR;
}
}
task->event.data = r;
task->event.handler = ngx_http_upstream_thread_event_handler;
if (ngx_thread_task_post(tp, task) != NGX_OK) {
return NGX_ERROR;
}
r->main->blocked++;
r->aio = 1;
p->aio = 1;
ngx_add_timer(&task->event, 60000);
return NGX_OK;
}
static void
ngx_http_upstream_thread_event_handler(ngx_event_t *ev)
{
ngx_connection_t *c;
ngx_http_request_t *r;
r = ev->data;
c = r->connection;
ngx_http_set_log_request(c->log, r);
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
"http upstream thread: \"%V?%V\"", &r->uri, &r->args);
if (ev->timedout) {
ngx_log_error(NGX_LOG_ALERT, c->log, 0,
"thread operation took too long");
ev->timedout = 0;
return;
}
if (ev->timer_set) {
ngx_del_timer(ev);
}
r->main->blocked--;
r->aio = 0;
#if (NGX_HTTP_V2)
if (r->stream) {
c->write->ready = 1;
c->write->active = 0;
}
#endif
if (r->done || r->main->terminated) {
c->write->handler(c->write);
} else {
r->write_event_handler(r);
ngx_http_run_posted_requests(c);
}
}
#endif
static ngx_int_t
ngx_http_upstream_output_filter(void *data, ngx_chain_t *chain)
{ … }
static void
ngx_http_upstream_process_downstream(ngx_http_request_t *r)
{ … }
static void
ngx_http_upstream_process_upstream(ngx_http_request_t *r,
ngx_http_upstream_t *u)
{ … }
static void
ngx_http_upstream_process_request(ngx_http_request_t *r,
ngx_http_upstream_t *u)
{ … }
static void
ngx_http_upstream_store(ngx_http_request_t *r, ngx_http_upstream_t *u)
{ … }
static void
ngx_http_upstream_dummy_handler(ngx_http_request_t *r, ngx_http_upstream_t *u)
{ … }
static void
ngx_http_upstream_next(ngx_http_request_t *r, ngx_http_upstream_t *u,
ngx_uint_t ft_type)
{ … }
static void
ngx_http_upstream_cleanup(void *data)
{ … }
static void
ngx_http_upstream_finalize_request(ngx_http_request_t *r,
ngx_http_upstream_t *u, ngx_int_t rc)
{ … }
static ngx_int_t
ngx_http_upstream_process_header_line(ngx_http_request_t *r, ngx_table_elt_t *h,
ngx_uint_t offset)
{ … }
static ngx_int_t
ngx_http_upstream_process_multi_header_lines(ngx_http_request_t *r,
ngx_table_elt_t *h, ngx_uint_t offset)
{ … }
static ngx_int_t
ngx_http_upstream_ignore_header_line(ngx_http_request_t *r, ngx_table_elt_t *h,
ngx_uint_t offset)
{ … }
static ngx_int_t
ngx_http_upstream_process_content_length(ngx_http_request_t *r,
ngx_table_elt_t *h, ngx_uint_t offset)
{ … }
static ngx_int_t
ngx_http_upstream_process_last_modified(ngx_http_request_t *r,
ngx_table_elt_t *h, ngx_uint_t offset)
{ … }
static ngx_int_t
ngx_http_upstream_process_set_cookie(ngx_http_request_t *r, ngx_table_elt_t *h,
ngx_uint_t offset)
{ … }
static ngx_int_t
ngx_http_upstream_process_cache_control(ngx_http_request_t *r,
ngx_table_elt_t *h, ngx_uint_t offset)
{ … }
static ngx_int_t
ngx_http_upstream_process_expires(ngx_http_request_t *r, ngx_table_elt_t *h,
ngx_uint_t offset)
{ … }
static ngx_int_t
ngx_http_upstream_process_accel_expires(ngx_http_request_t *r,
ngx_table_elt_t *h, ngx_uint_t offset)
{ … }
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_process_connection(ngx_http_request_t *r, ngx_table_elt_t *h,
ngx_uint_t offset)
{ … }
static ngx_int_t
ngx_http_upstream_process_transfer_encoding(ngx_http_request_t *r,
ngx_table_elt_t *h, ngx_uint_t offset)
{ … }
static ngx_int_t
ngx_http_upstream_process_vary(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
ngx_http_upstream_copy_multi_header_lines(ngx_http_request_t *r,
ngx_table_elt_t *h, ngx_uint_t offset)
{ … }
static ngx_int_t
ngx_http_upstream_copy_content_type(ngx_http_request_t *r, ngx_table_elt_t *h,
ngx_uint_t offset)
{ … }
static ngx_int_t
ngx_http_upstream_copy_last_modified(ngx_http_request_t *r, ngx_table_elt_t *h,
ngx_uint_t offset)
{ … }
static ngx_int_t
ngx_http_upstream_rewrite_location(ngx_http_request_t *r, ngx_table_elt_t *h,
ngx_uint_t offset)
{ … }
static ngx_int_t
ngx_http_upstream_rewrite_refresh(ngx_http_request_t *r, ngx_table_elt_t *h,
ngx_uint_t offset)
{ … }
static ngx_int_t
ngx_http_upstream_rewrite_set_cookie(ngx_http_request_t *r, ngx_table_elt_t *h,
ngx_uint_t offset)
{ … }
static ngx_int_t
ngx_http_upstream_copy_allow_ranges(ngx_http_request_t *r,
ngx_table_elt_t *h, ngx_uint_t offset)
{ … }
static ngx_int_t
ngx_http_upstream_add_variables(ngx_conf_t *cf)
{ … }
static ngx_int_t
ngx_http_upstream_addr_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
{ … }
static ngx_int_t
ngx_http_upstream_status_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
{ … }
static ngx_int_t
ngx_http_upstream_response_time_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
{ … }
static ngx_int_t
ngx_http_upstream_response_length_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
{ … }
static ngx_int_t
ngx_http_upstream_header_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
{ … }
static ngx_int_t
ngx_http_upstream_trailer_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
{ … }
static ngx_int_t
ngx_http_upstream_cookie_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
{ … }
#if (NGX_HTTP_CACHE)
static ngx_int_t
ngx_http_upstream_cache_status(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
{ … }
static ngx_int_t
ngx_http_upstream_cache_last_modified(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
{ … }
static ngx_int_t
ngx_http_upstream_cache_etag(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
{ … }
#endif
static char *
ngx_http_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
{ … }
static char *
ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{ … }
ngx_http_upstream_srv_conf_t *
ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags)
{ … }
char *
ngx_http_upstream_bind_set_slot(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf)
{ … }
static ngx_int_t
ngx_http_upstream_set_local(ngx_http_request_t *r, ngx_http_upstream_t *u,
ngx_http_upstream_local_t *local)
{ … }
char *
ngx_http_upstream_param_set_slot(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf)
{ … }
ngx_int_t
ngx_http_upstream_hide_headers_hash(ngx_conf_t *cf,
ngx_http_upstream_conf_t *conf, ngx_http_upstream_conf_t *prev,
ngx_str_t *default_hide_headers, ngx_hash_init_t *hash)
{ … }
static void *
ngx_http_upstream_create_main_conf(ngx_conf_t *cf)
{ … }
static char *
ngx_http_upstream_init_main_conf(ngx_conf_t *cf, void *conf)
{ … }