Skip to content

Commit

Permalink
Allow to use a proxy for downloads
Browse files Browse the repository at this point in the history
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`
  • Loading branch information
heiglandreas committed Jul 6, 2022
1 parent 34af1d3 commit cf122d1
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 2 deletions.
2 changes: 1 addition & 1 deletion phive.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<phive xmlns="https://phar.io/phive">
<phar name="phpunit" version="^9.3" location="./tools/phpunit" copy="false" installed="9.4.2"/>
<phar name="phpunit" version="^9.3" location="./tools/phpunit" copy="true" installed="9.5.21"/>
<phar name="psalm" version="^3.11" location="./tools/psalm" copy="false" installed="3.18.2"/>
<phar name="php-cs-fixer" version="^2.16" location="./tools/php-cs-fixer" copy="false" installed="2.16.7"/>
</phive>
36 changes: 35 additions & 1 deletion src/Service/Download.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
use SplFileInfo;
use function feof;
use function fwrite;
use function getenv;
use function stream_context_create;

final class Download
{
Expand All @@ -20,12 +22,44 @@ 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));
}
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);
}
}
41 changes: 41 additions & 0 deletions tests/unit/Service/DownloadTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

namespace PharIo\ComposerDistributorTest\unit\Service;

use PharIo\ComposerDistributor\Service\Download;
use PharIo\ComposerDistributor\Url;
use PHPUnit\Framework\TestCase;
use SplFileInfo;
use function file_get_contents;
use function putenv;
use function sys_get_temp_dir;
use function tempnam;

class DownloadTest extends TestCase
{
public function testDownloadWithoutProxy(): void
{
putenv('http_proxy=');

$temp = new SplFileInfo(tempnam(sys_get_temp_dir(), 'tests'));

$download = new Download(Url::fromString('https://example.org'));

$download->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);
}
}

0 comments on commit cf122d1

Please sign in to comment.