123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- <?php
- /**
- * PEAR_Proxy
- *
- * HTTP Proxy handling
- *
- * @category pear
- * @package PEAR
- * @author Nico Boehr
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @link http://pear.php.net/package/PEAR
- */
- class PEAR_Proxy
- {
- var $config = null;
- /**
- * @access private
- */
- var $proxy_host;
- /**
- * @access private
- */
- var $proxy_port;
- /**
- * @access private
- */
- var $proxy_user;
- /**
- * @access private
- */
- var $proxy_pass;
- /**
- * @access private
- */
- var $proxy_schema;
- function __construct($config = null)
- {
- $this->config = $config;
- $this->_parseProxyInfo();
- }
- /**
- * @access private
- */
- function _parseProxyInfo()
- {
- $this->proxy_host = $this->proxy_port = $this->proxy_user = $this->proxy_pass = '';
- if ($this->config->get('http_proxy')&&
- $proxy = parse_url($this->config->get('http_proxy'))
- ) {
- $this->proxy_host = isset($proxy['host']) ? $proxy['host'] : null;
- $this->proxy_port = isset($proxy['port']) ? $proxy['port'] : 8080;
- $this->proxy_user = isset($proxy['user']) ? urldecode($proxy['user']) : null;
- $this->proxy_pass = isset($proxy['pass']) ? urldecode($proxy['pass']) : null;
- $this->proxy_schema = (isset($proxy['scheme']) && $proxy['scheme'] == 'https') ? 'https' : 'http';
- }
- }
- /**
- * @access private
- */
- function _httpConnect($fp, $host, $port)
- {
- fwrite($fp, "CONNECT $host:$port HTTP/1.1\r\n");
- fwrite($fp, "Host: $host:$port\r\n");
- if ($this->getProxyAuth()) {
- fwrite($fp, 'Proxy-Authorization: Basic ' . $this->getProxyAuth() . "\r\n");
- }
- fwrite($fp, "\r\n");
- while ($line = trim(fgets($fp, 1024))) {
- if (preg_match('|^HTTP/1.[01] ([0-9]{3}) |', $line, $matches)) {
- $code = (int)$matches[1];
- /* as per RFC 2817 */
- if ($code < 200 || $code >= 300) {
- return PEAR::raiseError("Establishing a CONNECT tunnel through proxy failed with response code $code");
- }
- }
- }
- // connection was successful -- establish SSL through
- // the tunnel
- $crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT;
- if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) {
- $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
- $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
- }
- // set the correct hostname for working hostname
- // verification
- stream_context_set_option($fp, 'ssl', 'peer_name', $host);
- // blocking socket needed for
- // stream_socket_enable_crypto()
- // see
- // <http://php.net/manual/en/function.stream-socket-enable-crypto.php>
- stream_set_blocking ($fp, true);
- $crypto_res = stream_socket_enable_crypto($fp, true, $crypto_method);
- if (!$crypto_res) {
- return PEAR::raiseError("Could not establish SSL connection through proxy $proxy_host:$proxy_port: $crypto_res");
- }
- return true;
- }
- /**
- * get the authorization information for the proxy, encoded to be
- * passed in the Proxy-Authentication HTTP header.
- * @return null|string the encoded authentication information if a
- * proxy and authentication is configured, null
- * otherwise.
- */
- function getProxyAuth()
- {
- if ($this->isProxyConfigured() && $this->proxy_user != '') {
- return base64_encode($this->proxy_user . ':' . $this->proxy_pass);
- }
- return null;
- }
- function getProxyUser()
- {
- return $this->proxy_user;
- }
- /**
- * Check if we are configured to use a proxy.
- *
- * @return boolean true if we are configured to use a proxy, false
- * otherwise.
- * @access public
- */
- function isProxyConfigured()
- {
- return $this->proxy_host != '';
- }
- /**
- * Open a socket to a remote server, possibly involving a HTTP
- * proxy.
- *
- * If an HTTP proxy has been configured (http_proxy PEAR_Config
- * setting), the proxy will be used.
- *
- * @param string $host the host to connect to
- * @param string $port the port to connect to
- * @param boolean $secure if true, establish a secure connection
- * using TLS.
- * @access public
- */
- function openSocket($host, $port, $secure = false)
- {
- if ($this->isProxyConfigured()) {
- $fp = @fsockopen(
- $this->proxy_host, $this->proxy_port,
- $errno, $errstr, 15
- );
- if (!$fp) {
- return PEAR::raiseError("Connection to `$proxy_host:$proxy_port' failed: $errstr", -9276);
- }
- /* HTTPS is to be used and we have a proxy, use CONNECT verb */
- if ($secure) {
- $res = $this->_httpConnect($fp, $host, $port);
- if (PEAR::isError($res)) {
- return $res;
- }
- }
- } else {
- if ($secure) {
- $host = 'ssl://' . $host;
- }
- $fp = @fsockopen($host, $port, $errno, $errstr);
- if (!$fp) {
- return PEAR::raiseError("Connection to `$host:$port' failed: $errstr", $errno);
- }
- }
- return $fp;
- }
- }
|