diff --git a/composer.json b/composer.json index 13070dc..3ab88b5 100644 --- a/composer.json +++ b/composer.json @@ -27,15 +27,18 @@ "require": { "php": ">=5.6", "ext-json": "*", + "php-http/discovery": "^1.6.1", + "psr/http-client-implementation": "*", "symfony/console": "^3.4|^4|^5|^6", "symfony/finder": "^3|^4|^5|^6", "symfony/process": "^3.4|^4|^5|^6", - "symfony/yaml": "^3.4|^4|^5|^6", - "guzzlehttp/guzzle": "^6.3|^7.0" + "symfony/yaml": "^3.4|^4|^5|^6" }, "require-dev": { - "ext-zip" : "*", + "ext-zip": "*", "friendsofphp/php-cs-fixer": "^2.18|^3.0", + "php-http/client-common": "^2.5", + "php-http/socket-client": "^2.1", "phpunit/phpunit": "^5.5|^6|^7|^8|^9" }, "bin": ["security-checker"], diff --git a/src/AdvisoryFetcher.php b/src/AdvisoryFetcher.php index d80162d..6f98eb7 100644 --- a/src/AdvisoryFetcher.php +++ b/src/AdvisoryFetcher.php @@ -2,16 +2,23 @@ namespace Enlightn\SecurityChecker; -use GuzzleHttp\Client; +use Http\Client\HttpClient; +use Http\Discovery\Psr17FactoryDiscovery; use Psr\Http\Message\ResponseInterface; +use Http\Discovery\HttpClientDiscovery; class AdvisoryFetcher { /** - * @var \GuzzleHttp\Client + * @var \Http\Client\HttpClient */ private $client; + /** + * @var \Psr\Http\Message\RequestFactoryInterface + */ + private $requestFactory; + /** * @var string */ @@ -25,15 +32,14 @@ class AdvisoryFetcher const EXTRACT_PATH = 'php_security_advisories'; + public function __construct($tempDir = null) { - $this->client = new Client(); + $this->client = HttpClientDiscovery::find(); + $this->requestFactory = Psr17FactoryDiscovery::findRequestFactory(); $this->tempDir = is_null($tempDir) ? sys_get_temp_dir() : $tempDir; } - /** - * @throws \GuzzleHttp\Exception\GuzzleException - */ public function fetchAdvisories() { $archivePath = $this->fetchAdvisoriesArchive(); @@ -48,28 +54,22 @@ public function fetchAdvisories() /** * @return string - * @throws \GuzzleHttp\Exception\GuzzleException */ public function fetchAdvisoriesArchive() { - $headers = []; + $request = $this->requestFactory->createRequest('GET', self::ADVISORIES_URL); $cacheResult = []; if (! empty($cache = $this->getCacheFile())) { $cacheResult = json_decode($cache, true); - if (is_file($cacheResult['ArchivePath'])) { // Set cache headers only if both the cache file and archive file exist. - $headers = [ - 'If-None-Match' => $cacheResult['Key'], - 'If-Modified-Since' => $cacheResult['Date'], - ]; + $request = $request->withHeader('If-None-Match', $cacheResult['Key']); + $request = $request->withHeader('If-Modified-Since', $cacheResult['Date']); } } - $response = $this->client->get(self::ADVISORIES_URL, [ - 'headers' => $headers, - ]); + $response = $this->client->sendRequest($request); if ($response->getStatusCode() !== 304) { $this->writeCacheFile($response); @@ -119,7 +119,7 @@ public function getExtractDirectoryPath() return $this->tempDir.DIRECTORY_SEPARATOR.self::EXTRACT_PATH; } - public function setClient(Client $client) + public function setClient(HttpClient $client) { $this->client = $client; } @@ -134,4 +134,12 @@ protected function writeCacheFile(ResponseInterface $response) file_put_contents($this->getCacheFilePath(), json_encode($cache), LOCK_EX); } + + /** + * @return HttpClient + */ + public function getClient() + { + return $this->client; + } } diff --git a/src/SecurityChecker.php b/src/SecurityChecker.php index 49fd050..2fb00db 100644 --- a/src/SecurityChecker.php +++ b/src/SecurityChecker.php @@ -19,7 +19,6 @@ public function __construct($tempDir = null) * @param false $excludeDev * @param array $allowList * @return array - * @throws \GuzzleHttp\Exception\GuzzleException */ public function check($composerLockPath, $excludeDev = false, $allowList = []) { diff --git a/tests/AdvisoryFetcherTest.php b/tests/AdvisoryFetcherTest.php index c36afb3..1c7e986 100644 --- a/tests/AdvisoryFetcherTest.php +++ b/tests/AdvisoryFetcherTest.php @@ -4,9 +4,9 @@ use Enlightn\SecurityChecker\AdvisoryFetcher; use Enlightn\SecurityChecker\Filesystem; -use GuzzleHttp\Client; -use GuzzleHttp\HandlerStack; -use GuzzleHttp\Middleware; +use Enlightn\SecurityChecker\Tests\Journal\SimpleArray; +use Http\Client\Common\Plugin\HistoryPlugin; +use Http\Client\Common\PluginClient; use PHPUnit\Framework\TestCase; class AdvisoryFetcherTest extends TestCase @@ -17,10 +17,14 @@ class AdvisoryFetcherTest extends TestCase public function fetches_archives_with_and_without_cache() { $fetcher = new AdvisoryFetcher; - $container = []; - $fetcher->setClient(new Client([ - 'handler' => $this->setupHistoryMiddleware($container), - ])); + $journal = new SimpleArray; + + $pluginClient = new PluginClient( + $fetcher->getClient(), + [new HistoryPlugin($journal)] + ); + + $fetcher->setClient($pluginClient); // Test for non-cached version. $this->cleanCacheFiles($fetcher); @@ -30,8 +34,8 @@ public function fetches_archives_with_and_without_cache() $this->assertTrue(is_dir($fetcher->getExtractDirectoryPath())); $this->assertTrue(is_file($fetcher->getCacheFilePath())); $this->assertTrue(is_file($fetcher->getExtractDirectoryPath().DIRECTORY_SEPARATOR.$this->getSampleFileToValidate())); - $this->assertCount(1, $container); - $this->assertSame(200, $container[0]['response']->getStatusCode()); + $this->assertCount(1, $journal->successes); + $this->assertSame(200, $journal->successes[0][1]->getStatusCode()); // Test for cached version. $this->cleanExtractDirectory($fetcher); @@ -40,8 +44,8 @@ public function fetches_archives_with_and_without_cache() $this->assertTrue(is_dir($fetcher->getExtractDirectoryPath())); $this->assertTrue(is_file($fetcher->getCacheFilePath())); $this->assertTrue(is_file($fetcher->getExtractDirectoryPath().DIRECTORY_SEPARATOR.$this->getSampleFileToValidate())); - $this->assertCount(2, $container); - $this->assertSame(304, $container[1]['response']->getStatusCode()); + $this->assertCount(2, $journal->successes); + $this->assertSame(304, $journal->successes[1][1]->getStatusCode());; $this->cleanCacheFiles($fetcher); } @@ -58,14 +62,6 @@ protected function cleanCacheFiles(AdvisoryFetcher $fetcher) @unlink($fetcher->getArchiveFilePath()); } - protected function setupHistoryMiddleware(&$container) - { - $handlerStack = HandlerStack::create(); - $handlerStack->push(Middleware::history($container)); - - return $handlerStack; - } - protected function getSampleFileToValidate() { return 'security-advisories-master'.DIRECTORY_SEPARATOR.'laravel'.DIRECTORY_SEPARATOR.'framework' diff --git a/tests/Journal/SimpleArray.php b/tests/Journal/SimpleArray.php new file mode 100644 index 0000000..2dd3379 --- /dev/null +++ b/tests/Journal/SimpleArray.php @@ -0,0 +1,24 @@ +successes[] = [$request, $response]; + } + + public function addFailure(RequestInterface $request, ClientExceptionInterface $exception) + { + $this->failures[] = [$request, $exception]; + } +}