Mercurial > hg > nginx-quic
diff src/http/modules/proxy/ngx_http_event_proxy_handler.c @ 71:59229033ae93
nginx-0.0.1-2003-04-08-19:40:10 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Tue, 08 Apr 2003 15:40:10 +0000 |
parents | src/http/modules/ngx_http_event_proxy_handler.c@e320bf51c4e3 |
children | 66de3f065886 |
line wrap: on
line diff
copy from src/http/modules/ngx_http_event_proxy_handler.c copy to src/http/modules/proxy/ngx_http_event_proxy_handler.c --- a/src/http/modules/ngx_http_event_proxy_handler.c +++ b/src/http/modules/proxy/ngx_http_event_proxy_handler.c @@ -4,6 +4,7 @@ #include <ngx_string.h> #include <ngx_file.h> #include <ngx_hunk.h> +#include <ngx_inet.h> #include <ngx_conf_file.h> #include <ngx_event_write.h> @@ -14,25 +15,44 @@ #include <ngx_http_event_proxy_handler.h> -static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_request_t *r); -static int ngx_http_proxy_connect(ngx_http_proxy_ctx_t *p, - struct sockaddr_in *addr, - char *addr_text); -static int ngx_http_proxy_send_request(ngx_event_t *ev); +static int ngx_http_proxy_handler(ngx_http_request_t *r); -static int ngx_http_proxy_init_response(ngx_event_t *ev); -static int ngx_http_proxy_read_response_header(ngx_event_t *ev); -static int ngx_http_proxy_process_status_line(ngx_http_request_t *r, - ngx_http_proxy_ctx_t *p); +static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_proxy_ctx_t *p); +static int ngx_http_proxy_process_upstream(ngx_http_proxy_ctx_t *p, + ngx_event_t *ev); +static int ngx_http_proxy_connect(ngx_http_proxy_ctx_t *p); +static int ngx_http_proxy_process_upstream_event(ngx_event_t *ev); +static int ngx_http_proxy_send_request(ngx_http_proxy_ctx_t *p); +static int ngx_http_proxy_init_upstream(ngx_http_proxy_ctx_t *p); +static int ngx_http_proxy_read_upstream_header(ngx_http_proxy_ctx_t *p); +static int ngx_http_proxy_process_upstream_status_line(ngx_http_proxy_ctx_t *p); + static int ngx_http_proxy_read_response_body(ngx_event_t *ev); static int ngx_http_proxy_write_to_client(ngx_event_t *ev); static int ngx_read_http_proxy_status_line(ngx_http_proxy_ctx_t *ctx); +static int ngx_http_proxy_finalize_request(ngx_http_proxy_ctx_t *p, int error); +static size_t ngx_http_proxy_log_error(void *data, char *buf, size_t len); + +static void *ngx_http_proxy_create_loc_conf(ngx_pool_t *pool); + +static char *ngx_http_proxy_set_pass(ngx_conf_t *cf, ngx_command_t *cmd, + char *conf); + +static char *ngx_http_proxy_parse_upstream(ngx_str_t *url, + ngx_http_proxy_upstream_url_t *uu); + static ngx_command_t ngx_http_proxy_commands[] = { + {ngx_string("proxy_pass"), + NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_http_proxy_set_pass, + NGX_HTTP_LOC_CONF_OFFSET, + 0}, + {ngx_string("proxy_large_header"), NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_flag_slot, @@ -44,13 +64,13 @@ static ngx_command_t ngx_http_proxy_com static ngx_http_module_t ngx_http_proxy_module_ctx = { + NGX_HTTP_MODULE, + NULL, /* create server config */ NULL, /* init server config */ - NULL, /* create location config */ - NULL, /* merge location config */ - - NULL /* init filters */ + ngx_http_proxy_create_loc_conf, /* create location config */ + NULL /* merge location config */ }; @@ -78,24 +98,35 @@ static char conn_close_header[] = "Conne /* AF_INET only */ -int ngx_http_proxy_handler(ngx_http_request_t *r) +static int ngx_http_proxy_handler(ngx_http_request_t *r) { - struct sockaddr_in addr; - ngx_chain_t *chain; - ngx_http_proxy_ctx_t *p; - ngx_http_log_ctx_t *hcx; - ngx_http_proxy_log_ctx_t *lcx; + int rc; + struct sockaddr_in addr; + ngx_chain_t *chain; + ngx_http_proxy_ctx_t *p; + ngx_http_log_ctx_t *hcx; + ngx_http_proxy_log_ctx_t *lcx; + ngx_http_proxy_loc_conf_t *lcf; p = (ngx_http_proxy_ctx_t *) - ngx_http_get_module_ctx(r, ngx_http_proxy_module); + ngx_http_get_module_ctx(r, ngx_http_proxy_module_ctx); if (p == NULL) { - ngx_http_create_ctx(r, p, ngx_http_proxy_module, + ngx_http_create_ctx(r, p, ngx_http_proxy_module_ctx, sizeof(ngx_http_proxy_ctx_t), NGX_HTTP_INTERNAL_SERVER_ERROR); } - p->request = r; + if (p->upstream_url == NULL) { + lcf = (ngx_http_proxy_loc_conf_t *) + ngx_http_get_module_loc_conf(r, ngx_http_proxy_module_ctx); + + p->lcf = lcf; + p->request = r; + p->upstream_url = lcf->upstream_url; + p->upstreams = lcf->upstreams; + p->tries = lcf->upstreams->number; + } ngx_test_null(p->log, ngx_palloc(r->pool, sizeof(ngx_log_t)), NGX_HTTP_INTERNAL_SERVER_ERROR); @@ -106,56 +137,55 @@ int ngx_http_proxy_handler(ngx_http_requ p->log->data = lcx; hcx = r->connection->log->data; lcx->client = hcx->client; + lcx->url = hcx->url; - /* - if (!resolved) { - return ngx_dns_resolve(name, handler, p, r->pool, p->log); - } - */ + p->method = r->method; - chain = ngx_http_proxy_create_request(r); + /* TODO: read a client's body */ + + chain = ngx_http_proxy_create_request(p); if (chain == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } - /* TODO: duplicate hunks and chain if there is backend farm */ + /* TODO: duplicate the hunks and chain if there is backend farm */ p->out = chain; - ngx_memzero(&addr, sizeof(struct sockaddr_in)); - addr.sin_family = AF_INET; -#if 0 - addr.sin_addr.s_addr = inet_addr("127.0.0.1"); -#else - addr.sin_addr.s_addr = inet_addr("192.168.10.2"); -#endif - addr.sin_port = htons(9000); + p->last_error = NGX_HTTP_BAD_GATEWAY; + ngx_http_proxy_process_upstream(p, NULL); - return ngx_http_proxy_connect(p, &addr, "connecting to 127.0.0.1:9000"); + /* On an error ngx_http_proxy_process_upstream() calls + ngx_http_proxy_finalize_request() so we return NGX_DONE to avoid + the additional NGX_HTTP_INTERNAL_SERVER_ERROR error + that would be generated by ngx_http_process_request() */ + + return NGX_DONE; } -static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_request_t *r) +static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_proxy_ctx_t *p) { - int i; - size_t len; - ngx_hunk_t *hunk; - ngx_chain_t *chain; - ngx_table_elt_t *header; + int i; + size_t len; + ngx_hunk_t *hunk; + ngx_chain_t *chain; + ngx_table_elt_t *header; + ngx_http_request_t *r; - /* 2 is for "\r\n" after request line - and 2 is for "\r\n" at the header end */ - - /* STUB: "method p->url HTTP/1.0" length */ + r = p->request; - len = r->request_line.len + 2 + 2; - - /* TODO: Host length */ - - /* "Connection: close\r\n" */ - len += sizeof(conn_close_header) - 1; + len = http_methods[p->method - 1].len + + p->upstream_url->uri.len + + (r->uri.len - p->upstream_url->location->len) + + r->args.len + 1 /* 1 is for "?" */ + + sizeof(http_version) - 1 + + sizeof(host_header) - 1 + p->upstream_url->host.len + 2 + + sizeof(conn_close_header) - 1 + + 2; /* 2 is for "\r\n" at the header end */ header = (ngx_table_elt_t *) r->headers_in.headers->elts; for (i = 0; i < r->headers_in.headers->nelts; i++) { + if (&header[i] == r->headers_in.host) { continue; } @@ -173,56 +203,46 @@ static ngx_chain_t *ngx_http_proxy_creat ngx_test_null(hunk, ngx_create_temp_hunk(r->pool, len, 0, 0), NULL); ngx_add_hunk_to_chain(chain, hunk, r->pool, NULL); -#if 0 - /* the request line */ ngx_memcpy(hunk->last, http_methods[p->method - 1].data, http_methods[p->method - 1].len); hunk->last += http_methods[p->method - 1].len; - ngx_memcpy(hunk->last, p->uri_start.data, p->uri_start.len); - hunk->last += p->uri_start.len; + ngx_memcpy(hunk->last, p->upstream_url->uri.data, p->upstream_url->uri.len); + hunk->last += p->upstream_url->uri.len; - ngx_memcpy(hunk->last, p->uri_rest.data, p->uri_rest.len); - hunk->last += p->uri_rest.len; + ngx_memcpy(hunk->last, r->uri.data + p->upstream_url->location->len, + r->uri.len - p->upstream_url->location->len); + hunk->last += r->uri.len - p->upstream_url->location->len; - if (r->args) { + if (r->args.len > 0) { *(hunk->last++) = '?'; - ngx_memcpy(hunk->last, r->uri_args.data, r->uri_args.len); - hunk->last += r->uri_args.len; + ngx_memcpy(hunk->last, r->args.data, r->args.len); + hunk->last += r->args.len; } ngx_memcpy(hunk->last, http_version, sizeof(http_version) - 1); hunk->last += sizeof(http_version) - 1; - /* the 'Host' header */ + /* the "Host" header */ ngx_memcpy(hunk->last, host_header, sizeof(host_header) - 1); hunk->last += sizeof(host_header) - 1; - ngx_memcpy(hunk->last, p->host.data, p->host.len); - hunk->last += p->host.len; + ngx_memcpy(hunk->last, p->upstream_url->host.data, + p->upstream_url->host.len); + hunk->last += p->upstream_url->host.len; *(hunk->last++) = CR; *(hunk->last++) = LF; - /* the 'Connection: close' header */ + /* the "Connection: close" header */ ngx_memcpy(hunk->last, conn_close_header, sizeof(conn_close_header) - 1); hunk->last += sizeof(conn_close_header) - 1; -#else - - ngx_memcpy(hunk->last, r->request_line.data, r->request_line.len); - hunk->last += r->request_line.len; - *(hunk->last++) = CR; *(hunk->last++) = LF; + for (i = 0; i < r->headers_in.headers->nelts; i++) { - ngx_memcpy(hunk->last, conn_close_header, sizeof(conn_close_header) - 1); - hunk->last += sizeof(conn_close_header) - 1; - -#endif - - for (i = 0; i < r->headers_in.headers->nelts; i++) { if (&header[i] == r->headers_in.host) { continue; } @@ -255,112 +275,191 @@ static ngx_chain_t *ngx_http_proxy_creat } -#if 0 +static int ngx_http_proxy_process_upstream(ngx_http_proxy_ctx_t *p, + ngx_event_t *ev) +{ + int rc; + time_t now; + ngx_connection_t *c; + ngx_http_proxy_upstream_t *u; -client_read() - if (!ev->write) { - if error close upstream ? - else block it - } + for ( ;; ) { - -static int ngx_http_proxy_process_upstream(ngx_event_t *ev) -{ - again = 0; + if (ev == NULL) { + /* STUB: look up cached connection */ + c = NULL; - do { + if (c) { + p->cached_connection = 1; + p->connection = c; + c->write->event_handler = ngx_http_proxy_process_upstream_event; + rc = ngx_http_proxy_send_request(p); - if (p->state_write_upstream_handler == - ngx_http_proxy_connect_to_upstream) { - if (!get_cached_connection()) - get_next_upstream(p); - } + } else { + p->cached_connection = 0; + p->connection = NULL; + rc = ngx_http_proxy_connect(p); + } - if (ev->write) { - - /* ngx_http_proxy_connect_to_upstream() - ngx_http_proxy_send_request() */ - - rc = p->state_write_upstream_handler(p); + if (p->connection) { + ev = p->connection->write; + } } else { - /* ngx_http_proxy_read_response() */ + if (ev->timedout) { + rc = NGX_HTTP_GATEWAY_TIME_OUT; + + } else if (ev->write) { - rc = p->state_read_upstream_handler(p); + rc = p->state_write_upstream_handler(p); + + } else { /* ev->read */ + + rc = p->state_read_upstream_handler(p); + } } - if (rc == NGX_BUSY || rc == NGX_AGAIN || rc == NGX_OK) { + if (rc == NGX_DONE || rc == NGX_AGAIN) { return rc; } if (rc == NGX_ERROR) { return ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR); + return NGX_DONE; } - /* This NGX_HTTP_INTERNAL_SERVER_ERROR is sent by an upstream */ - if (rc == NGX_HTTP_BAD_GATEWAY || rc == NGX_HTTP_GATEWAY_TIME_OUT - || (rc == NGX_HTTP_INTERNAL_SERVER_ERROR && lcf->retry_500) + || (rc == NGX_OK + && p->status == NGX_HTTP_INTERNAL_SERVER_ERROR + && p->lcf->retry_500_error)) { - ngx_http_close_connection(ev); - - if (p->upstream->amount > 1) { - /* Here is the race condition on SMP machine - when the upstreams are shared between threads or processes - but it's not serious */ - p->upstream->upstreams[p->cur_upstream].fails++; + if (ev) { + ngx_event_close_connection(ev); + ev = NULL; } - p->upstreams--; + if (!p->cached_connection) { + if (p->upstreams->number > 1) { + now = ngx_time(); + u = &p->upstreams->u[p->cur_upstream]; + + /* Here is the race condition when the upstreams are shared + between threads or processes but it's not serious */ - if (p->upstreams == 0) { - return ngx_http_proxy_finalize_request(p, rc); - } + u->fails++; + u->accessed = now; - p->cur_upstream++; - if (p->cur_upstream > p->upstream->amount) { - p->cur_upstream = 0; + /* */ + } + + p->tries--; + p->last_error = rc; } - p->state_read_upstream_handler = ignore; - p->state_write_upstream_handler = - ngx_http_proxy_connect_to_upstream; - again = 1; + if (p->tries == 0) { + ngx_http_proxy_finalize_request(p, p->last_error); + return NGX_ERROR; + } } - if (rc == NGX_HTTP_INTERNAL_SERVER_ERROR) { - ??? + if (rc == NGX_OK) { + ngx_http_proxy_finalize_request(p, p->status); + return NGX_DONE; } - } while (again); + if (rc > NGX_OK) { + ngx_http_proxy_finalize_request(p, rc); + } - return NGX_BUSY; + return NGX_DONE; + } } static int ngx_http_proxy_connect(ngx_http_proxy_ctx_t *p) { - ngx_socket_t s; - ngx_connection_t *c; - ngx_http_log_ctx_t *lcx; + int rc, event; + struct sockaddr_in *addr; + ngx_err_t err; + ngx_socket_t s; + ngx_event_t *rev, *wev; + ngx_connection_t *c; + ngx_http_proxy_log_ctx_t *lcx; + ngx_http_proxy_upstream_t *u; + + if (p->upstreams->number > 1) { + if (p->tries == p->upstreams->number) { + + /* Here is the race condition + when the upstreams are shared between threads or processes + but it should not be serious */ + + p->cur_upstream = p->upstreams->current++; + + if (p->upstreams->current >= p->upstreams->number) { + p->upstreams->current = 0; + } + + /* */ + +#if (NGX_MULTITHREADED || NGX_MULTIPROCESSED) + /* eliminate the sequences of the race condition */ + if (p->cur_upstream >= p->upstreams->number) { + p->cur_upstream = 0; + } +#endif + } + + if (p->upstreams->max_fails > 0) { + + for ( ;; ) { + u = &p->upstreams->u[p->cur_upstream]; + + /* Here is the race condition + when the upstreams are shared between threads or processes + but it should not be serious */ + + if (u->fails > p->upstreams->max_fails + || u->accessed < p->upstreams->fail_timeout) + { + break; + } + + /* */ + + p->cur_upstream++; + + if (p->cur_upstream >= p->upstreams->number) { + p->cur_upstream = 0; + } + + p->tries--; + + if (p->tries == 0) { + return p->last_error; + } + } + } + } lcx = p->log->data; lcx->action = "connecting to an upstream"; - lcx->upstream = p->upstream.data; + lcx->upstream = p->upstreams->u[p->cur_upstream].addr_port_name.data; p->log->handler = ngx_http_proxy_log_error; s = ngx_socket(AF_INET, SOCK_STREAM, IPPROTO_IP, 0); + if (s == -1) { ngx_log_error(NGX_LOG_ALERT, p->log, ngx_socket_errno, ngx_socket_n " failed"); return NGX_ERROR; } - if (lcf->rcvbuf) { + if (p->lcf->rcvbuf) { if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, - (const void *) &rcvbuf, sizeof(int)) == -1) { + (const void *) &p->lcf->rcvbuf, sizeof(int)) == -1) { ngx_log_error(NGX_LOG_ALERT, p->log, ngx_socket_errno, "setsockopt(SO_RCVBUF) failed"); @@ -385,7 +484,51 @@ static int ngx_http_proxy_connect(ngx_ht return NGX_ERROR; } - rc = connect(s, (struct sockaddr *) p->addr, sizeof(struct sockaddr_in)); + c = &ngx_connections[s]; + rev = &ngx_read_events[s]; + wev = &ngx_write_events[s]; + + ngx_memzero(c, sizeof(ngx_connection_t)); + ngx_memzero(rev, sizeof(ngx_event_t)); + ngx_memzero(wev, sizeof(ngx_event_t)); + + rev->index = wev->index = NGX_INVALID_INDEX; + rev->data = wev->data = c; + c->read = rev; + c->write = wev; + rev->first = wev->first = 1; + rev->log = wev->log = c->log = p->log; + c->fd = s; + wev->close_handler = rev->close_handler = ngx_event_close_connection; + +#if !(USE_KQUEUE) + +#if (HAVE_EDGE_EVENT) /* epoll */ + + if (ngx_event_flags & NGX_HAVE_EDGE_EVENT) { + if (ngx_edge_add_event(wev) != NGX_OK) { + return NGX_ERROR; + } + } + +#endif + +#endif + + ngx_test_null(c->pool, ngx_create_pool(p->lcf->conn_pool_size, p->log), + NGX_ERROR); + + ngx_test_null(p->sockaddr, + ngx_pcalloc(c->pool, sizeof(struct sockaddr_in)), + NGX_ERROR); + + addr = (struct sockaddr_in *) p->sockaddr; + + addr->sin_family = AF_INET; + addr->sin_addr.s_addr = p->upstreams->u[p->cur_upstream].addr; + addr->sin_port = htons(p->upstreams->u[p->cur_upstream].port); + + rc = connect(s, p->sockaddr, sizeof(struct sockaddr_in)); if (rc == -1) { err = ngx_socket_errno; @@ -397,210 +540,89 @@ static int ngx_http_proxy_connect(ngx_ht ngx_close_socket_n " failed"); } - return NGX_HTTP_BAD_GATEWAY; - } - } - - c = &ngx_connections[s]; - rev = &ngx_read_events[s]; - wev = &ngx_write_events[s]; - - ngx_memzero(rev, sizeof(ngx_event_t)); - ngx_memzero(wev, sizeof(ngx_event_t)); - ngx_memzero(c, sizeof(ngx_connection_t)); - - rev->index = wev->index = NGX_INVALID_INDEX; - - rev->data = wev->data = c; - c->read = rev; - c->write = wev; - - rev->first = wev->first = 1; - - c->data = p->request; - p->connection = c; - - c->fd = s; - - rev->log = wev->log = c->log = p->log; - - ngx_test_null(c->pool, ngx_create_pool(lcf->conn_pool_size, p->log), - NGX_ERROR); - -} - -#if 0 -connect_upstream() - get next upstream - init connect to upstream - if error return error - if ok send_request(); - if inprogress p->state_handler = send_request, return busy - -send_request() - if timeout inc fail counter - p->state_handler = connect_upstream, return 504 -#endif - -#endif - - -static int ngx_http_proxy_connect(ngx_http_proxy_ctx_t *p, - struct sockaddr_in *addr, - char *addr_text) -{ - int rc, event; - ngx_err_t err; - ngx_socket_t s; - ngx_event_t *rev, *wev; - ngx_connection_t *c, *pc; - ngx_http_log_ctx_t *ctx; - - c = p->request->connection; - ctx = c->log->data; - ctx->action = addr_text; - - s = ngx_socket(AF_INET, SOCK_STREAM, IPPROTO_IP, 0); - if (s == -1) { - ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno, - ngx_socket_n " failed"); - return NGX_HTTP_INTERNAL_SERVER_ERROR; - } - -#if 0 - if (rcvbuf) { - if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, - (const void *) &rcvbuf, sizeof(int)) == -1) { - ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno, - "setsockopt(SO_RCVBUF) failed"); - - if (ngx_close_socket(s) == -1) { - ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno, - ngx_close_socket_n " failed"); - } - - return NGX_HTTP_INTERNAL_SERVER_ERROR; - } - } -#endif - - if (ngx_nonblocking(s) == -1) { - ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno, - ngx_nonblocking_n " failed"); - - if (ngx_close_socket(s) == -1) { - ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno, - ngx_close_socket_n " failed"); - } - - return NGX_HTTP_INTERNAL_SERVER_ERROR; - } - - rc = connect(s, (struct sockaddr *) addr, sizeof(struct sockaddr_in)); - - if (rc == -1) { - err = ngx_socket_errno; - if (err != NGX_EINPROGRESS) { - ngx_log_error(NGX_LOG_CRIT, c->log, err, "connect() failed"); - - if (ngx_close_socket(s) == -1) { - ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno, - ngx_close_socket_n " failed"); - } + ngx_destroy_pool(c->pool); return NGX_HTTP_BAD_GATEWAY; } } - pc = &ngx_connections[s]; - rev = &ngx_read_events[s]; - wev = &ngx_write_events[s]; - - ngx_memzero(rev, sizeof(ngx_event_t)); - ngx_memzero(wev, sizeof(ngx_event_t)); - ngx_memzero(pc, sizeof(ngx_connection_t)); - - rev->index = wev->index = NGX_INVALID_INDEX; - - rev->data = wev->data = pc; - pc->read = rev; - pc->write = wev; + c->data = p->request; + p->connection = c; - pc->data = p->request;; - p->connection = pc; - - pc->fd = s; - pc->servers = c->servers; - - ngx_test_null(pc->log, ngx_palloc(c->pool, sizeof(ngx_log_t)), NGX_OK); - ngx_memcpy(pc->log, c->log, sizeof(ngx_log_t)); - rev->log = wev->log = pc->log; - - ngx_test_null(pc->pool, - ngx_create_pool(/* STUB */ 1024 /**/, pc->log), - NGX_HTTP_INTERNAL_SERVER_ERROR); - - wev->event_handler = ngx_http_proxy_send_request; - rev->event_handler = ngx_http_proxy_init_response; - rev->close_handler = wev->close_handler = ngx_event_close_connection; - + ngx_test_null(c->pool, ngx_create_pool(p->lcf->conn_pool_size, p->log), + NGX_ERROR); #if (USE_KQUEUE) if (ngx_add_event(rev, NGX_READ_EVENT, NGX_CLEAR_EVENT) != NGX_OK) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; + return NGX_ERROR; } #else -#if (HAVE_CLEAR_EVENT) /* kqueue */ + if ((ngx_event_flags & NGX_HAVE_EDGE_EVENT) == 0) { /* not epoll */ - if (ngx_event_flags & NGX_HAVE_CLEAR_EVENT) { - event = NGX_CLEAR_EVENT; - - } else { - event = NGX_LEVEL_EVENT; - } + if (ngx_event_flags & NGX_HAVE_CLEAR_EVENT) { /* kqueue */ + event = NGX_CLEAR_EVENT; -#else /* select, poll, /dev/poll */ - - event = NGX_LEVEL_EVENT; + } else { /* select, poll, /dev/poll */ + event = NGX_LEVEL_EVENT; + } -#endif + /* TODO: aio, iocp */ - if (ngx_add_event(rev, NGX_READ_EVENT, event) != NGX_OK) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; + if (ngx_add_event(rev, NGX_READ_EVENT, event) != NGX_OK) { + return NGX_ERROR; + } } #endif /* USE_KQUEUE */ - /* TODO: aio, iocp */ + wev->event_handler = rev->event_handler = + ngx_http_proxy_process_upstream_event; + + p->state_write_upstream_handler = ngx_http_proxy_send_request; + p->state_read_upstream_handler = ngx_http_proxy_init_upstream; /* The connection has been established */ if (rc == 0) { wev->write = 1; wev->ready = 1; - return ngx_http_proxy_send_request(wev); + return ngx_http_proxy_send_request(p); } /* The connection is in a progress */ - /* TODO: oneshot */ - if (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_ONESHOT_EVENT) != NGX_OK) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; + wev->timer_set = 1; + ngx_add_timer(wev, p->lcf->connect_timeout); + +#if (USE_KQUEUE) + + if (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_CLEAR_EVENT) != NGX_OK) { + return NGX_ERROR; } - wev->timer_set = 1; - ngx_add_timer(wev, /* STUB: lcf->connect_timeout */ 10000); +#else + + /* TODO: aio, iocp */ + + if (ngx_event_flags & NGX_HAVE_EDGE_EVENT) { + return NGX_DONE; + } - return NGX_BUSY; + if (ngx_add_event(wev, NGX_WRITE_EVENT, event) != NGX_OK) { + return NGX_ERROR; + } + +#endif /* USE_KQUEUE */ + + return NGX_DONE; } -static int ngx_http_proxy_send_request(ngx_event_t *ev) +static int ngx_http_proxy_process_upstream_event(ngx_event_t *ev) { - ngx_chain_t *chain; ngx_connection_t *c; ngx_http_request_t *r; ngx_http_proxy_ctx_t *p; @@ -608,210 +630,181 @@ static int ngx_http_proxy_send_request(n c = (ngx_connection_t *) ev->data; r = (ngx_http_request_t *) c->data; p = (ngx_http_proxy_ctx_t *) - ngx_http_get_module_ctx(r, ngx_http_proxy_module); + ngx_http_get_module_ctx(r, ngx_http_proxy_module_ctx); + + return ngx_http_proxy_process_upstream(p, ev); +} + - if (ev->timedout) { - return ngx_http_proxy_error(r, p, NGX_HTTP_GATEWAY_TIME_OUT); - } +static int ngx_http_proxy_send_request(ngx_http_proxy_ctx_t *p) +{ + ngx_chain_t *chain; + ngx_event_t *wev; - chain = ngx_write_chain(c, p->out, 0); + chain = ngx_write_chain(p->connection, p->out, 0); if (chain == (ngx_chain_t *) -1) { return NGX_ERROR; } p->out = chain; - return NGX_BUSY; + wev = p->connection->write; + + ngx_del_timer(wev); + + if (chain) { + ngx_add_timer(wev, p->lcf->send_timeout); + wev->timer_set = 1; + + } else { + wev->timer_set = 0; + } + + return NGX_DONE; } -static int ngx_http_proxy_init_response(ngx_event_t *ev) +static int ngx_http_proxy_init_upstream(ngx_http_proxy_ctx_t *p) { - int n; - ngx_hunk_t **ph; - ngx_connection_t *c; - ngx_http_request_t *r; - ngx_http_proxy_ctx_t *p; + int n; + ngx_hunk_t **ph; + ngx_http_request_t *r; - c = (ngx_connection_t *) ev->data; - r = (ngx_http_request_t *) c->data; - - if (ev->timedout) { - return ngx_http_proxy_error(r, p, NGX_HTTP_GATEWAY_TIME_OUT); - } - - p = (ngx_http_proxy_ctx_t *) - ngx_http_get_module_ctx(r, ngx_http_proxy_module); + r = p->request; ngx_test_null(p->header_in, - ngx_create_temp_hunk(r->pool, - /* STUB */ 1024 /**/, 0, 0), - ngx_http_proxy_error(r, p, NGX_HTTP_INTERNAL_SERVER_ERROR)); + ngx_create_temp_hunk(r->pool, p->lcf->header_size, 0, 0), + NGX_ERROR); p->header_in->type = NGX_HUNK_MEMORY|NGX_HUNK_IN_MEMORY; ngx_test_null(p->headers_in, ngx_palloc(r->pool, sizeof(ngx_http_proxy_headers_in_t)), - ngx_http_proxy_error(r, p, NGX_HTTP_INTERNAL_SERVER_ERROR)); + NGX_ERROR); - ngx_init_array(p->hunks, r->pool, - /* STUB */ 10 /**/, - sizeof(ngx_hunk_t *), - ngx_http_proxy_error(r, p, NGX_HTTP_INTERNAL_SERVER_ERROR)); + p->hunks_number = p->lcf->max_block_size / p->lcf->block_size; + if (p->hunks_number * p->lcf->block_size < p->lcf->max_block_size) { + p->hunks_number++; + } + + ngx_init_array(p->hunks, r->pool, p->hunks_number, sizeof(ngx_hunk_t *), + NGX_ERROR); ngx_test_null(ph, ngx_push_array(&p->hunks), NGX_ERROR); *ph = p->header_in; - p->state_handler = ngx_http_proxy_process_status_line; + p->state_handler = ngx_http_proxy_process_upstream_status_line; - return ngx_http_proxy_read_response_header(ev); + return ngx_http_proxy_read_upstream_header(p); } -static int ngx_http_proxy_read_response_header(ngx_event_t *ev) +static int ngx_http_proxy_read_upstream_header(ngx_http_proxy_ctx_t *p) { - int n; - ngx_hunk_t **ph; - ngx_connection_t *c; - ngx_http_request_t *r; - ngx_http_proxy_ctx_t *p; - ngx_http_proxy_loc_conf_t *lcf; + int n, rc; + ngx_event_t *rev; - c = (ngx_connection_t *) ev->data; - r = (ngx_http_request_t *) c->data; - p = (ngx_http_proxy_ctx_t *) - ngx_http_get_module_ctx(r, ngx_http_proxy_module); - - if (ev->timedout) { - return ngx_http_proxy_error(r, p, NGX_HTTP_GATEWAY_TIME_OUT); - } - - lcf = (ngx_http_proxy_loc_conf_t *) - ngx_http_get_module_loc_conf(r, ngx_http_proxy_module); - - -#if 0 + rev = p->connection->read; do { - n = ngx_event_recv(c, p->header_in->last, - p->header_in->end - p->header_in->last; + n = ngx_event_recv(p->connection, p->header_in->last, + p->header_in->end - p->header_in->last); if (n == NGX_AGAIN) { - if (ev->timer_set) { - ngx_del_timer(ev); + if (rev->timer_set) { + ngx_del_timer(rev); } else { - ev->timer_set = 1; + rev->timer_set = 1; } - ngx_add_timer(ev, lcf->timeout); + ngx_add_timer(rev, p->lcf->read_timeout); return NGX_AGAIN; } if (n == NGX_ERROR) { - ngx_http_proxy_close_request(r, p); - return ngx_http_error(r, NGX_HTTP_BAD_GATEWAY); + return NGX_HTTP_BAD_GATEWAY; } - ngx_log_debug(c->log, "http proxy read %d" _ n); + ngx_log_debug(p->log, "http proxy read %d" _ n); if (n == 0) { - ngx_log_error(NGX_LOG_INFO, c->log, 0, - "client has prematurely closed connection"); - ngx_http_proxy_close_request(r, p); + ngx_log_error(NGX_LOG_INFO, p->log, 0, + "upstream closed prematurely connection"); + return NGX_HTTP_BAD_GATEWAY; } p->header_in->last += n; - if (lcf->large_header && p->header_in->end == p->header_in->last) { - again = 1; - } else { - again = 0; - } - - - - -#if (HAVE_AIO_EVENT) /* aio, iocp */ - - if (ngx_event_flags & NGX_HAVE_AIO_EVENT) { - again = 1; - } - -#endif - - } while (rc == NGX_AGAIN && again); - -#endif + /* the state handlers are called in the following order: + ngx_http_proxy_process_upstream_status_line(r) + ngx_http_proxy_process_upstream_headers(r) */ - n = ngx_event_recv(c, p->header_in->last, - p->header_in->end - p->header_in->last); - - ngx_log_debug(c->log, "READ:%d" _ n); - - p->header_in->last += n; + do { + rc = p->state_handler(p); + } while (rc == NGX_AGAIN && p->header_in->end < p->header_in->last); - /* STUB */ - *p->header_in->last = '\0'; - ngx_log_debug(c->log, "PROXY:\n'%s'" _ p->header_in->pos); - /**/ + } while (rc == NGX_AGAIN + && (rev->ready || ngx_event_flags & NGX_HAVE_AIO_EVENT)); - if (n == 0) { - ngx_log_debug(c->log, "CLOSE proxy"); -#if 0 - ngx_del_event(ev, NGX_READ_EVENT, NGX_CLOSE_EVENT); -#endif - ngx_event_close_connection(ev); - - p->hunk_n = 0; - c->write->event_handler = ngx_http_proxy_write_to_client; - return ngx_http_proxy_write_to_client(c->write); + if (rc > NGX_OK) { + return rc; } - /* state_handlers are called in following order: - ngx_http_proxy_process_status_line(r, p) - ngx_http_proxy_process_reponse_header(r, p) */ - -#if 0 - do { - rc = (p->state_handler)(r, p); - - if (rc == NGX_ERROR) { - return rc; - } - - /* rc == NGX_OK || rc == NGX_AGAIN */ - - } while (p->header_in->pos.mem < p->header_in->last.mem); -#endif - - ev->event_handler = ngx_http_proxy_read_response_body; - if (p->header_in->end - p->header_in->last == 0) { - return ngx_http_proxy_read_response_body(ev); + if (rc == NGX_OK) { + /* STUB */ return NGX_ERROR; } - return NGX_BUSY; + /* STUB */ return NGX_ERROR; } -static int ngx_http_proxy_process_status_line(ngx_http_request_t *r, - ngx_http_proxy_ctx_t *p) +static int ngx_http_proxy_process_upstream_status_line(ngx_http_proxy_ctx_t *p) { int rc; +#if 0 + *p->header_in->last = '\0'; + ngx_log_debug(p->log, "PROXY:\n'%s'" _ p->header_in->pos); +#endif + rc = ngx_read_http_proxy_status_line(p); if (rc == NGX_HTTP_PROXY_PARSE_NO_HEADER) { p->status = 200; + p->status_line.len = 0; + p->full_status_line.len = 0; } if (rc == NGX_OK) { - /* STUB */ - ngx_log_debug(r->connection->log, "STATUS: %d" _ p->status); + p->status_line.len = p->status_end - p->status_start; + p->full_status_line.len = p->status_end - p->header_in->start; + + if (p->lcf->large_header) { + ngx_test_null(p->full_status_line.data, + ngx_palloc(p->request->pool, + p->full_status_line.len + 1), + NGX_HTTP_INTERNAL_SERVER_ERROR); + + ngx_cpystrn(p->full_status_line.data, p->header_in->start, + p->full_status_line.len + 1); + + if (p->header_in->pos == p->header_in->end) { + p->header_in->pos = p->header_in->last = p->header_in->start; + } + + } else { + p->status_line.data = p->status_start; + p->full_status_line.data = p->header_in->start; + *p->status_end = '\0'; + } + + ngx_log_debug(p->log, "upstream status: %d, '%s'" _ + p->status _ p->full_status_line.data); p->state_handler = NULL; } - if (p->header_in->last >= p->header_in->end) { + if (p->header_in->last == p->header_in->end) { rc = NGX_HTTP_PARSE_TOO_LONG_STATUS_LINE; } else if (rc == NGX_AGAIN) { @@ -822,6 +815,14 @@ static int ngx_http_proxy_process_status } + + + + + + + + #if 0 static int ngx_http_proxy_process_response_header(ngx_http_request_t *r, ngx_http_proxy_ctx_t *p) @@ -848,7 +849,7 @@ static int ngx_http_proxy_read_response_ c = (ngx_connection_t *) ev->data; r = (ngx_http_request_t *) c->data; p = (ngx_http_proxy_ctx_t *) - ngx_http_get_module_ctx(r, ngx_http_proxy_module); + ngx_http_get_module_ctx(r, ngx_http_proxy_module_ctx); if (p->hunks.nelts > 0) { h = ((ngx_hunk_t **) p->hunks.elts)[p->hunks.nelts - 1]; @@ -904,7 +905,7 @@ static int ngx_http_proxy_read_response_ ngx_log_debug(c->log, "READ:%d" _ n); if (n == NGX_AGAIN) { - return NGX_BUSY; + return NGX_DONE; } if (n == NGX_ERROR) { @@ -933,7 +934,7 @@ static int ngx_http_proxy_read_response_ return ngx_http_proxy_write_to_client(c->write); } - /* STUB */ return NGX_BUSY; + /* STUB */ return NGX_DONE; } @@ -948,7 +949,7 @@ static int ngx_http_proxy_write_to_clien c = (ngx_connection_t *) ev->data; r = (ngx_http_request_t *) c->data; p = (ngx_http_proxy_ctx_t *) - ngx_http_get_module_ctx(r, ngx_http_proxy_module); + ngx_http_get_module_ctx(r, ngx_http_proxy_module_ctx); do { h = ((ngx_hunk_t **) p->hunks.elts)[p->hunk_n]; @@ -970,13 +971,19 @@ static int ngx_http_proxy_write_to_clien } +static int ngx_http_proxy_finalize_request(ngx_http_proxy_ctx_t *p, int error) +{ + return ngx_http_finalize_request(p->request, error); +} + + static int ngx_http_proxy_error(ngx_http_request_t *r, ngx_http_proxy_ctx_t *p, int error) { ngx_event_close_connection(p->connection->read); return ngx_http_error(r, error); -} +} static size_t ngx_http_proxy_log_error(void *data, char *buf, size_t len) @@ -1085,7 +1092,7 @@ static int ngx_read_http_proxy_status_li if (++ctx->status_count == 3) { state = sw_space_after_status; - ctx->status_line = p - 3; + ctx->status_start = p - 3; } break; @@ -1121,7 +1128,7 @@ static int ngx_read_http_proxy_status_li /* end of request line */ case sw_almost_done: - ctx->request_end = p - 2; + ctx->status_end = p - 2; switch (ch) { case LF: state = sw_done; @@ -1136,8 +1143,8 @@ static int ngx_read_http_proxy_status_li ctx->header_in->pos = p; if (state == sw_done) { - if (ctx->request_end == NULL) { - ctx->request_end = p - 1; + if (ctx->status_end == NULL) { + ctx->status_end = p - 1; } ctx->state = sw_start; @@ -1150,43 +1157,73 @@ static int ngx_read_http_proxy_status_li } -#if 0 +static void *ngx_http_proxy_create_loc_conf(ngx_pool_t *pool) +{ + ngx_http_proxy_loc_conf_t *conf; + + ngx_test_null(conf, + ngx_pcalloc(pool, sizeof(ngx_http_proxy_loc_conf_t)), + NULL); + + /* STUB */ + conf->conn_pool_size = 16384; + conf->connect_timeout = 10000; + conf->send_timeout = 10000; + conf->read_timeout = 10000; + conf->header_size = 1024; + conf->block_size = 4096; + conf->max_block_size = 32768; + /**/ + + return conf; +} + static char *ngx_http_proxy_set_pass(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) { - ngx_http_proxy_conf_t *lcf = (ngx_http_proxy_conf_t *) conf; - char *url; - struct hostent *h; - ngx_str_t *value; - ngx_http_proxy_pass_t *pass; + ngx_http_proxy_loc_conf_t *lcf = (ngx_http_proxy_loc_conf_t *) conf; + + int i, s, len; + char *err, *host; + struct hostent *h; + u_int32_t addr; + ngx_str_t *value; + ngx_http_conf_ctx_t *ctx; + ngx_http_core_loc_conf_t *core_lcf; value = (ngx_str_t *) cf->args->elts; - url = value[1].data; - ngx_test_null(pass, ngx_push_array(lcf->proxy_pass), NGX_CONF_ERROR); - - if (ngx_strncasecmp(url, "http://", 7) == 0) { - /* STUB: "invalid prefix in URL %s", url */ - return "invalid prefix"; + if (ngx_strncasecmp(value[1].data, "http://", 7) != 0) { + return "invalid URL prefix"; } - err = ngx_http_proxy_parse_upstream(url, u); + ngx_test_null(lcf->upstream_url, + ngx_pcalloc(cf->pool, sizeof(ngx_http_proxy_upstream_url_t)), + NGX_CONF_ERROR); + + value[1].data += 7; + value[1].len -= 7; + + err = ngx_http_proxy_parse_upstream(&value[1], lcf->upstream_url); if (err) { - /* STUB: "%s %s", err, url */ return err; } - if (u.port == 0) { - u.port = 80; + if (lcf->upstream_url->port == 0) { + lcf->upstream_url->port = 80; } - ngx_test_null(host, ngx_palloc(cf->pool, u.host.len + 1), NGX_CONF_ERROR); - ngx_cpystr(host, u.host.data, u.host.len + 1); + ngx_test_null(host, ngx_palloc(cf->pool, lcf->upstream_url->host.len + 1), + NGX_CONF_ERROR); + ngx_cpystrn(host, lcf->upstream_url->host.data, + lcf->upstream_url->host.len + 1); - addr.sin_addr.s_addr = inet_addr(host); - if (addr.sin_addr.s_addr == INADDR_NONE) { + /* TODO: look up upstreams */ + + addr = inet_addr(host); + if (addr == INADDR_NONE) { h = gethostbyname(host); if (h == NULL || h->h_addr_list[0] == NULL) { @@ -1200,63 +1237,88 @@ static char *ngx_http_proxy_set_pass(ngx /* MP: ngx_shared_palloc() */ - ngx_test_null(upstreams, - ngx_palloc(cf->pool, - sizeof(ngx_http_proxy_upstreams_t) - + sizeof(ngx_http_proxy_upstream_t) * (i - 1)), + ngx_test_null(lcf->upstreams, + ngx_pcalloc(cf->pool, + sizeof(ngx_http_proxy_upstreams_t) + + sizeof(ngx_http_proxy_upstream_t) * (i - 1)), NGX_CONF_ERROR); - upstreams->num = i; + lcf->upstreams->number = i; for (i = 0; h->h_addr_list[i] != NULL; i++) { - upstreams->u[i].host.data = host; - upstreams->u[i].host.len = u.host.len; - upstreams->u[i].addr = *(struct in_addr *)(h->h_addr_list[i]); - upstreams->u[i].port = u.port; + lcf->upstreams->u[i].host.data = host; + lcf->upstreams->u[i].host.len = lcf->upstream_url->host.len; + lcf->upstreams->u[i].addr = *(u_int32_t *)(h->h_addr_list[i]); + lcf->upstreams->u[i].port = lcf->upstream_url->port; - len = INET_ADDRSTRLEN + u.port_name.len + 1; - ngx_test_null(upstreams->u[i].addr_port_name.data, + len = INET_ADDRSTRLEN + lcf->upstream_url->port_name.len + 1; + ngx_test_null(lcf->upstreams->u[i].addr_port_name.data, ngx_palloc(cf->pool, len), NGX_CONF_ERROR); - s = (ngx_inet_ntop(AF_INET, - upstreams->u[i].addr, - upstreams->u[i].addr_port_name.data, - len), + s = ngx_inet_ntop(AF_INET, + (char *) &lcf->upstreams->u[i].addr, + lcf->upstreams->u[i].addr_port_name.data, + len); + + lcf->upstreams->u[i].addr_port_name.data[s++] = ':'; - upstreams->u[i].addr_port_name.data[s++] = ':'; + ngx_cpystrn(lcf->upstreams->u[i].addr_port_name.data + s, + lcf->upstream_url->port_name.data, + lcf->upstream_url->port_name.len + 1); - ngx_cpystrn(upstreams->u[i].addr_port_name.data[s], - u.port_name.data, - u.port_name.len + 1); - - upstreams->u[i].addr_port_name.len = s + u.port_name.len + 1; + lcf->upstreams->u[i].addr_port_name.len = + s + lcf->upstream_url->port_name.len + 1; } } else { /* MP: ngx_shared_palloc() */ - ngx_test_null(upstreams, - ngx_palloc(cf->pool, sizeof(ngx_http_proxy_upstreams_t), + ngx_test_null(lcf->upstreams, + ngx_palloc(cf->pool, sizeof(ngx_http_proxy_upstreams_t)), + NGX_CONF_ERROR); + + lcf->upstreams->number = 1; + + lcf->upstreams->u[0].host.data = host; + lcf->upstreams->u[0].host.len = lcf->upstream_url->host.len; + lcf->upstreams->u[0].addr = addr; + lcf->upstreams->u[0].port = lcf->upstream_url->port; + + len = lcf->upstream_url->host.len + + lcf->upstream_url->port_name.len + 1; + + ngx_test_null(lcf->upstreams->u[0].addr_port_name.data, + ngx_palloc(cf->pool, len + 1), NGX_CONF_ERROR); - upstreams->num = 1; + ngx_memcpy(lcf->upstreams->u[0].addr_port_name.data, + lcf->upstream_url->host.data, + lcf->upstream_url->host.len); + + s = lcf->upstream_url->host.len; + + lcf->upstreams->u[0].addr_port_name.data[s++] = ':'; - upstreams->u[0].host.data = host; - upstreams->u[0].host.len = u.host.len; - upstreams->u[0].addr = *(struct in_addr *)(h->h_addr_list[i]); - upstreams->u[0].port = u.port; + ngx_cpystrn(lcf->upstreams->u[0].addr_port_name.data + s, + lcf->upstream_url->port_name.data, + lcf->upstream_url->port_name.len + 1); + + lcf->upstreams->u[0].addr_port_name.len = len; } + ctx = cf->ctx; + core_lcf = ctx->loc_conf[ngx_http_core_module_ctx.index]; + core_lcf->handler = ngx_http_proxy_handler; + lcf->upstream_url->location = &core_lcf->name; + return NULL; } -#endif - static char *ngx_http_proxy_parse_upstream(ngx_str_t *url, - ngx_http_proxy_upstream_url_t *u) + ngx_http_proxy_upstream_url_t *uu) { size_t i; @@ -1264,33 +1326,33 @@ static char *ngx_http_proxy_parse_upstre return "invalid upstream URL"; } - u->host.data = url->data; - u->host_header.data = url->data; + uu->host.data = url->data; + uu->host_header.data = url->data; for (i = 1; i < url->len; i++) { if (url->data[i] == ':') { - u->port_name.data = &url->data[i]; - u->host.len = i; + uu->port_name.data = &url->data[i] + 1; + uu->host.len = i; } if (url->data[i] == '/') { - u->uri.data = &url->data[i]; - u->uri.len = url->len - i; - u->host_header.len = i; + uu->uri.data = &url->data[i]; + uu->uri.len = url->len - i; + uu->host_header.len = i; - if (u->host.len == 0) { - u->host.len = i; + if (uu->host.len == 0) { + uu->host.len = i; } - if (u->port_name.data == NULL) { + if (uu->port_name.data == NULL) { return NULL; } - u->port_name.len = &url->data[i] - u->port_name.data; + uu->port_name.len = &url->data[i] - uu->port_name.data; - if (u->port_name.len > 0) { - u->port = ngx_atoi(u->port_name.data, u->port_name.len); - if (u->port > 0) { + if (uu->port_name.len > 0) { + uu->port = ngx_atoi(uu->port_name.data, uu->port_name.len); + if (uu->port > 0) { return NULL; } } @@ -1299,24 +1361,24 @@ static char *ngx_http_proxy_parse_upstre } } - if (u->host.len == 0) { - u->host.len = i; + if (uu->host.len == 0) { + uu->host.len = i; } - u->host_header.len = i; + uu->host_header.len = i; - u->uri.data = "/"; - u->uri.len = 1; + uu->uri.data = "/"; + uu->uri.len = 1; - if (u->port_name.data == NULL) { + if (uu->port_name.data == NULL) { return NULL; } - u->port_name.len = &url->data[i] - u->port_name.data; + uu->port_name.len = &url->data[i] - uu->port_name.data; - if (u->port_name.len > 0) { - u->port = ngx_atoi(u->port_name.data, u->port_name.len); - if (u->port > 0) { + if (uu->port_name.len > 0) { + uu->port = ngx_atoi(uu->port_name.data, uu->port_name.len); + if (uu->port > 0) { return NULL; } }