From 2bbe40cf8802bbc3bbf83d454cc294080ebaf241 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Tue, 11 Feb 2014 23:01:29 +0100 Subject: HTTPClient: correctly abort a proxy connection if a needed CONNECT tunnel fails --- inc/HTTPClient.php | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'inc/HTTPClient.php') diff --git a/inc/HTTPClient.php b/inc/HTTPClient.php index 96954fb47..2226103b3 100644 --- a/inc/HTTPClient.php +++ b/inc/HTTPClient.php @@ -304,11 +304,18 @@ class HTTPClient { } // try establish a CONNECT tunnel for SSL - if($this->_ssltunnel($socket, $request_url)){ - // no keep alive for tunnels - $this->keep_alive = false; - // tunnel is authed already - if(isset($headers['Proxy-Authentication'])) unset($headers['Proxy-Authentication']); + try { + if($this->_ssltunnel($socket, $request_url)){ + // no keep alive for tunnels + $this->keep_alive = false; + // tunnel is authed already + if(isset($headers['Proxy-Authentication'])) unset($headers['Proxy-Authentication']); + } + } catch (HTTPClientException $e) { + $this->status = $e->getCode(); + $this->error = $e->getMessage(); + fclose($socket); + return false; } // keep alive? @@ -363,7 +370,7 @@ class HTTPClient { // get Status if (!preg_match('/^HTTP\/(\d\.\d)\s*(\d+).*?\n/', $r_headers, $m)) - throw new HTTPClientException('Server returned bad answer'); + throw new HTTPClientException('Server returned bad answer '.$r_headers); $this->status = $m[2]; @@ -526,6 +533,7 @@ class HTTPClient { * * @param resource &$socket * @param string &$requesturl + * @throws HTTPClientException when a tunnel is needed but could not be established * @return bool true if a tunnel was established */ function _ssltunnel(&$socket, &$requesturl){ @@ -559,7 +567,8 @@ class HTTPClient { return true; } } - return false; + + throw new HTTPClientException('Failed to establish secure proxy connection', -150); } /** -- cgit v1.2.3 From 350eada6c66014c2bfb20902742120b7568ec576 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Thu, 13 Feb 2014 14:43:33 +0100 Subject: make HTTPclient check for SSL support --- inc/HTTPClient.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'inc/HTTPClient.php') diff --git a/inc/HTTPClient.php b/inc/HTTPClient.php index 2226103b3..de3a16830 100644 --- a/inc/HTTPClient.php +++ b/inc/HTTPClient.php @@ -254,7 +254,13 @@ class HTTPClient { } // add SSL stream prefix if needed - needs SSL support in PHP - if($port == 443 || $this->proxy_ssl) $server = 'ssl://'.$server; + if($port == 443 || $this->proxy_ssl) { + if(!in_array('ssl', stream_get_transports())) { + $this->status = -200; + $this->error = 'This PHP version does not support SSL - cannot connect to server'; + } + $server = 'ssl://'.$server; + } // prepare headers $headers = $this->headers; -- cgit v1.2.3 From adfe6dafd15d9bf52ed6212b44b02a6a32c8bf49 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Sun, 23 Feb 2014 09:38:03 +0100 Subject: fixed proxy authentication in SSL tunneling --- inc/HTTPClient.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'inc/HTTPClient.php') diff --git a/inc/HTTPClient.php b/inc/HTTPClient.php index de3a16830..53f3c9a78 100644 --- a/inc/HTTPClient.php +++ b/inc/HTTPClient.php @@ -552,7 +552,7 @@ class HTTPClient { $request = "CONNECT {$requestinfo['host']}:{$requestinfo['port']} HTTP/1.0".HTTP_NL; $request .= "Host: {$requestinfo['host']}".HTTP_NL; if($this->proxy_user) { - 'Proxy-Authorization Basic '.base64_encode($this->proxy_user.':'.$this->proxy_pass).HTTP_NL; + $request .= 'Proxy-Authorization Basic '.base64_encode($this->proxy_user.':'.$this->proxy_pass).HTTP_NL; } $request .= HTTP_NL; -- cgit v1.2.3 From 67f6ad6b9470dc8cc4396298d366e5df008fe69d Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 29 Apr 2014 22:31:58 +0200 Subject: Fix https proxy authentication, the header was missing a colon so that the auth info was not working. --- inc/HTTPClient.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'inc/HTTPClient.php') diff --git a/inc/HTTPClient.php b/inc/HTTPClient.php index 53f3c9a78..f8b836753 100644 --- a/inc/HTTPClient.php +++ b/inc/HTTPClient.php @@ -552,7 +552,7 @@ class HTTPClient { $request = "CONNECT {$requestinfo['host']}:{$requestinfo['port']} HTTP/1.0".HTTP_NL; $request .= "Host: {$requestinfo['host']}".HTTP_NL; if($this->proxy_user) { - $request .= 'Proxy-Authorization Basic '.base64_encode($this->proxy_user.':'.$this->proxy_pass).HTTP_NL; + $request .= 'Proxy-Authorization: Basic '.base64_encode($this->proxy_user.':'.$this->proxy_pass).HTTP_NL; } $request .= HTTP_NL; -- cgit v1.2.3 From 5171287a24c73f32e4765bdb998c23febb131467 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Mon, 19 May 2014 21:37:20 +0200 Subject: fixed parameter type --- inc/HTTPClient.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'inc/HTTPClient.php') diff --git a/inc/HTTPClient.php b/inc/HTTPClient.php index f8b836753..b5956a7f8 100644 --- a/inc/HTTPClient.php +++ b/inc/HTTPClient.php @@ -343,7 +343,7 @@ class HTTPClient { try { //set non-blocking - stream_set_blocking($socket, false); + stream_set_blocking($socket, 0); // build request $request = "$method $request_url HTTP/".$this->http.HTTP_NL; -- cgit v1.2.3 From 6fc4ea2c9a414260900dbe10478d307dc3e952c0 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Sun, 25 May 2014 12:16:22 +0200 Subject: removed some unused lines in HTTPClient --- inc/HTTPClient.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'inc/HTTPClient.php') diff --git a/inc/HTTPClient.php b/inc/HTTPClient.php index b5956a7f8..4352bcb97 100644 --- a/inc/HTTPClient.php +++ b/inc/HTTPClient.php @@ -61,6 +61,9 @@ class DokuHTTPClient extends HTTPClient { } +/** + * Class HTTPClientException + */ class HTTPClientException extends Exception { } /** @@ -249,7 +252,6 @@ class HTTPClient { if (empty($port)) $port = 8080; }else{ $request_url = $path; - $server = $server; if (!isset($port)) $port = ($uri['scheme'] == 'https') ? 443 : 80; } @@ -280,7 +282,6 @@ class HTTPClient { } } $headers['Content-Length'] = strlen($data); - $rmethod = 'POST'; }elseif($method == 'GET'){ $data = ''; //no data allowed on GET requests } @@ -458,7 +459,7 @@ class HTTPClient { if ($chunk_size > 0) { $r_body .= $this->_readData($socket, $chunk_size, 'chunk'); - $byte = $this->_readData($socket, 2, 'chunk'); // read trailing \r\n + $this->_readData($socket, 2, 'chunk'); // read trailing \r\n } } while ($chunk_size && !$abort); }elseif(isset($this->resp_headers['content-length']) && !isset($this->resp_headers['transfer-encoding'])){ @@ -480,7 +481,6 @@ class HTTPClient { $r_body = $this->_readData($socket, $this->max_bodysize, 'response (content-length limited)', true); }else{ // read entire socket - $r_size = 0; while (!feof($socket)) { $r_body .= $this->_readData($socket, 4096, 'response (unlimited)', true); } @@ -509,7 +509,6 @@ class HTTPClient { if (!$this->keep_alive || (isset($this->resp_headers['connection']) && $this->resp_headers['connection'] == 'Close')) { // close socket - $status = socket_get_status($socket); fclose($socket); unset(self::$connections[$connectionId]); } -- cgit v1.2.3 From 2314059e5b8fc84fcdc52e4506ec907d0c792f50 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Fri, 4 Jul 2014 17:16:09 +0200 Subject: allow for easier HTTPClient debugging Sometimes users report bugs or problems releated to HTTP connections made by our HTTPCient (eg. in the extension manager or XMLRPC). Debugging those problems previously required modifying some sources to enable the debugging output of the HTTPClient. This patch adds a way to enable the debugging via a request parameter. Since HTTP requests are often done only *after* some button was clicked, the parameter is also looked for in the referrer of a request. Debugging output is enabled through the existence of the parameter 'httpdebug' and is directly printed to the screen. Debugging HTTP only works when allowdebug is enabled. --- inc/HTTPClient.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'inc/HTTPClient.php') diff --git a/inc/HTTPClient.php b/inc/HTTPClient.php index 4352bcb97..6ac67f159 100644 --- a/inc/HTTPClient.php +++ b/inc/HTTPClient.php @@ -35,6 +35,19 @@ class DokuHTTPClient extends HTTPClient { $this->proxy_pass = conf_decodeString($conf['proxy']['pass']); $this->proxy_ssl = $conf['proxy']['ssl']; $this->proxy_except = $conf['proxy']['except']; + + // allow enabling debugging via URL parameter (if debugging allowed) + if($conf['allowdebug']) { + if( + isset($_REQUEST['httpdebug']) || + ( + isset($_SERVER['HTTP_REFERER']) && + strpos($_SERVER['HTTP_REFERER'], 'httpdebug') !== false + ) + ) { + $this->debug = true; + } + } } -- cgit v1.2.3 From 5aca1d54db0f056fec97a36487b09ebf0a864ed3 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Mon, 28 Jul 2014 19:01:42 +0200 Subject: HTTPClient don't omit headers with value 0 --- inc/HTTPClient.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'inc/HTTPClient.php') diff --git a/inc/HTTPClient.php b/inc/HTTPClient.php index 6ac67f159..cd4c7c4c5 100644 --- a/inc/HTTPClient.php +++ b/inc/HTTPClient.php @@ -808,7 +808,7 @@ class HTTPClient { function _buildHeaders($headers){ $string = ''; foreach($headers as $key => $value){ - if(empty($value)) continue; + if($value === '') continue; $string .= $key.': '.$value.HTTP_NL; } return $string; -- cgit v1.2.3 From e0c26282a603881e8d2f839d94c28dbbfc57d71b Mon Sep 17 00:00:00 2001 From: Gerrit Uitslag Date: Mon, 29 Sep 2014 03:34:17 +0200 Subject: scrutinizer documentations issues --- inc/HTTPClient.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'inc/HTTPClient.php') diff --git a/inc/HTTPClient.php b/inc/HTTPClient.php index cd4c7c4c5..ea20e3e56 100644 --- a/inc/HTTPClient.php +++ b/inc/HTTPClient.php @@ -57,6 +57,12 @@ class DokuHTTPClient extends HTTPClient { * @triggers HTTPCLIENT_REQUEST_SEND * @author Andreas Gohr */ + /** + * @param string $url + * @param string|array $data the post data either as array or raw data + * @param string $method + * @return bool + */ function sendRequest($url,$data='',$method='GET'){ $httpdata = array('url' => $url, 'data' => $data, @@ -104,7 +110,7 @@ class HTTPClient { var $header_regexp; // if set this RE must match against the headers, else abort var $headers; var $debug; - var $start = 0; // for timings + var $start = 0.0; // for timings var $keep_alive = true; // keep alive rocks // don't set these, read on error -- cgit v1.2.3 From 42ea7f447f39fbc2f79eaaec31f8c10ede59c5d0 Mon Sep 17 00:00:00 2001 From: Gerrit Uitslag Date: Wed, 1 Oct 2014 11:30:27 +0200 Subject: Many PHPDocs, some unused and dyn declared vars many PHPDocs some unused variables some dynamically declared variables declared --- inc/HTTPClient.php | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) (limited to 'inc/HTTPClient.php') diff --git a/inc/HTTPClient.php b/inc/HTTPClient.php index ea20e3e56..2e991b52f 100644 --- a/inc/HTTPClient.php +++ b/inc/HTTPClient.php @@ -172,7 +172,8 @@ class HTTPClient { * * @param string $url The URL to fetch * @param bool $sloppy304 Return body on 304 not modified - * @return bool|string response body, false on error + * @return false|string response body, false on error + * * @author Andreas Gohr */ function get($url,$sloppy304=false){ @@ -193,7 +194,8 @@ class HTTPClient { * @param string $url The URL to fetch * @param array $data Associative array of parameters * @param bool $sloppy304 Return body on 304 not modified - * @return bool|string response body, false on error + * @return false|string response body, false on error + * * @author Andreas Gohr */ function dget($url,$data,$sloppy304=false){ @@ -213,7 +215,7 @@ class HTTPClient { * * @param string $url The URL to fetch * @param array $data Associative array of parameters - * @return bool|string response body, false on error + * @return false|string response body, false on error * @author Andreas Gohr */ function post($url,$data){ @@ -235,6 +237,7 @@ class HTTPClient { * @param mixed $data - the post data either as array or raw data * @param string $method - HTTP Method usually GET or POST. * @return bool - true on success + * * @author Andreas Goetz * @author Andreas Gohr */ @@ -602,6 +605,7 @@ class HTTPClient { * @param string $data The data to write * @param string $message Description of what is being read * @throws HTTPClientException + * * @author Tom N Harris */ function _sendData($socket, $data, $message) { @@ -646,6 +650,7 @@ class HTTPClient { * @param bool $ignore_eof End-of-file is not an error if this is set * @throws HTTPClientException * @return string + * * @author Tom N Harris */ function _readData($socket, $nbytes, $message, $ignore_eof = false) { @@ -695,6 +700,7 @@ class HTTPClient { * @param string $message Description of what is being read * @throws HTTPClientException * @return string + * * @author Tom N Harris */ function _readLine($socket, $message) { @@ -729,6 +735,9 @@ class HTTPClient { * Uses _debug_text or _debug_html depending on the SAPI name * * @author Andreas Gohr + * + * @param string $info + * @param mixed $var */ function _debug($info,$var=null){ if(!$this->debug) return; @@ -742,8 +751,8 @@ class HTTPClient { /** * print debug info as HTML * - * @param $info - * @param null $var + * @param string $info + * @param mixed $var */ function _debug_html($info, $var=null){ print ''.$info.' '.($this->_time() - $this->start).'s
'; @@ -759,8 +768,8 @@ class HTTPClient { /** * prints debug info as plain text * - * @param $info - * @param null $var + * @param string $info + * @param mixed $var */ function _debug_text($info, $var=null){ print '*'.$info.'* '.($this->_time() - $this->start)."s\n"; @@ -770,6 +779,8 @@ class HTTPClient { /** * Return current timestamp in microsecond resolution + * + * @return float */ static function _time(){ list($usec, $sec) = explode(" ", microtime()); @@ -782,6 +793,9 @@ class HTTPClient { * All Keys are lowercased. * * @author Andreas Gohr + * + * @param string $string + * @return array */ function _parseHeaders($string){ $headers = array(); @@ -810,6 +824,9 @@ class HTTPClient { * convert given header array to header string * * @author Andreas Gohr + * + * @param array $headers + * @return string */ function _buildHeaders($headers){ $string = ''; @@ -824,6 +841,8 @@ class HTTPClient { * get cookies as http header string * * @author Andreas Goetz + * + * @return string */ function _getCookies(){ $headers = ''; @@ -839,6 +858,9 @@ class HTTPClient { * Encode data for posting * * @author Andreas Gohr + * + * @param array $data + * @return string */ function _postEncode($data){ return http_build_query($data,'','&'); @@ -849,6 +871,9 @@ class HTTPClient { * * @fixme use of urlencode might be wrong here * @author Andreas Gohr + * + * @param array $data + * @return string */ function _postMultipartEncode($data){ $boundary = '--'.$this->boundary; -- cgit v1.2.3 From dc193bd914e6c9cd3d0d1df7e171d38e8da407e5 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Thu, 11 Dec 2014 21:35:04 +0100 Subject: prefer TLS for SSL Tunnel connections #915 --- inc/HTTPClient.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'inc/HTTPClient.php') diff --git a/inc/HTTPClient.php b/inc/HTTPClient.php index 2e991b52f..4112932c4 100644 --- a/inc/HTTPClient.php +++ b/inc/HTTPClient.php @@ -589,7 +589,13 @@ class HTTPClient { $this->_debug('SSL Tunnel Response',$r_headers); if(preg_match('/^HTTP\/1\.[01] 200/i',$r_headers)){ - if (stream_socket_enable_crypto($socket, true, STREAM_CRYPTO_METHOD_SSLv3_CLIENT)) { + // Try a TLS connection first + if (@stream_socket_enable_crypto($socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) { + $requesturl = $requestinfo['path']; + return true; + } + // Fall back to SSLv3 + if (@stream_socket_enable_crypto($socket, true, STREAM_CRYPTO_METHOD_SSLv3_CLIENT)) { $requesturl = $requestinfo['path']; return true; } -- cgit v1.2.3 From 4343d40d6272b3148e99369d2f16d60f90c835a5 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Thu, 11 Dec 2014 23:39:21 +0100 Subject: set correct peer name when connecting through a SSL tunnel proxy --- inc/HTTPClient.php | 3 +++ 1 file changed, 3 insertions(+) (limited to 'inc/HTTPClient.php') diff --git a/inc/HTTPClient.php b/inc/HTTPClient.php index 4112932c4..c791b7f4a 100644 --- a/inc/HTTPClient.php +++ b/inc/HTTPClient.php @@ -589,6 +589,9 @@ class HTTPClient { $this->_debug('SSL Tunnel Response',$r_headers); if(preg_match('/^HTTP\/1\.[01] 200/i',$r_headers)){ + // set correct peer name for verification (enabled since PHP 5.6) + stream_context_set_option($socket, 'ssl', 'peer_name', $requestinfo['host']); + // Try a TLS connection first if (@stream_socket_enable_crypto($socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) { $requesturl = $requestinfo['path']; -- cgit v1.2.3 From c05ef534171135f4252fa0feed5466a75435b97a Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Fri, 12 Dec 2014 01:30:38 +0100 Subject: seems we need to do SSL/TLS checks the other way round --- inc/HTTPClient.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'inc/HTTPClient.php') diff --git a/inc/HTTPClient.php b/inc/HTTPClient.php index c791b7f4a..76d973c38 100644 --- a/inc/HTTPClient.php +++ b/inc/HTTPClient.php @@ -592,13 +592,15 @@ class HTTPClient { // set correct peer name for verification (enabled since PHP 5.6) stream_context_set_option($socket, 'ssl', 'peer_name', $requestinfo['host']); - // Try a TLS connection first - if (@stream_socket_enable_crypto($socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) { + // Because of older PHP versions having trouble with TLS (enable_crypto returns true, but + // the conection still borks) we try SSLv3 first + if (@stream_socket_enable_crypto($socket, true, STREAM_CRYPTO_METHOD_SSLv3_CLIENT)) { $requesturl = $requestinfo['path']; return true; } - // Fall back to SSLv3 - if (@stream_socket_enable_crypto($socket, true, STREAM_CRYPTO_METHOD_SSLv3_CLIENT)) { + + // If the proxy does not support SSLv3 we try TLS + if (@stream_socket_enable_crypto($socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) { $requesturl = $requestinfo['path']; return true; } -- cgit v1.2.3