Skip to content

Commit 854ff61

Browse files
authored
Merge pull request chobits#103 from chobits/for_pull_request
proxy_connect_address: support dynamic domain resolving
2 parents ddbcf6e + 5398310 commit 854ff61

File tree

2 files changed

+104
-176
lines changed

2 files changed

+104
-176
lines changed

ngx_http_proxy_connect_module.c

Lines changed: 95 additions & 176 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ typedef struct {
3535
size_t send_lowat;
3636
size_t buffer_size;
3737

38-
ngx_http_proxy_connect_address_t *address;
38+
ngx_http_complex_value_t *address;
3939
ngx_http_proxy_connect_address_t *local;
4040
} ngx_http_proxy_connect_loc_conf_t;
4141

@@ -100,18 +100,16 @@ static void ngx_http_proxy_connect_read_downstream(ngx_http_request_t *r);
100100
static void ngx_http_proxy_connect_send_handler(ngx_http_request_t *r);
101101
static ngx_int_t ngx_http_proxy_connect_allow_handler(ngx_http_request_t *r,
102102
ngx_http_proxy_connect_loc_conf_t *plcf);
103-
static char* ngx_http_proxy_connect_address(ngx_conf_t *cf, ngx_command_t *cmd,
104-
void *conf);
105103
static char* ngx_http_proxy_connect_bind(ngx_conf_t *cf, ngx_command_t *cmd,
106104
void *conf);
107105
static ngx_int_t ngx_http_proxy_connect_set_local(ngx_http_request_t *r,
108106
ngx_http_proxy_connect_upstream_t *u, ngx_http_proxy_connect_address_t *local);
109-
static ngx_int_t ngx_http_proxy_connect_set_address(ngx_http_request_t *r,
110-
ngx_http_proxy_connect_upstream_t *u, ngx_http_proxy_connect_address_t *address);
111107
static ngx_int_t ngx_http_proxy_connect_variable_get_time(ngx_http_request_t *r,
112108
ngx_http_variable_value_t *v, uintptr_t data);
113109
static void ngx_http_proxy_connect_variable_set_time(ngx_http_request_t *r,
114110
ngx_http_variable_value_t *v, uintptr_t data);
111+
static ngx_int_t ngx_http_proxy_connect_sock_ntop(ngx_http_request_t *r,
112+
ngx_http_proxy_connect_upstream_t *u);
115113

116114

117115

@@ -161,7 +159,7 @@ static ngx_command_t ngx_http_proxy_connect_commands[] = {
161159

162160
{ ngx_string("proxy_connect_address"),
163161
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
164-
ngx_http_proxy_connect_address,
162+
ngx_http_set_complex_value_slot,
165163
NGX_HTTP_LOC_CONF_OFFSET,
166164
offsetof(ngx_http_proxy_connect_loc_conf_t, address),
167165
NULL },
@@ -1386,11 +1384,27 @@ ngx_http_proxy_connect_handler(ngx_http_request_t *r)
13861384

13871385
ngx_memzero(&url, sizeof(ngx_url_t));
13881386

1389-
url.url.len = r->connect_host.len;
1390-
url.url.data = r->connect_host.data;
1387+
if (plcf->address) {
1388+
if (ngx_http_complex_value(r, plcf->address, &url.url) != NGX_OK) {
1389+
return NGX_HTTP_INTERNAL_SERVER_ERROR;
1390+
}
1391+
1392+
if (url.url.len == 0 || url.url.data == NULL) {
1393+
url.url.len = r->connect_host.len;
1394+
url.url.data = r->connect_host.data;
1395+
}
1396+
1397+
} else {
1398+
url.url.len = r->connect_host.len;
1399+
url.url.data = r->connect_host.data;
1400+
}
1401+
13911402
url.default_port = r->connect_port_n;
13921403
url.no_resolve = 1;
13931404

1405+
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1406+
"connect handler: parse url: %V" , &url);
1407+
13941408
if (ngx_parse_url(r->pool, &url) != NGX_OK) {
13951409
if (url.err) {
13961410
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
@@ -1404,55 +1418,53 @@ ngx_http_proxy_connect_handler(ngx_http_request_t *r)
14041418
r->read_event_handler = ngx_http_proxy_connect_rd_check_broken_connection;
14051419
r->write_event_handler = ngx_http_proxy_connect_wr_check_broken_connection;
14061420

1421+
/* NOTE:
1422+
* We use only one address in u->resolved,
1423+
* and u->resolved.host is "<address:port>" format.
1424+
*/
1425+
14071426
u->resolved = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_resolved_t));
14081427
if (u->resolved == NULL) {
14091428
return NGX_HTTP_INTERNAL_SERVER_ERROR;
14101429
}
14111430

