aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/event/ngx_event_connect.c26
-rw-r--r--src/event/ngx_event_pipe.c11
-rw-r--r--src/event/ngx_event_pipe.h1
-rw-r--r--src/http/modules/proxy/ngx_http_proxy_handler.c85
4 files changed, 112 insertions, 11 deletions
diff --git a/src/event/ngx_event_connect.c b/src/event/ngx_event_connect.c
index e42efb8cb..2e4a33554 100644
--- a/src/event/ngx_event_connect.c
+++ b/src/event/ngx_event_connect.c
@@ -38,7 +38,10 @@ int ngx_event_connect_peer(ngx_peer_connection_t *pc)
pc->cached = 0;
pc->connection = NULL;
- if (pc->peers->number > 1) {
+ if (pc->peers->number == 1) {
+ peer = &pc->peers->peers[0];
+
+ } else {
/* there are several peers */
@@ -53,7 +56,10 @@ int ngx_event_connect_peer(ngx_peer_connection_t *pc)
}
}
- if (pc->peers->max_fails > 0) {
+ if (pc->peers->max_fails == 0) {
+ peer = &pc->peers->peers[pc->cur_peer];
+
+ } else {
/* the peers support a fault tolerance */
@@ -83,13 +89,8 @@ int ngx_event_connect_peer(ngx_peer_connection_t *pc)
}
}
- peer = &pc->peers->peers[pc->cur_peer];
-
/* ngx_unlock_mutex(pc->peers->mutex); */
-#if 0
- pc->addr_port_text = peer->addr_port_text;
-#endif
s = ngx_socket(AF_INET, SOCK_STREAM, IPPROTO_IP, 0);
@@ -263,6 +264,17 @@ ngx_log_debug(pc->log, "CONNECT: %s" _ peer->addr_port_text.data);
void ngx_event_connect_peer_failed(ngx_peer_connection_t *pc)
{
+ time_t now;
+
+ now = ngx_time();
+
+ /* ngx_lock_mutex(pc->peers->mutex); */
+
+ pc->peers->peers[pc->cur_peer].fails++;
+ pc->peers->peers[pc->cur_peer].accessed = now;
+
+ /* ngx_unlock_mutex(pc->peers->mutex); */
+
pc->cur_peer++;
if (pc->cur_peer >= pc->peers->number) {
diff --git a/src/event/ngx_event_pipe.c b/src/event/ngx_event_pipe.c
index 387d8b861..0d6e89159 100644
--- a/src/event/ngx_event_pipe.c
+++ b/src/event/ngx_event_pipe.c
@@ -252,7 +252,7 @@ int ngx_event_pipe_read_upstream(ngx_event_pipe_t *p)
if (n >= size) {
cl->hunk->last = cl->hunk->end;
- /* STUB */ cl->hunk->num = p->num++;
+/* STUB */ cl->hunk->num = p->num++;
if (p->input_filter(p, cl->hunk) == NGX_ERROR) {
return NGX_ABORT;
@@ -271,15 +271,17 @@ int ngx_event_pipe_read_upstream(ngx_event_pipe_t *p)
}
if ((p->upstream_eof || p->upstream_error) && p->free_raw_hunks) {
- /* STUB */ p->free_raw_hunks->hunk->num = p->num++;
+/* STUB */ p->free_raw_hunks->hunk->num = p->num++;
if (p->input_filter(p, p->free_raw_hunks->hunk) == NGX_ERROR) {
return NGX_ABORT;
}
p->free_raw_hunks = p->free_raw_hunks->next;
- for (cl = p->free_raw_hunks; cl; cl = cl->next) {
- ngx_pfree(p->pool, cl->hunk->start);
+ if (p->free_bufs) {
+ for (cl = p->free_raw_hunks; cl; cl = cl->next) {
+ ngx_pfree(p->pool, cl->hunk->start);
+ }
}
}
@@ -394,6 +396,7 @@ int ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p)
for (cl = p->free; cl; cl = cl->next) {
+ /* TODO: free hunk if p->free_bufs && upstream done */
/* add the free shadow raw hunk to p->free_raw_hunks */
if (cl->hunk->type & NGX_HUNK_LAST_SHADOW) {
diff --git a/src/event/ngx_event_pipe.h b/src/event/ngx_event_pipe.h
index fc68cc6e7..662d65f70 100644
--- a/src/event/ngx_event_pipe.h
+++ b/src/event/ngx_event_pipe.h
@@ -39,6 +39,7 @@ struct ngx_event_pipe_s {
unsigned read:1;
unsigned cachable:1;
unsigned single_buf:1;
+ unsigned free_bufs:1;
unsigned upstream_done:1;
unsigned upstream_error:1;
unsigned upstream_eof:1;
diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.c b/src/http/modules/proxy/ngx_http_proxy_handler.c
index 053b7b598..52c0481dd 100644
--- a/src/http/modules/proxy/ngx_http_proxy_handler.c
+++ b/src/http/modules/proxy/ngx_http_proxy_handler.c
@@ -229,6 +229,7 @@ static int ngx_http_proxy_handler(ngx_http_request_t *r)
r->request_body_handler = ngx_http_proxy_init_request;
r->data = p;
+ /* TODO: we ignore return value of ngx_http_read_client_request_body */
ngx_http_read_client_request_body(r, p->lcf->request_buffer_size);
return NGX_DONE;
@@ -449,6 +450,87 @@ static void ngx_http_proxy_send_request_handler(ngx_event_t *wev)
}
+#if 0
+
+static int ngx_http_proxy_connect(ngx_http_proxy_ctx_t *p)
+{
+ int rc;
+ ngx_chain_t *cl;
+ ngx_connection_t *c;
+
+ for ( ;; ) {
+ p->action = "connecting to upstream";
+
+ rc = ngx_event_connect_peer(&p->upstream);
+
+ if (rc == NGX_ERROR) {
+ ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR);
+ return NGX_DONE;
+ }
+
+ 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))) {
+ 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;
+ }
+
+ continue;
+ }
+
+ p->upstream.connection->data = p;
+ p->upstream.connection->write->event_handler =
+ ngx_http_proxy_send_request_handler;
+ p->upstream.connection->read->event_handler =
+ ngx_http_proxy_process_upstream_status_line;
+
+ c = p->upstream.connection;
+ c->pool = p->request->pool;
+ c->read->log = c->write->log = c->log = p->request->connection->log;
+
+ if (p->upstream.tries > 1 && p->request_sent) {
+
+ /* reinit the request chain */
+
+ for (cl = p->request->request_hunks; cl; cl = cl->next) {
+ cl->hunk->pos = cl->hunk->start;
+ }
+ }
+
+ p->request_sent = 0;
+ p->timedout = 0;
+
+ if (rc == NGX_OK) {
+ return ngx_http_proxy_send_request(p);
+ }
+
+ /* rc == NGX_AGAIN */
+
+ ngx_add_timer(c->write, p->lcf->connect_timeout);
+
+ return NGX_AGAIN;
+ }
+}
+
+#endif
+
+
static void ngx_http_proxy_send_request(ngx_http_proxy_ctx_t *p)
{
int rc;
@@ -986,6 +1068,9 @@ static void ngx_http_proxy_send_response(ngx_http_proxy_ctx_t *p)
ep->single_buf = 1;
}
+ /* TODO: ep->free_bufs = 0 if use ngx_create_chain_of_hunks() */
+ ep->free_bufs = 1;
+
/*
* event_pipe would do p->header_in->last += ep->preread_size
* as though these bytes were read.