class-wp-http-proxy.php (5863B)
1 <?php 2 /** 3 * HTTP API: WP_HTTP_Proxy class 4 * 5 * @package WordPress 6 * @subpackage HTTP 7 * @since 4.4.0 8 */ 9 10 /** 11 * Core class used to implement HTTP API proxy support. 12 * 13 * There are caveats to proxy support. It requires that defines be made in the wp-config.php file to 14 * enable proxy support. There are also a few filters that plugins can hook into for some of the 15 * constants. 16 * 17 * Please note that only BASIC authentication is supported by most transports. 18 * cURL MAY support more methods (such as NTLM authentication) depending on your environment. 19 * 20 * The constants are as follows: 21 * <ol> 22 * <li>WP_PROXY_HOST - Enable proxy support and host for connecting.</li> 23 * <li>WP_PROXY_PORT - Proxy port for connection. No default, must be defined.</li> 24 * <li>WP_PROXY_USERNAME - Proxy username, if it requires authentication.</li> 25 * <li>WP_PROXY_PASSWORD - Proxy password, if it requires authentication.</li> 26 * <li>WP_PROXY_BYPASS_HOSTS - Will prevent the hosts in this list from going through the proxy. 27 * You do not need to have localhost and the site host in this list, because they will not be passed 28 * through the proxy. The list should be presented in a comma separated list, wildcards using * are supported, eg. *.wordpress.org</li> 29 * </ol> 30 * 31 * An example can be as seen below. 32 * 33 * define('WP_PROXY_HOST', '192.168.84.101'); 34 * define('WP_PROXY_PORT', '8080'); 35 * define('WP_PROXY_BYPASS_HOSTS', 'localhost, www.example.com, *.wordpress.org'); 36 * 37 * @link https://core.trac.wordpress.org/ticket/4011 Proxy support ticket in WordPress. 38 * @link https://core.trac.wordpress.org/ticket/14636 Allow wildcard domains in WP_PROXY_BYPASS_HOSTS 39 * 40 * @since 2.8.0 41 */ 42 class WP_HTTP_Proxy { 43 44 /** 45 * Whether proxy connection should be used. 46 * 47 * @since 2.8.0 48 * 49 * @use WP_PROXY_HOST 50 * @use WP_PROXY_PORT 51 * 52 * @return bool 53 */ 54 public function is_enabled() { 55 return defined( 'WP_PROXY_HOST' ) && defined( 'WP_PROXY_PORT' ); 56 } 57 58 /** 59 * Whether authentication should be used. 60 * 61 * @since 2.8.0 62 * 63 * @use WP_PROXY_USERNAME 64 * @use WP_PROXY_PASSWORD 65 * 66 * @return bool 67 */ 68 public function use_authentication() { 69 return defined( 'WP_PROXY_USERNAME' ) && defined( 'WP_PROXY_PASSWORD' ); 70 } 71 72 /** 73 * Retrieve the host for the proxy server. 74 * 75 * @since 2.8.0 76 * 77 * @return string 78 */ 79 public function host() { 80 if ( defined( 'WP_PROXY_HOST' ) ) { 81 return WP_PROXY_HOST; 82 } 83 84 return ''; 85 } 86 87 /** 88 * Retrieve the port for the proxy server. 89 * 90 * @since 2.8.0 91 * 92 * @return string 93 */ 94 public function port() { 95 if ( defined( 'WP_PROXY_PORT' ) ) { 96 return WP_PROXY_PORT; 97 } 98 99 return ''; 100 } 101 102 /** 103 * Retrieve the username for proxy authentication. 104 * 105 * @since 2.8.0 106 * 107 * @return string 108 */ 109 public function username() { 110 if ( defined( 'WP_PROXY_USERNAME' ) ) { 111 return WP_PROXY_USERNAME; 112 } 113 114 return ''; 115 } 116 117 /** 118 * Retrieve the password for proxy authentication. 119 * 120 * @since 2.8.0 121 * 122 * @return string 123 */ 124 public function password() { 125 if ( defined( 'WP_PROXY_PASSWORD' ) ) { 126 return WP_PROXY_PASSWORD; 127 } 128 129 return ''; 130 } 131 132 /** 133 * Retrieve authentication string for proxy authentication. 134 * 135 * @since 2.8.0 136 * 137 * @return string 138 */ 139 public function authentication() { 140 return $this->username() . ':' . $this->password(); 141 } 142 143 /** 144 * Retrieve header string for proxy authentication. 145 * 146 * @since 2.8.0 147 * 148 * @return string 149 */ 150 public function authentication_header() { 151 return 'Proxy-Authorization: Basic ' . base64_encode( $this->authentication() ); 152 } 153 154 /** 155 * Determines whether the request should be sent through a proxy. 156 * 157 * We want to keep localhost and the site URL from being sent through the proxy, because 158 * some proxies can not handle this. We also have the constant available for defining other 159 * hosts that won't be sent through the proxy. 160 * 161 * @since 2.8.0 162 * 163 * @param string $uri URL of the request. 164 * @return bool Whether to send the request through the proxy. 165 */ 166 public function send_through_proxy( $uri ) { 167 $check = parse_url( $uri ); 168 169 // Malformed URL, can not process, but this could mean ssl, so let through anyway. 170 if ( false === $check ) { 171 return true; 172 } 173 174 $home = parse_url( get_option( 'siteurl' ) ); 175 176 /** 177 * Filters whether to preempt sending the request through the proxy. 178 * 179 * Returning false will bypass the proxy; returning true will send 180 * the request through the proxy. Returning null bypasses the filter. 181 * 182 * @since 3.5.0 183 * 184 * @param bool|null $override Whether to send the request through the proxy. Default null. 185 * @param string $uri URL of the request. 186 * @param array $check Associative array result of parsing the request URL with `parse_url()`. 187 * @param array $home Associative array result of parsing the site URL with `parse_url()`. 188 */ 189 $result = apply_filters( 'pre_http_send_through_proxy', null, $uri, $check, $home ); 190 if ( ! is_null( $result ) ) { 191 return $result; 192 } 193 194 if ( 'localhost' === $check['host'] || ( isset( $home['host'] ) && $home['host'] === $check['host'] ) ) { 195 return false; 196 } 197 198 if ( ! defined( 'WP_PROXY_BYPASS_HOSTS' ) ) { 199 return true; 200 } 201 202 static $bypass_hosts = null; 203 static $wildcard_regex = array(); 204 if ( null === $bypass_hosts ) { 205 $bypass_hosts = preg_split( '|,\s*|', WP_PROXY_BYPASS_HOSTS ); 206 207 if ( false !== strpos( WP_PROXY_BYPASS_HOSTS, '*' ) ) { 208 $wildcard_regex = array(); 209 foreach ( $bypass_hosts as $host ) { 210 $wildcard_regex[] = str_replace( '\*', '.+', preg_quote( $host, '/' ) ); 211 } 212 $wildcard_regex = '/^(' . implode( '|', $wildcard_regex ) . ')$/i'; 213 } 214 } 215 216 if ( ! empty( $wildcard_regex ) ) { 217 return ! preg_match( $wildcard_regex, $check['host'] ); 218 } else { 219 return ! in_array( $check['host'], $bypass_hosts, true ); 220 } 221 } 222 }