1412-
rc = ngx_http_proxy_connect_set_address(r, u, plcf->address);
1413-
1414-
if (rc == NGX_ERROR) {
1415-
return NGX_HTTP_INTERNAL_SERVER_ERROR;
1416-
}
1417-
1418-
if (rc == NGX_OK) {
1419-
1420-
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1421-
"connect network address given by proxy_connect_address");
1422-
1423-
r->main->count++;
1424-
1425-
ngx_http_proxy_connect_process_connect(r, u);
1426-
1427-
return NGX_DONE;
1428-
}
1429-
14301431
/* rc = NGX_DECLINED */
14311432

1432-
if (url.addrs && url.addrs[0].sockaddr) {
1433+
if (url.addrs) {
14331434
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
14341435
"connect network address given directly");
14351436

14361437
u->resolved->sockaddr = url.addrs[0].sockaddr;
14371438
u->resolved->socklen = url.addrs[0].socklen;
1439+
#if defined(nginx_version) && nginx_version >= 1011007
1440+
u->resolved->name = url.addrs[0].name;
1441+
#endif
14381442
u->resolved->naddrs = 1;
1439-
u->resolved->host = url.addrs[0].name;
1440-
1441-
} else {
1442-
u->resolved->host = r->connect_host;
1443-
u->resolved->port = (in_port_t) r->connect_port_n;
14441443
}
14451444

1445+
u->resolved->host = url.host;
1446+
u->resolved->port = (in_port_t) (url.no_port ? r->connect_port_n : url.port);
1447+
u->resolved->no_port = url.no_port;
1448+
14461449
if (u->resolved->sockaddr) {
1450+
1451+
rc = ngx_http_proxy_connect_sock_ntop(r, u);
1452+
1453+
if (rc != NGX_OK) {
1454+
return rc;
1455+
}
1456+
14471457
r->main->count++;
14481458

14491459
ngx_http_proxy_connect_process_connect(r, u);
14501460

14511461
return NGX_DONE;
14521462
}
14531463

1454-
temp.name = r->connect_host;
1464+
ngx_str_t *host = &url.host;
1465+
14551466
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1467+
temp.name = *host;
14561468

14571469
rctx = ngx_resolve_start(clcf->resolver, &temp);
14581470
if (rctx == NULL) {
@@ -1467,7 +1479,7 @@ ngx_http_proxy_connect_handler(ngx_http_request_t *r)
14671479
return NGX_HTTP_BAD_GATEWAY;
14681480
}
14691481

1470-
rctx->name = r->connect_host;
1482+
rctx->name = *host;
14711483
#if !defined(nginx_version) || nginx_version < 1005008
14721484
rctx->type = NGX_RESOLVE_A;
14731485
#endif
@@ -1492,6 +1504,45 @@ ngx_http_proxy_connect_handler(ngx_http_request_t *r)
14921504
}
14931505

14941506

