4545APLOG_USE_MODULE (proxy );
4646
4747/*
48- * Opaque structure containing target server info when
49- * using a forward proxy.
50- * Up to now only used in combination with HTTP CONNECT to ProxyRemote
48+ * Opaque structure containing infos for CONNECT-ing an origin server through a
49+ * remote (forward) proxy. Saved in the (opaque) proxy_conn_rec::forward pointer
50+ * field for backend connections kept alive, allowing for reuse when subsequent
51+ * requests should be routed through the same remote proxy.
5152 */
5253typedef struct {
53- int use_http_connect ; /* Use SSL Tunneling via HTTP CONNECT */
54- const char * target_host ; /* Target hostname */
55- apr_port_t target_port ; /* Target port */
5654 const char * proxy_auth ; /* Proxy authorization */
57- } forward_info ;
55+ const char * target_host ; /* Target/origin hostname */
56+ apr_port_t target_port ; /* Target/origin port */
57+ } remote_connect_info ;
5858
5959/*
6060 * Opaque structure containing a refcounted and TTL'ed address.
@@ -1608,9 +1608,7 @@ PROXY_DECLARE(int) ap_proxy_connection_reusable(proxy_conn_rec *conn)
16081608{
16091609 proxy_worker * worker = conn -> worker ;
16101610
1611- return !(conn -> close
1612- || conn -> forward
1613- || worker -> s -> disablereuse );
1611+ return !(conn -> close || worker -> s -> disablereuse );
16141612}
16151613
16161614static proxy_conn_rec * connection_make (apr_pool_t * p , proxy_worker * worker )
@@ -3329,12 +3327,10 @@ ap_proxy_determine_connection(apr_pool_t *p, request_rec *r,
33293327 uri -> scheme , conn -> uds_path , conn -> hostname , conn -> port );
33303328 }
33313329 else {
3330+ remote_connect_info * connect_info = NULL ;
33323331 const char * hostname = uri -> hostname ;
33333332 apr_port_t hostport = uri -> port ;
33343333
3335- /* Not a remote CONNECT until further notice */
3336- conn -> forward = NULL ;
3337-
33383334 if (proxyname ) {
33393335 hostname = proxyname ;
33403336 hostport = proxyport ;
@@ -3345,7 +3341,6 @@ ap_proxy_determine_connection(apr_pool_t *p, request_rec *r,
33453341 * sending our actual HTTPS requests.
33463342 */
33473343 if (conn -> is_ssl ) {
3348- forward_info * forward ;
33493344 const char * proxy_auth ;
33503345
33513346 /* Do we want to pass Proxy-Authorization along?
@@ -3364,13 +3359,15 @@ ap_proxy_determine_connection(apr_pool_t *p, request_rec *r,
33643359 proxy_auth = NULL ;
33653360 }
33663361
3367- /* Reset forward info if they changed */
3368- if (!(forward = conn -> forward )
3369- || forward -> target_port != uri -> port
3370- || ap_cstr_casecmp (forward -> target_host , uri -> hostname ) != 0
3371- || (forward -> proxy_auth != NULL ) != (proxy_auth != NULL )
3372- || (forward -> proxy_auth != NULL && proxy_auth != NULL &&
3373- strcmp (forward -> proxy_auth , proxy_auth ) != 0 )) {
3362+ /* Save our real backend data for using it later during HTTP CONNECT */
3363+ connect_info = conn -> forward ;
3364+ if (!connect_info
3365+ /* reset connect info if they changed */
3366+ || connect_info -> target_port != uri -> port
3367+ || ap_cstr_casecmp (connect_info -> target_host , uri -> hostname ) != 0
3368+ || (connect_info -> proxy_auth != NULL ) != (proxy_auth != NULL )
3369+ || (connect_info -> proxy_auth != NULL && proxy_auth != NULL &&
3370+ strcmp (connect_info -> proxy_auth , proxy_auth ) != 0 )) {
33743371 apr_pool_t * fwd_pool = conn -> pool ;
33753372 if (worker -> s -> is_address_reusable ) {
33763373 if (conn -> fwd_pool ) {
@@ -3381,26 +3378,23 @@ ap_proxy_determine_connection(apr_pool_t *p, request_rec *r,
33813378 }
33823379 fwd_pool = conn -> fwd_pool ;
33833380 }
3384- forward = apr_pcalloc (fwd_pool , sizeof (forward_info ));
3385- conn -> forward = forward ;
3386-
3387- /*
3388- * Save our real backend data for using it later during HTTP CONNECT.
3389- */
3390- forward -> use_http_connect = 1 ;
3391- forward -> target_host = apr_pstrdup (fwd_pool , uri -> hostname );
3392- forward -> target_port = uri -> port ;
3381+ connect_info = apr_pcalloc (fwd_pool , sizeof (* connect_info ));
3382+ connect_info -> target_host = apr_pstrdup (fwd_pool , uri -> hostname );
3383+ connect_info -> target_port = uri -> port ;
33933384 if (proxy_auth ) {
3394- forward -> proxy_auth = apr_pstrdup (fwd_pool , proxy_auth );
3385+ connect_info -> proxy_auth = apr_pstrdup (fwd_pool , proxy_auth );
33953386 }
33963387 }
33973388 }
33983389 }
33993390
3400- if (conn -> hostname
3401- && (conn -> port != hostport
3402- || ap_cstr_casecmp (conn -> hostname , hostname ) != 0 )) {
3391+ /* Don't reuse a connection to a different remote proxy or origin server */
3392+ if (conn -> forward != connect_info
3393+ || (conn -> hostname
3394+ && (conn -> port != hostport
3395+ || ap_cstr_casecmp (conn -> hostname , hostname ) != 0 ))) {
34033396 conn_cleanup (conn );
3397+ conn -> forward = connect_info ;
34043398 }
34053399
34063400 /* Resolve the connection address with the determined hostname/port */
@@ -3444,9 +3438,8 @@ ap_proxy_determine_connection(apr_pool_t *p, request_rec *r,
34443438 if (dconf -> preserve_host ) {
34453439 ssl_hostname = r -> hostname ;
34463440 }
3447- else if (conn -> forward
3448- && ((forward_info * )(conn -> forward ))-> use_http_connect ) {
3449- ssl_hostname = ((forward_info * )conn -> forward )-> target_host ;
3441+ else if (conn -> forward ) {
3442+ ssl_hostname = ((remote_connect_info * )conn -> forward )-> target_host ;
34503443 }
34513444 else {
34523445 ssl_hostname = conn -> hostname ;
@@ -3543,7 +3536,7 @@ PROXY_DECLARE(int) ap_proxy_is_socket_connected(apr_socket_t *sock)
35433536
35443537
35453538/*
3546- * Send a HTTP CONNECT request to a forward proxy.
3539+ * Send a HTTP CONNECT request to a remote proxy.
35473540 * The proxy is given by "backend", the target server
35483541 * is contained in the "forward" member of "backend".
35493542 */
@@ -3556,24 +3549,24 @@ static apr_status_t send_http_connect(proxy_conn_rec *backend,
35563549 int complete = 0 ;
35573550 char buffer [HUGE_STRING_LEN ];
35583551 char drain_buffer [HUGE_STRING_LEN ];
3559- forward_info * forward = ( forward_info * ) backend -> forward ;
3552+ remote_connect_info * connect_info = backend -> forward ;
35603553 int len = 0 ;
35613554
35623555 ap_log_error (APLOG_MARK , APLOG_DEBUG , 0 , s , APLOGNO (00948 )
35633556 "CONNECT: sending the CONNECT request for %s:%d "
35643557 "to the remote proxy %pI (%s)" ,
3565- forward -> target_host , forward -> target_port ,
3558+ connect_info -> target_host , connect_info -> target_port ,
35663559 backend -> addr , backend -> hostname );
35673560 /* Create the CONNECT request */
35683561 nbytes = apr_snprintf (buffer , sizeof (buffer ),
35693562 "CONNECT %s:%d HTTP/1.0" CRLF ,
3570- forward -> target_host , forward -> target_port );
3563+ connect_info -> target_host , connect_info -> target_port );
35713564 /* Add proxy authorization from the configuration, or initial
35723565 * request if necessary */
3573- if (forward -> proxy_auth != NULL ) {
3566+ if (connect_info -> proxy_auth != NULL ) {
35743567 nbytes += apr_snprintf (buffer + nbytes , sizeof (buffer ) - nbytes ,
35753568 "Proxy-Authorization: %s" CRLF ,
3576- forward -> proxy_auth );
3569+ connect_info -> proxy_auth );
35773570 }
35783571 /* Set a reasonable agent and send everything */
35793572 nbytes += apr_snprintf (buffer + nbytes , sizeof (buffer ) - nbytes ,
@@ -3617,7 +3610,7 @@ static apr_status_t send_http_connect(proxy_conn_rec *backend,
36173610 char code_str [4 ];
36183611
36193612 ap_log_error (APLOG_MARK , APLOG_DEBUG , 0 , s , APLOGNO (00949 )
3620- "send_http_connect: response from the forward proxy: %s" ,
3613+ "send_http_connect: response from the remote proxy: %s" ,
36213614 buffer );
36223615
36233616 /* Extract the returned code */
@@ -3628,7 +3621,7 @@ static apr_status_t send_http_connect(proxy_conn_rec *backend,
36283621 }
36293622 else {
36303623 ap_log_error (APLOG_MARK , APLOG_ERR , 0 , s , APLOGNO (00950 )
3631- "send_http_connect: the forward proxy returned code is '%s'" ,
3624+ "send_http_connect: the remote proxy returned code is '%s'" ,
36323625 code_str );
36333626 status = APR_INCOMPLETE ;
36343627 }
@@ -3792,7 +3785,7 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function,
37923785{
37933786 apr_status_t rv ;
37943787 int loglevel ;
3795- forward_info * forward = conn -> forward ;
3788+ remote_connect_info * connect_info = conn -> forward ;
37963789 apr_sockaddr_t * backend_addr ;
37973790 /* the local address to use for the outgoing connection */
37983791 apr_sockaddr_t * local_addr ;
@@ -3993,27 +3986,25 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function,
39933986
39943987 conn -> sock = newsock ;
39953988
3996- if (forward && forward -> use_http_connect ) {
3997- /*
3998- * For HTTP CONNECT we need to prepend CONNECT request before
3999- * sending our actual HTTPS requests.
4000- */
4001- {
4002- rv = send_http_connect (conn , s );
4003- /* If an error occurred, loop round and try again */
4004- if (rv != APR_SUCCESS ) {
4005- conn -> sock = NULL ;
4006- apr_socket_close (newsock );
4007- loglevel = backend_addr -> next ? APLOG_DEBUG : APLOG_ERR ;
4008- ap_log_error (APLOG_MARK , loglevel , rv , s , APLOGNO (00958 )
4009- "%s: attempt to connect to %s:%hu "
4010- "via http CONNECT through %pI (%s:%hu) failed" ,
4011- proxy_function ,
4012- forward -> target_host , forward -> target_port ,
4013- backend_addr , conn -> hostname , conn -> port );
4014- backend_addr = backend_addr -> next ;
4015- continue ;
4016- }
3989+ /*
3990+ * For HTTP CONNECT we need to prepend CONNECT request before
3991+ * sending our actual HTTPS requests.
3992+ */
3993+ if (connect_info ) {
3994+ rv = send_http_connect (conn , s );
3995+ /* If an error occurred, loop round and try again */
3996+ if (rv != APR_SUCCESS ) {
3997+ conn -> sock = NULL ;
3998+ apr_socket_close (newsock );
3999+ loglevel = backend_addr -> next ? APLOG_DEBUG : APLOG_ERR ;
4000+ ap_log_error (APLOG_MARK , loglevel , rv , s , APLOGNO (00958 )
4001+ "%s: attempt to connect to %s:%hu "
4002+ "via http CONNECT through %pI (%s:%hu) failed" ,
4003+ proxy_function ,
4004+ connect_info -> target_host , connect_info -> target_port ,
4005+ backend_addr , conn -> hostname , conn -> port );
4006+ backend_addr = backend_addr -> next ;
4007+ continue ;
40174008 }
40184009 }
40194010 }
0 commit comments