From fe0f5cc6e1e48412235ae91c2f71ec2ec9110a60 Mon Sep 17 00:00:00 2001 From: Igor Sysoev Date: Fri, 31 Oct 2003 16:05:33 +0000 Subject: nginx-0.0.1-2003-10-31-19:05:33 import --- src/http/modules/proxy/ngx_http_proxy_handler.c | 133 ++++++++++++++++++++---- src/http/modules/proxy/ngx_http_proxy_handler.h | 8 ++ src/http/ngx_http_headers.c | 7 +- src/http/ngx_http_request.c | 2 + 4 files changed, 128 insertions(+), 22 deletions(-) (limited to 'src/http') diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.c b/src/http/modules/proxy/ngx_http_proxy_handler.c index 52c0481dd..800039415 100644 --- a/src/http/modules/proxy/ngx_http_proxy_handler.c +++ b/src/http/modules/proxy/ngx_http_proxy_handler.c @@ -22,6 +22,7 @@ static void ngx_http_proxy_process_body(ngx_event_t *ev); static int ngx_http_proxy_parse_status_line(ngx_http_proxy_ctx_t *p); static void ngx_http_proxy_next_upstream(ngx_http_proxy_ctx_t *p, int ft_type); +static int ngx_http_proxy_log_state(ngx_http_proxy_ctx_t *p, int status); static void ngx_http_proxy_finalize_request(ngx_http_proxy_ctx_t *p, int rc); static void ngx_http_proxy_close_connection(ngx_connection_t *c); @@ -189,9 +190,9 @@ static ngx_http_header_t headers_in[] = { }; -static char http_version[] = " HTTP/1.0" CRLF; -static char host_header[] = "Host: "; -static char connection_close_header[] = "Connection: close" CRLF; +static char http_version[] = " HTTP/1.0" CRLF; +static char host_header[] = "Host: "; +static char connection_close_header[] = "Connection: close" CRLF; @@ -207,6 +208,10 @@ static int ngx_http_proxy_handler(ngx_http_request_t *r) p->upstream.peers = p->lcf->peers; p->upstream.tries = p->lcf->peers->number; + ngx_init_array(p->states, r->pool, p->upstream.tries, + sizeof(ngx_http_proxy_state_t), + NGX_HTTP_INTERNAL_SERVER_ERROR); + p->request = r; p->method = r->method; @@ -471,21 +476,13 @@ static int ngx_http_proxy_connect(ngx_http_proxy_ctx_t *p) if (rc == NGX_CONNECT_ERROR) { ngx_event_connect_peer_failed(&p->upstream); -#if 0 - /* TODO: make separate func and call it from next_upstream */ - - if (!(state = ngx_push_array(p->states))) { + if (ngx_http_proxy_log_state(p, NGX_HTTP_BAD_GATEWAY) == NGX_ERROR) + { ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR); return NGX_DONE; } - state->status = NGX_HTTP_BAD_GATEWAY; - state->peer = - p->upstream.peers->peers[p->upstream.cur_peer].addr_port_text; - -#endif - if (p->upstream.tries == 0) { ngx_http_proxy_finalize_request(p, NGX_HTTP_BAD_GATEWAY); return NGX_DONE; @@ -517,7 +514,7 @@ static int ngx_http_proxy_connect(ngx_http_proxy_ctx_t *p) p->timedout = 0; if (rc == NGX_OK) { - return ngx_http_proxy_send_request(p); + return ngx_http_proxy_send_request0(p); } /* rc == NGX_AGAIN */ @@ -528,6 +525,78 @@ static int ngx_http_proxy_connect(ngx_http_proxy_ctx_t *p) } } + +static int ngx_http_proxy_send_request0(ngx_http_proxy_ctx_t *p) +{ + ngx_connection_t *c; + ngx_chain_writer_ctx_t *wctx; + + c = p->upstream.connection; + + p->action = "sending request to upstream"; + wctx = p->output_chain_ctx->output_ctx; + wctx->connection = c; + rc = ngx_output_chain(p->output_chain_ctx, + !p->request_sent ? p->request->request_hunks: + NULL); + if (rc == NGX_ERROR) { + return ngx_http_proxy_next_upstream(p, NGX_HTTP_PROXY_FT_ERROR); + } + + p->request_sent = 1; + + if (c->write->timer_set) { + ngx_del_timer(c->write); + } + + if (rc == NGX_AGAIN) { + ngx_add_timer(c->write, p->lcf->send_timeout); + + if (ngx_handle_write_event(c->write, /* STUB: lowat */ 0) == NGX_ERROR) + { + ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR); + return; + } + + return NGX_AGAIN; + } + + /* rc == NGX_OK */ + + if (c->read->ready) { + /* post aio operation */ + ngx_http_proxy_process_upstream_status_line(c->read); + } + + if (ngx_handle_level_write_event(c->write) == NGX_ERROR) { + ngx_http_proxy_finalize_request(p, + NGX_HTTP_INTERNAL_SERVER_ERROR); + return; + } + + if (c->tcp_nopush) { + if (ngx_tcp_push(c->fd) == NGX_ERROR) { + ngx_log_error(NGX_LOG_CRIT, c->log, + ngx_socket_errno, + ngx_tcp_push_n " failed"); + ngx_http_proxy_finalize_request(p, + NGX_HTTP_INTERNAL_SERVER_ERROR); + return; + } + + c->tcp_nopush = 0; + } + } + + return; + } + + ngx_http_proxy_next_upstream(p, NGX_HTTP_PROXY_FT_ERROR); + + return NGX_OK; +} + + #endif @@ -1391,6 +1460,8 @@ static int ngx_http_proxy_parse_status_line(ngx_http_proxy_ctx_t *p) static void ngx_http_proxy_next_upstream(ngx_http_proxy_ctx_t *p, int ft_type) { + int status; + ngx_event_connect_peer_failed(&p->upstream); if (p->timedout) { @@ -1403,10 +1474,20 @@ static void ngx_http_proxy_next_upstream(ngx_http_proxy_ctx_t *p, int ft_type) p->upstream.connection = NULL; } + if (ft_type == NGX_HTTP_PROXY_FT_TIMEOUT) { + status = NGX_HTTP_GATEWAY_TIME_OUT; + + } else { + status = NGX_HTTP_BAD_GATEWAY; + } + + if (ngx_http_proxy_log_state(p, status) == NGX_ERROR) { + ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR); + return; + } + if (p->upstream.tries == 0 || !(p->lcf->next_upstream & ft_type)) { - ngx_http_proxy_finalize_request(p, - p->timedout ? NGX_HTTP_GATEWAY_TIME_OUT: - NGX_HTTP_BAD_GATEWAY); + ngx_http_proxy_finalize_request(p, status); return; } @@ -1420,6 +1501,23 @@ ngx_log_debug(p->request->connection->log, "FATAL ERROR IN NEXT UPSTREAM"); return; } + +static int ngx_http_proxy_log_state(ngx_http_proxy_ctx_t *p, int status) +{ + ngx_http_proxy_state_t *state; + + if (!(state = ngx_push_array(&p->states))) { + return NGX_ERROR; + } + + state->status = status; + state->peer = + &p->upstream.peers->peers[p->upstream.cur_peer].addr_port_text; + + return NGX_OK; +} + + static void ngx_http_proxy_finalize_request(ngx_http_proxy_ctx_t *p, int rc) { ngx_log_debug(p->request->connection->log, @@ -1447,7 +1545,6 @@ static void ngx_http_proxy_finalize_request(ngx_http_proxy_ctx_t *p, int rc) } - static void ngx_http_proxy_close_connection(ngx_connection_t *c) { ngx_log_debug(c->log, "close connection: %d" _ c->fd); diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.h b/src/http/modules/proxy/ngx_http_proxy_handler.h index 601a8f6ca..c211afbba 100644 --- a/src/http/modules/proxy/ngx_http_proxy_handler.h +++ b/src/http/modules/proxy/ngx_http_proxy_handler.h @@ -43,6 +43,12 @@ typedef struct { } ngx_http_proxy_loc_conf_t; +typedef struct { + int status; + ngx_str_t *peer; +} ngx_http_proxy_state_t; + + typedef struct { ngx_table_t *headers; /* it must be first field */ @@ -91,6 +97,8 @@ struct ngx_http_proxy_ctx_s { int status_count; int state; + ngx_array_t states; /* of ngx_http_proxy_state_t */ + char *action; ngx_http_log_ctx_t *saved_ctx; ngx_log_handler_pt saved_handler; diff --git a/src/http/ngx_http_headers.c b/src/http/ngx_http_headers.c index 3f009149a..b8773cbbf 100644 --- a/src/http/ngx_http_headers.c +++ b/src/http/ngx_http_headers.c @@ -48,7 +48,7 @@ ngx_http_header_t ngx_http_headers_out[] = { ngx_table_elt_t *ngx_http_add_header(void *header, ngx_http_header_t *http_headers) { - int i, j, nelts; + int i, j; char *prev; ngx_table_t *headers; ngx_table_elt_t *h, *new; @@ -56,7 +56,6 @@ ngx_table_elt_t *ngx_http_add_header(void *header, headers = *(ngx_table_t **) header; prev = headers->elts; - nelts = headers->nelts; if (!(new = ngx_push_table(headers))) { return NULL; @@ -74,10 +73,10 @@ ngx_table_elt_t *ngx_http_add_header(void *header, */ ngx_log_error(NGX_LOG_ALERT, headers->pool->log, 0, - "header table is small, %d elements", nelts); + "header table is small, %d elements", headers->nelts - 1); h = headers->elts; - for (i = 0; i < nelts; i++) { + for (i = 0; i < headers->nelts - 1; i++) { if (h[i].key.len == 0) { continue; } diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c index 36fac0352..dcf8dac66 100644 --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -95,6 +95,8 @@ void ngx_http_init_connection(ngx_connection_t *c) } #if 0 + /* TODO: learn SO_SNDBUF (to use in zerocopy) via kqueue's EV_CLEAR event */ + c->write->ready = 0; c->write->event_handler = ngx_http_dummy; -- cgit v1.2.3