1507+
static ngx_int_t
1508+
ngx_http_proxy_connect_sock_ntop(ngx_http_request_t *r,
1509+
ngx_http_proxy_connect_upstream_t *u)
1510+
{
1511+
u_char *p;
1512+
ngx_int_t len;
1513+
ngx_http_upstream_resolved_t *ur;
1514+
1515+
ur = u->resolved;
1516+
1517+
/* fix u->resolved->host to "<address:port>" format */
1518+
1519+
#if defined(nginx_version) && nginx_version >= 1005008
1520+
p = ngx_pnalloc(r->pool, NGX_SOCKADDR_STRLEN);
1521+
if (p == NULL) {
1522+
return NGX_HTTP_INTERNAL_SERVER_ERROR;
1523+
}
1524+
1525+
len = ngx_sock_ntop(ur->sockaddr, ur->socklen, p, NGX_SOCKADDR_STRLEN, 1);
1526+
#else
1527+
/* for nginx older than 1.5.8 */
1528+
1529+
len = NGX_INET_ADDRSTRLEN + sizeof(":65536") - 1;
1530+
1531+
p = ngx_pnalloc(r->pool, len + sizeof(struct sockaddr_in));
1532+
if (p == NULL) {
1533+
return NGX_HTTP_INTERNAL_SERVER_ERROR;
1534+
}
1535+
1536+
len = ngx_inet_ntop(AF_INET, ur->sockaddr, p, NGX_INET_ADDRSTRLEN);
1537+
len = ngx_sprintf(&p[len], ":%d", ur->port) - p;
1538+
#endif
1539+
u->resolved->host.data = p;
1540+
u->resolved->host.len = len;
1541+
1542+
return NGX_OK;
1543+
}
1544+
1545+
14951546
static ngx_int_t
14961547
ngx_http_proxy_connect_allow_handler(ngx_http_request_t *r,
14971548
ngx_http_proxy_connect_loc_conf_t *plcf)
@@ -1623,84 +1674,6 @@ ngx_http_proxy_connect(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
16231674
}
16241675

16251676

1626-
char *
1627-
ngx_http_proxy_connect_address(ngx_conf_t *cf, ngx_command_t *cmd,
1628-
void *conf)
1629-
{
1630-
char *p = conf;
1631-
1632-
ngx_int_t rc;
1633-
ngx_str_t *value;
1634-
ngx_http_complex_value_t cv;
1635-
ngx_http_proxy_connect_address_t **paddress, *address;
1636-
ngx_http_compile_complex_value_t ccv;
1637-
1638-
paddress = (ngx_http_proxy_connect_address_t **) (p + cmd->offset);
1639-
1640-
if (*paddress != NGX_CONF_UNSET_PTR) {
1641-
return "is duplicate";
1642-
}
1643-
1644-
value = cf->args->elts;
1645-
1646-
if (ngx_strcmp(value[1].data, "off") == 0) {
1647-
*paddress = NULL;
1648-
return NGX_CONF_OK;
1649-
}
1650-
1651-
ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
1652-
1653-
ccv.cf = cf;
1654-
ccv.value = &value[1];
1655-
ccv.complex_value = &cv;
1656-
1657-
if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
1658-
return NGX_CONF_ERROR;
1659-
}
1660-
1661-
address = ngx_pcalloc(cf->pool, sizeof(ngx_http_proxy_connect_address_t));
1662-
if (address == NULL) {
1663-
return NGX_CONF_ERROR;
1664-
}
1665-
1666-
*paddress = address;
1667-
1668-
if (cv.lengths) {
1669-
address->value = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t));
1670-
if (address->value == NULL) {
1671-
return NGX_CONF_ERROR;
1672-
}
1673-
1674-
*address->value = cv;
1675-
1676-
} else {
1677-
address->addr = ngx_palloc(cf->pool, sizeof(ngx_addr_t));
1678-
if (address->addr == NULL) {
1679-
return NGX_CONF_ERROR;
1680-
}
1681-
1682-
rc = __ngx_parse_addr_port(cf->pool, address->addr, value[1].data,
1683-
value[1].len);
1684-
1685-
switch (rc) {
1686-
case NGX_OK:
1687-
address->addr->name = value[1];
1688-
break;
1689-
1690-
case NGX_DECLINED:
1691-
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1692-
"invalid address \"%V\"", &value[1]);
1693-
/* fall through */
1694-
1695-
default:
1696-
return NGX_CONF_ERROR;
1697-
}
1698-
}
1699-
1700-
return NGX_CONF_OK;
1701-
}
1702-
1703-
17041677
char *
17051678
ngx_http_proxy_connect_bind(ngx_conf_t *cf, ngx_command_t *cmd,
17061679
void *conf)
@@ -1848,68 +1821,6 @@ ngx_http_proxy_connect_set_local(ngx_http_request_t *r,
18481821
}
18491822

