@@ -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);
100100static void ngx_http_proxy_connect_send_handler (ngx_http_request_t * r );
101101static 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 );
105103static char * ngx_http_proxy_connect_bind (ngx_conf_t * cf , ngx_command_t * cmd ,
106104 void * conf );
107105static 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 );
111107static 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 );
113109static 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+
14951546static ngx_int_t
14961547ngx_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-
17041677char *
17051678ngx_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-
19131824static void *
19141825ngx_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