diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c index 957927741..6e4d956d8 100644 --- a/src/http/modules/ngx_http_fastcgi_module.c +++ b/src/http/modules/ngx_http_fastcgi_module.c @@ -512,8 +512,16 @@ ngx_http_fastcgi_eval(ngx_http_request_t *r, ngx_http_fastcgi_loc_conf_t *flcf) return NGX_ERROR; } - r->upstream->resolved->host = u.host; - r->upstream->resolved->port = u.port; + if (u.addrs[0].sockaddr) { + r->upstream->resolved->sockaddr = u.addrs[0].sockaddr; + r->upstream->resolved->socklen = u.addrs[0].socklen; + r->upstream->resolved->naddrs = 1; + r->upstream->resolved->host = u.addrs[0].name; + + } else { + r->upstream->resolved->host = u.host; + r->upstream->resolved->port = u.port; + } return NGX_OK; } diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c index 2cf009bd9..2bf58ab68 100644 --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -614,10 +614,18 @@ ngx_http_proxy_eval(ngx_http_request_t *r, ngx_http_proxy_ctx_t *ctx, return NGX_ERROR; } - r->upstream->resolved->host = u.host; - r->upstream->resolved->port = (in_port_t) (u.no_port ? u.default_port: - u.port); - r->upstream->resolved->no_port = u.no_port; + if (u.addrs[0].sockaddr) { + r->upstream->resolved->sockaddr = u.addrs[0].sockaddr; + r->upstream->resolved->socklen = u.addrs[0].socklen; + r->upstream->resolved->naddrs = 1; + r->upstream->resolved->host = u.addrs[0].name; + + } else { + r->upstream->resolved->host = u.host; + r->upstream->resolved->port = (in_port_t) (u.no_port ? u.default_port: + u.port); + r->upstream->resolved->no_port = u.no_port; + } return NGX_OK; } diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c index 9a96a1e3c..f567a438e 100644 --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -414,6 +414,20 @@ ngx_http_upstream_init(ngx_http_request_t *r) } else { + if (u->resolved->sockaddr) { + + if (ngx_http_upstream_create_round_robin_peer(r, u->resolved) + != NGX_OK) + { + ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); + return; + } + + ngx_http_upstream_connect(r, u); + + return; + } + host = &u->resolved->host; umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module); diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h index b6f2161d4..3c141276d 100644 --- a/src/http/ngx_http_upstream.h +++ b/src/http/ngx_http_upstream.h @@ -209,8 +209,13 @@ typedef struct { ngx_str_t host; in_port_t port; ngx_uint_t no_port; /* unsigned no_port:1 */ + ngx_uint_t naddrs; in_addr_t *addrs; + + struct sockaddr *sockaddr; + socklen_t socklen; + ngx_resolver_ctx_t *ctx; } ngx_http_upstream_resolved_t; diff --git a/src/http/ngx_http_upstream_round_robin.c b/src/http/ngx_http_upstream_round_robin.c index 2479baa78..52bd80858 100644 --- a/src/http/ngx_http_upstream_round_robin.c +++ b/src/http/ngx_http_upstream_round_robin.c @@ -279,35 +279,47 @@ ngx_http_upstream_create_round_robin_peer(ngx_http_request_t *r, peers->number = ur->naddrs; peers->name = &ur->host; - for (i = 0; i < ur->naddrs; i++) { + if (ur->sockaddr) { + peers->peer[0].sockaddr = ur->sockaddr; + peers->peer[0].socklen = ur->socklen; + peers->peer[0].name = ur->host; + peers->peer[0].weight = 1; + peers->peer[0].current_weight = 1; + peers->peer[0].max_fails = 1; + peers->peer[0].fail_timeout = 10; - len = NGX_INET_ADDRSTRLEN + sizeof(":65536") - 1; + } else { - p = ngx_pnalloc(r->pool, len); - if (p == NULL) { - return NGX_ERROR; + for (i = 0; i < ur->naddrs; i++) { + + len = NGX_INET_ADDRSTRLEN + sizeof(":65536") - 1; + + p = ngx_pnalloc(r->pool, len); + if (p == NULL) { + return NGX_ERROR; + } + + len = ngx_inet_ntop(AF_INET, &ur->addrs[i], p, NGX_INET_ADDRSTRLEN); + len = ngx_sprintf(&p[len], ":%d", ur->port) - p; + + sin = ngx_pcalloc(r->pool, sizeof(struct sockaddr_in)); + if (sin == NULL) { + return NGX_ERROR; + } + + sin->sin_family = AF_INET; + sin->sin_port = htons(ur->port); + sin->sin_addr.s_addr = ur->addrs[i]; + + peers->peer[i].sockaddr = (struct sockaddr *) sin; + peers->peer[i].socklen = sizeof(struct sockaddr_in); + peers->peer[i].name.len = len; + peers->peer[i].name.data = p; + peers->peer[i].weight = 1; + peers->peer[i].current_weight = 1; + peers->peer[i].max_fails = 1; + peers->peer[i].fail_timeout = 10; } - - len = ngx_inet_ntop(AF_INET, &ur->addrs[i], p, NGX_INET_ADDRSTRLEN); - len = ngx_sprintf(&p[len], ":%d", ur->port) - p; - - sin = ngx_pcalloc(r->pool, sizeof(struct sockaddr_in)); - if (sin == NULL) { - return NGX_ERROR; - } - - sin->sin_family = AF_INET; - sin->sin_port = htons(ur->port); - sin->sin_addr.s_addr = ur->addrs[i]; - - peers->peer[i].sockaddr = (struct sockaddr *) sin; - peers->peer[i].socklen = sizeof(struct sockaddr_in); - peers->peer[i].name.len = len; - peers->peer[i].name.data = p; - peers->peer[i].weight = 1; - peers->peer[i].current_weight = 1; - peers->peer[i].max_fails = 1; - peers->peer[i].fail_timeout = 10; } rrp->peers = peers;