18501823

1851-
static ngx_int_t
1852-
ngx_http_proxy_connect_set_address(ngx_http_request_t *r,
1853-
ngx_http_proxy_connect_upstream_t *u, ngx_http_proxy_connect_address_t *address)
1854-
{
1855-
ngx_int_t rc;
1856-
ngx_str_t val;
1857-
ngx_addr_t *addr;
1858-
1859-
if (address == NULL) {
1860-
return NGX_DECLINED;
1861-
}
1862-
1863-
if (address->value == NULL) {
1864-
1865-
u->resolved->naddrs = 1;
1866-
u->resolved->addrs = NULL;
1867-
u->resolved->sockaddr = address->addr->sockaddr;
1868-
u->resolved->socklen = address->addr->socklen;
1869-
#if defined(nginx_version) && nginx_version >= 1011007
1870-
u->resolved->name = address->addr->name;
1871-
#endif
1872-
u->resolved->host = address->addr->name;
1873-
1874-
return NGX_OK;
1875-
}
1876-
1877-
if (ngx_http_complex_value(r, address->value, &val) != NGX_OK) {
1878-
return NGX_ERROR;
1879-
}
1880-
1881-
if (val.len == 0) {
1882-
return NGX_DECLINED;
1883-
}
1884-
1885-
addr = ngx_palloc(r->pool, sizeof(ngx_addr_t));
1886-
if (addr == NULL) {
1887-
return NGX_ERROR;
1888-
}
1889-
1890-
rc = __ngx_parse_addr_port(r->pool, addr, val.data, val.len);
1891-
if (rc == NGX_ERROR) {
1892-
return NGX_ERROR;
1893-
}
1894-
1895-
if (rc != NGX_OK) {
1896-
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1897-
"invalid proxy connect address \"%V\"", &val);
1898-
return NGX_DECLINED;
1899-
}
1900-
1901-
addr->name = val;
1902-
u->resolved->sockaddr = addr->sockaddr;
1903-
u->resolved->socklen = addr->socklen;
1904-
#if defined(nginx_version) && nginx_version >= 1011007
1905-
u->resolved->name = addr->name;
1906-
#endif
1907-
u->resolved->naddrs = 1;
1908-
1909-
return NGX_OK;
1910-
}
1911-
1912-
19131824
static void *
19141825
ngx_http_proxy_connect_create_loc_conf(ngx_conf_t *cf)
19151826
{
@@ -1920,6 +1831,12 @@ ngx_http_proxy_connect_create_loc_conf(ngx_conf_t *cf)
19201831
return NULL;
19211832
}
19221833

1834+
/*
1835+
* set by ngx_pcalloc():
1836+
*
1837+
* conf->address = NULL;
1838+
*/
1839+
19231840
conf->accept_connect = NGX_CONF_UNSET;
19241841
conf->allow_port_all = NGX_CONF_UNSET;
19251842
conf->allow_ports = NGX_CONF_UNSET_PTR;
@@ -1931,7 +1848,6 @@ ngx_http_proxy_connect_create_loc_conf(ngx_conf_t *cf)
19311848
conf->send_lowat = NGX_CONF_UNSET_SIZE;
19321849
conf->buffer_size = NGX_CONF_UNSET_SIZE;
19331850

1934-
conf->address = NGX_CONF_UNSET_PTR;
19351851
conf->local = NGX_CONF_UNSET_PTR;
19361852

19371853
return conf;
@@ -1959,7 +1875,10 @@ ngx_http_proxy_connect_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
19591875

19601876
ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size, 16384);
19611877

1962-
ngx_conf_merge_ptr_value(conf->address, prev->address, NULL);
1878+
if (conf->address == NULL) {
1879+
conf->address = prev->address;
1880+
}
1881+
19631882
ngx_conf_merge_ptr_value(conf->local, prev->local, NULL);
19641883

19651884
return NGX_CONF_OK;

0 commit comments

Comments
 (0)