From 5819f7013357bc443f536b575dfffaa25a644ad1 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Tim=20D=C3=BCsterhus?= Date: Wed, 19 Nov 2014 04:37:59 +0100 Subject: [PATCH] Use CONNECT to proxy HTTPS connections --- .../files/lib/util/HTTPRequest.class.php | 51 +++++++++++++++++-- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/wcfsetup/install/files/lib/util/HTTPRequest.class.php b/wcfsetup/install/files/lib/util/HTTPRequest.class.php index 591c462838..867eb942bd 100644 --- a/wcfsetup/install/files/lib/util/HTTPRequest.class.php +++ b/wcfsetup/install/files/lib/util/HTTPRequest.class.php @@ -44,18 +44,36 @@ final class HTTPRequest { */ private $useSSL = false; + /** + * indicates if the connection to the proxy target will be made via SSL + * @var boolean + */ + private $originUseSSL = false; + /** * target host * @var string */ private $host; + /** + * target host if a proxy is used + * @var string + */ + private $originHost; + /** * target port * @var integer */ private $port; + /** + * target port if a proxy is used + * @var integer + */ + private $originPort; + /** * target path * @var string @@ -214,12 +232,13 @@ final class HTTPRequest { $this->port = isset($parsedUrl['port']) ? $parsedUrl['port'] : ($this->useSSL ? 443 : 80); $this->query = isset($parsedUrl['query']) ? $parsedUrl['query'] : ''; + $this->originUseSSL = $originUrl['scheme'] === 'https'; + $this->originHost = $originUrl['host']; + $this->originPort = isset($originUrl['port']) ? $originUrl['port'] : ($this->originUseSSL ? 443 : 80); + // update the 'Host:' header if URL has changed if ($this->url != $url) { - $originUseSSL = $originUrl['scheme'] === 'https'; - $originHost = $originUrl['host']; - $originPort = isset($originUrl['port']) ? $originUrl['port'] : ($originUseSSL ? 443 : 80); - $this->addHeader('host', $originHost.($originPort != ($originUseSSL ? 443 : 80) ? ':'.$originPort : '')); + $this->addHeader('host', $this->originHost.($this->originPort != ($this->originUseSSL ? 443 : 80) ? ':'.$this->originPort : '')); } $this->url = $url; @@ -232,6 +251,30 @@ final class HTTPRequest { // connect $remoteFile = new RemoteFile(($this->useSSL ? 'ssl://' : '').$this->host, $this->port, $this->options['timeout']); + if ($this->originUseSSL && PROXY_SERVER_HTTP) { + if ($this->useSSL) throw new SystemException("Unable to proxy HTTPS when using TLS for proxy connection"); + + $request = "CONNECT ".$this->originHost.":".$this->originPort." HTTP/1.0\r\n"; + if (isset($this->headers['user-agent'])) { + $request .= 'user-agent: '.reset($this->headers['user-agent'])."\r\n"; + } + $request .= "Host: ".$this->originHost.":".$this->originPort."\r\n"; + $request .= "\r\n"; + $remoteFile->puts($request); + $this->replyHeaders = array(); + while (!$remoteFile->eof()) { + $line = $remoteFile->gets(); + if (rtrim($line) === '') { + $this->parseReplyHeaders(); + + break; + } + $this->replyHeaders[] = $line; + } + if ($this->statusCode != 200) throw new SystemException("Expected 200 Ok as reply to my CONNECT, got '".$this->statusCode."'"); + $remoteFile->setTLS(true); + } + $request = $this->options['method']." ".$this->path.($this->query ? '?'.$this->query : '')." HTTP/1.1\r\n"; // add headers -- 2.20.1