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.
@@ -1605,9 +1605,7 @@ PROXY_DECLARE(int) ap_proxy_connection_reusable(proxy_conn_rec *conn)
16051605{
16061606 proxy_worker * worker = conn -> worker ;
16071607
1608- return !(conn -> close
1609- || conn -> forward
1610- || worker -> s -> disablereuse );
1608+ return !(conn -> close || worker -> s -> disablereuse );
16111609}
16121610
16131611static proxy_conn_rec * connection_make (apr_pool_t * p , proxy_worker * worker )
@@ -3331,12 +3329,10 @@ ap_proxy_determine_connection(apr_pool_t *p, request_rec *r,
33313329 uri -> scheme , conn -> uds_path , conn -> hostname , conn -> port );
33323330 }
33333331 else {
3332+ remote_connect_info * connect_info = NULL ;
33343333 const char * hostname = uri -> hostname ;
33353334 apr_port_t hostport = uri -> port ;
33363335
3337- /* Not a remote CONNECT until further notice */
3338- conn -> forward = NULL ;
3339-
33403336 if (proxyname ) {
33413337 hostname = proxyname ;
33423338 hostport = proxyport ;
@@ -3347,7 +3343,6 @@ ap_proxy_determine_connection(apr_pool_t *p, request_rec *r,
33473343 * sending our actual HTTPS requests.
33483344 */
33493345 if (conn -> is_ssl ) {
3350- forward_info * forward ;
33513346 const char * proxy_auth ;
33523347
33533348 /* Do we want to pass Proxy-Authorization along?
@@ -3366,13 +3361,15 @@ ap_proxy_determine_connection(apr_pool_t *p, request_rec *r,
33663361 proxy_auth = NULL ;
33673362 }
33683363
3369- /* Reset forward info if they changed */
3370- if (!(forward = conn -> forward )
3371- || forward -> target_port != uri -> port
3372- || ap_cstr_casecmp (forward -> target_host , uri -> hostname ) != 0
3373- || (forward -> proxy_auth != NULL ) != (proxy_auth != NULL )
3374- || (forward -> proxy_auth != NULL && proxy_auth != NULL &&
3375- strcmp (forward -> proxy_auth , proxy_auth ) != 0 )) {
3364+ /* Save our real backend data for using it later during HTTP CONNECT */
3365+ connect_info = conn -> forward ;
3366+ if (!connect_info
3367+ /* reset connect info if they changed */
3368+ || connect_info -> target_port != uri -> port
3369+ || ap_cstr_casecmp (connect_info -> target_host , uri -> hostname ) != 0
3370+ || (connect_info -> proxy_auth != NULL ) != (proxy_auth != NULL )
3371+ || (connect_info -> proxy_auth != NULL && proxy_auth != NULL &&
3372+ strcmp (connect_info -> proxy_auth , proxy_auth ) != 0 )) {
33763373 apr_pool_t * fwd_pool = conn -> pool ;
33773374 if (worker -> s -> is_address_reusable ) {
33783375 if (conn -> fwd_pool ) {
@@ -3383,26 +3380,24 @@ ap_proxy_determine_connection(apr_pool_t *p, request_rec *r,
33833380 }
33843381 fwd_pool = conn -> fwd_pool ;
33853382 }
3386- forward = apr_pcalloc (fwd_pool , sizeof (forward_info ));
3387- conn -> forward = forward ;
3388-
3389- /*
3390- * Save our real backend data for using it later during HTTP CONNECT.
3391- */
3392- forward -> use_http_connect = 1 ;
3393- forward -> target_host = apr_pstrdup (fwd_pool , uri -> hostname );
3394- forward -> target_port = uri -> port ;
3383+ connect_info = apr_pcalloc (fwd_pool , sizeof (* connect_info ));
3384+ connect_info -> target_host = apr_pstrdup (fwd_pool , uri -> hostname );
3385+ connect_info -> target_port = uri -> port ;
33953386 if (proxy_auth ) {
3396- forward -> proxy_auth = apr_pstrdup (fwd_pool , proxy_auth );
3387+ connect_info -> proxy_auth = apr_pstrdup (fwd_pool , proxy_auth );
33973388 }
3389+ conn -> forward = NULL ;
33983390 }
33993391 }
34003392 }
34013393
3402- if (conn -> hostname
3403- && (conn -> port != hostport
3404- || ap_cstr_casecmp (conn -> hostname , hostname ) != 0 )) {
3394+ /* Close the connection if the remote proxy or origin server don't match */
3395+ if (conn -> forward != connect_info
3396+ || (conn -> hostname
3397+ && (conn -> port != hostport
3398+ || ap_cstr_casecmp (conn -> hostname , hostname ) != 0 ))) {
34053399 conn_cleanup (conn );
3400+ conn -> forward = connect_info ;
34063401 }
34073402
34083403 /* Resolve the connection address with the determined hostname/port */
@@ -3446,9 +3441,8 @@ ap_proxy_determine_connection(apr_pool_t *p, request_rec *r,
34463441 if (dconf -> preserve_host ) {
34473442 ssl_hostname = r -> hostname ;
34483443 }
3449- else if (conn -> forward
3450- && ((forward_info * )(conn -> forward ))-> use_http_connect ) {
3451- ssl_hostname = ((forward_info * )conn -> forward )-> target_host ;
3444+ else if (conn -> forward ) {
3445+ ssl_hostname = ((remote_connect_info * )conn -> forward )-> target_host ;
34523446 }
34533447 else {
34543448 ssl_hostname = conn -> hostname ;
@@ -3545,7 +3539,7 @@ PROXY_DECLARE(int) ap_proxy_is_socket_connected(apr_socket_t *sock)
35453539
35463540
35473541/*
3548- * Send a HTTP CONNECT request to a forward proxy.
3542+ * Send a HTTP CONNECT request to a remote proxy.
35493543 * The proxy is given by "backend", the target server
35503544 * is contained in the "forward" member of "backend".
35513545 */
@@ -3558,24 +3552,24 @@ static apr_status_t send_http_connect(proxy_conn_rec *backend,
35583552 int complete = 0 ;
35593553 char buffer [HUGE_STRING_LEN ];
35603554 char drain_buffer [HUGE_STRING_LEN ];
3561- forward_info * forward = ( forward_info * ) backend -> forward ;
3555+ remote_connect_info * connect_info = backend -> forward ;
35623556 int len = 0 ;
35633557
35643558 ap_log_error (APLOG_MARK , APLOG_DEBUG , 0 , s , APLOGNO (00948 )
35653559 "CONNECT: sending the CONNECT request for %s:%d "
35663560 "to the remote proxy %pI (%s)" ,
3567- forward -> target_host , forward -> target_port ,
3561+ connect_info -> target_host , connect_info -> target_port ,
35683562 backend -> addr , backend -> hostname );
35693563 /* Create the CONNECT request */
35703564 nbytes = apr_snprintf (buffer , sizeof (buffer ),
35713565 "CONNECT %s:%d HTTP/1.0" CRLF ,
3572- forward -> target_host , forward -> target_port );
3566+ connect_info -> target_host , connect_info -> target_port );
35733567 /* Add proxy authorization from the configuration, or initial
35743568 * request if necessary */
3575- if (forward -> proxy_auth != NULL ) {
3569+ if (connect_info -> proxy_auth != NULL ) {
35763570 nbytes += apr_snprintf (buffer + nbytes , sizeof (buffer ) - nbytes ,
35773571 "Proxy-Authorization: %s" CRLF ,
3578- forward -> proxy_auth );
3572+ connect_info -> proxy_auth );
35793573 }
35803574 /* Set a reasonable agent and send everything */
35813575 nbytes += apr_snprintf (buffer + nbytes , sizeof (buffer ) - nbytes ,
@@ -3619,7 +3613,7 @@ static apr_status_t send_http_connect(proxy_conn_rec *backend,
36193613 char code_str [4 ];
36203614
36213615 ap_log_error (APLOG_MARK , APLOG_DEBUG , 0 , s , APLOGNO (00949 )
3622- "send_http_connect: response from the forward proxy: %s" ,
3616+ "send_http_connect: response from the remote proxy: %s" ,
36233617 buffer );
36243618
36253619 /* Extract the returned code */
@@ -3630,7 +3624,7 @@ static apr_status_t send_http_connect(proxy_conn_rec *backend,
36303624 }
36313625 else {
36323626 ap_log_error (APLOG_MARK , APLOG_ERR , 0 , s , APLOGNO (00950 )
3633- "send_http_connect: the forward proxy returned code is '%s'" ,
3627+ "send_http_connect: the remote proxy returned code is '%s'" ,
36343628 code_str );
36353629 status = APR_INCOMPLETE ;
36363630 }
@@ -3794,7 +3788,7 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function,
37943788{
37953789 apr_status_t rv ;
37963790 int loglevel ;
3797- forward_info * forward = conn -> forward ;
3791+ remote_connect_info * connect_info = conn -> forward ;
37983792 apr_sockaddr_t * backend_addr ;
37993793 /* the local address to use for the outgoing connection */
38003794 apr_sockaddr_t * local_addr ;
@@ -3995,27 +3989,25 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function,
39953989
39963990 conn -> sock = newsock ;
39973991
3998- if (forward && forward -> use_http_connect ) {
3999- /*
4000- * For HTTP CONNECT we need to prepend CONNECT request before
4001- * sending our actual HTTPS requests.
4002- */
4003- {
4004- rv = send_http_connect (conn , s );
4005- /* If an error occurred, loop round and try again */
4006- if (rv != APR_SUCCESS ) {
4007- conn -> sock = NULL ;
4008- apr_socket_close (newsock );
4009- loglevel = backend_addr -> next ? APLOG_DEBUG : APLOG_ERR ;
4010- ap_log_error (APLOG_MARK , loglevel , rv , s , APLOGNO (00958 )
4011- "%s: attempt to connect to %s:%hu "
4012- "via http CONNECT through %pI (%s:%hu) failed" ,
4013- proxy_function ,
4014- forward -> target_host , forward -> target_port ,
4015- backend_addr , conn -> hostname , conn -> port );
4016- backend_addr = backend_addr -> next ;
4017- continue ;
4018- }
3992+ /*
3993+ * For HTTP CONNECT we need to prepend CONNECT request before
3994+ * sending our actual HTTPS requests.
3995+ */
3996+ if (connect_info ) {
3997+ rv = send_http_connect (conn , s );
3998+ /* If an error occurred, loop round and try again */
3999+ if (rv != APR_SUCCESS ) {
4000+ conn -> sock = NULL ;
4001+ apr_socket_close (newsock );
4002+ loglevel = backend_addr -> next ? APLOG_DEBUG : APLOG_ERR ;
4003+ ap_log_error (APLOG_MARK , loglevel , rv , s , APLOGNO (00958 )
4004+ "%s: attempt to connect to %s:%hu "
4005+ "via http CONNECT through %pI (%s:%hu) failed" ,
4006+ proxy_function ,
4007+ connect_info -> target_host , connect_info -> target_port ,
4008+ backend_addr , conn -> hostname , conn -> port );
4009+ backend_addr = backend_addr -> next ;
4010+ continue ;
40194011 }
40204012 }
40214013 }
0 commit comments