@@ -658,6 +658,15 @@ static const char *oidc_http_user_agent(request_rec *r) {
658658 return s_useragent ;
659659}
660660
661+ #define OIDC_CURL_INTERFACE_ENV_VAR "OIDC_CURL_INTERFACE"
662+
663+ /*
664+ * construct our local address/interface for outgoing requests
665+ */
666+ static const char * oidc_http_interface (request_rec * r ) {
667+ return apr_table_get (r -> subprocess_env , OIDC_CURL_INTERFACE_ENV_VAR );
668+ }
669+
661670/*
662671 * execute a HTTP (GET or POST) request
663672 */
@@ -755,10 +764,24 @@ static apr_byte_t oidc_http_request(request_rec *r, const char *url, const char
755764#endif
756765
757766 /* identify this HTTP client */
758- const char * useragent = oidc_http_user_agent (r );
759- if ((useragent != NULL ) && (_oidc_strcmp (useragent , "" ) != 0 )) {
760- oidc_debug (r , "set HTTP request header User-Agent to: %s" , useragent );
761- curl_easy_setopt (curl , CURLOPT_USERAGENT , useragent );
767+ const char * s_useragent = oidc_http_user_agent (r );
768+ if ((s_useragent != NULL ) && (_oidc_strcmp (s_useragent , "" ) != 0 )) {
769+ oidc_debug (r , "set HTTP request header User-Agent to: %s" , s_useragent );
770+ curl_easy_setopt (curl , CURLOPT_USERAGENT , s_useragent );
771+ }
772+
773+ /* set the local interface if defined */
774+ const char * s_interface = oidc_http_interface (r );
775+ if ((s_interface != NULL ) && (_oidc_strcmp (s_interface , "" ) != 0 )) {
776+ #if LIBCURL_VERSION_NUM >= 0x073000
777+ oidc_debug (r , "set local interface to: %s" , s_interface );
778+ if (curl_easy_setopt (curl , CURLOPT_INTERFACE , s_interface ) != CURLE_OK )
779+ oidc_warn (r , "could not set local interface to: %s" , s_interface );
780+ #else
781+ oidc_warn (
782+ r , "local interface is configured to %s, but the cURL version in use does not support setting this" ,
783+ s_interface );
784+ #endif
762785 }
763786
764787 /* set optional outgoing proxy for the local network */
@@ -850,7 +873,8 @@ static apr_byte_t oidc_http_request(request_rec *r, const char *url, const char
850873 break ;
851874 }
852875 if (res == CURLE_OPERATION_TIMEDOUT ) {
853- /* in case of a request/transfer timeout (which includes the connect timeout) we'll not retry */
876+ /* in case of a request/transfer timeout (which includes the connect timeout) we'll not
877+ * retry */
854878 oidc_error (r , "curl_easy_perform failed with a timeout for %s: [%s]; won't retry" , url ,
855879 curl_err [0 ] ? curl_err : "<n/a>" );
856880 OIDC_METRICS_COUNTER_INC_SPEC (r , c , OM_PROVIDER_CONNECT_ERROR ,
@@ -1052,13 +1076,13 @@ void oidc_http_set_cookie(request_rec *r, const char *cookieName, const char *co
10521076 /* sanity check on overall cookie value size */
10531077 if (_oidc_strlen (headerString ) > OIDC_HTTP_COOKIE_MAX_SIZE ) {
10541078 oidc_warn (r ,
1055- "the length of the cookie value (%d) is greater than %d(!) bytes, this may not work with all "
1056- "browsers/server combinations: consider switching to a server side caching!" ,
1079+ "the length of the cookie value (%d) is greater than %d(!) bytes, this may not work "
1080+ "with all browsers/server combinations: consider switching to a server side caching!" ,
10571081 (int )_oidc_strlen (headerString ), OIDC_HTTP_COOKIE_MAX_SIZE );
10581082 }
10591083
1060- /* use r->err_headers_out so we always print our headers (even on 302 redirect) - headers_out only prints on 2xx
1061- * responses */
1084+ /* use r->err_headers_out so we always print our headers (even on 302 redirect) - headers_out only
1085+ * prints on 2xx responses */
10621086 oidc_http_hdr_err_out_add (r , OIDC_HTTP_HDR_SET_COOKIE , headerString );
10631087}
10641088
0 commit comments