From cf122d1b7e4bf1d6711edd645c499b0be98b4ea8 Mon Sep 17 00:00:00 2001 From: Andreas Heigl Date: Wed, 6 Jul 2022 22:08:02 +0200 Subject: [PATCH] Allow to use a proxy for downloads This change will make it possible to provide a proxy when downloading. For that the content of the environment-variable `HTTP_PROXY` is used. Alternatively one can also use `http_proxy` (as used by curl) can be used. For proxy-authentication you can set user and password for basic- authentication via the environment variable `HTTP_PROXY_AUTH` --- phive.xml | 2 +- src/Service/Download.php | 36 ++++++++++++++++++++++++- tests/unit/Service/DownloadTest.php | 41 +++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 tests/unit/Service/DownloadTest.php diff --git a/phive.xml b/phive.xml index 1cc6c17..be59661 100644 --- a/phive.xml +++ b/phive.xml @@ -1,6 +1,6 @@ - + diff --git a/src/Service/Download.php b/src/Service/Download.php index 5a80c69..166aad0 100644 --- a/src/Service/Download.php +++ b/src/Service/Download.php @@ -8,6 +8,8 @@ use SplFileInfo; use function feof; use function fwrite; +use function getenv; +use function stream_context_create; final class Download { @@ -20,7 +22,8 @@ public function __construct(Url $url) public function toLocation(SplFileInfo $downloadLocation) : void { - $source = fopen($this->url->toString(), 'r'); + $context = $this->getStreamContext(); + $source = fopen($this->url->toString(), 'r',false, $context); $target = fopen($downloadLocation->getPathname(), 'w'); while (!feof($source)) { fwrite($target, fread($source, 1024)); @@ -28,4 +31,35 @@ public function toLocation(SplFileInfo $downloadLocation) : void fclose($source); fclose($target); } + + /** + * @return resource + */ + private function getStreamContext() + { + foreach (['http_proxy', 'HTTP_PROXY', 'https_proxy', 'HTTPS_PROXY'] as $envName) { + $proxy = getenv($envName); + if ($proxy !== '') { + break; + } + } + + if ($proxy === '') { + return stream_context_create([]); + } + + $context = [ + 'http' => [ + 'proxy' => $proxy, + 'request_fulluri' => true, + ] + ]; + + $auth = getenv('HTTP_PROXY_AUTH'); + if ($auth !== '') { + $context['http']['header'][] = 'Proxy-Authorization: Basic ' . $auth; + } + + return stream_context_create($context); + } } diff --git a/tests/unit/Service/DownloadTest.php b/tests/unit/Service/DownloadTest.php new file mode 100644 index 0000000..ed25f97 --- /dev/null +++ b/tests/unit/Service/DownloadTest.php @@ -0,0 +1,41 @@ +toLocation($temp); + + self::assertStringContainsString('example', file_get_contents($temp->getPathname())); + } + + public function testDownloadWithProxy(): void + { + putenv('http_proxy=tcp://172.16.1.184:8888'); + + $temp = new SplFileInfo(tempnam(sys_get_temp_dir(), 'tests')); + + $download = new Download(Url::fromString('https://example.org')); + + $this->expectWarning(); + + $download->toLocation($temp); + } +}