From b11cc73091a3dbfee68bec755287feb068f0459f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20Fabr=C3=A9gat?= Date: Thu, 3 May 2018 12:14:39 +0200 Subject: [PATCH] new response type HttpProxyResponse --- composer.json | 3 +- src/HttpProxyResponse.php | 80 +++++++++++++++++++++++++++++++++ tests/HttpProxyResponseTest.php | 76 +++++++++++++++++++++++++++++++ 3 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 src/HttpProxyResponse.php create mode 100644 tests/HttpProxyResponseTest.php diff --git a/composer.json b/composer.json index d64f9a0..0fceb85 100644 --- a/composer.json +++ b/composer.json @@ -13,7 +13,8 @@ "codeinc/media-types": "^1.0" }, "require-dev": { - "phpunit/phpunit": "^7" + "phpunit/phpunit": "^7", + "codeinc/psr7-response-sender": "^1.1" }, "autoload": { "psr-4": {"CodeInc\\Psr7Responses\\": "src/"} diff --git a/src/HttpProxyResponse.php b/src/HttpProxyResponse.php new file mode 100644 index 0000000..09f35cd --- /dev/null +++ b/src/HttpProxyResponse.php @@ -0,0 +1,80 @@ + +// Date: 03/05/2018 +// Time: 11:43 +// Project: Psr7Responses +// +declare(strict_types=1); +namespace CodeInc\Psr7Responses; +use CodeInc\Psr7Responses\Tests\HttpProxyResponseTest; +use GuzzleHttp\Psr7\Response; +use function GuzzleHttp\Psr7\stream_for; + + +/** + * Class HttpProxyResponse + * + * @see HttpProxyResponseTest + * @package CodeInc\Psr7Responses + * @author Joan Fabrégat + */ +class HttpProxyResponse extends Response +{ + /** + * ProxyResponse constructor. + * + * @param string $remoteUrl + * @param int $status + * @param array $headers + * @param string $version + * @param null|string $reason + * @throws ResponseException + */ + public function __construct(string $remoteUrl, int $status = 200, array $headers = [], + string $version = '1.1', ?string $reason = null) + { + // checking the URL + if (!filter_var($remoteUrl, FILTER_VALIDATE_URL)) { + throw new ResponseException( + sprintf("%s is not a valid URL", $remoteUrl), + $this + ); + } + + // downloading + $context = stream_context_create(['http' => ['method' => 'GET']]); + if (($f = fopen($remoteUrl, 'r', false, $context)) === false) { + throw new ResponseException( + sprintf("Unable to open the URL %s", $remoteUrl), + $this + ); + } + + // importing the headers + foreach ($http_response_header as $header) { + if (preg_match('/^([\\w-]+): +(.+)$/ui', $header, $matches)) { + if (in_array(strtolower($matches[1]), ['content-type', 'last-modified', 'content-length', 'date'])) { + $headers[$matches[1]] = $matches[2]; + } + } + } + + parent::__construct($status, $headers, stream_for($f), $version, $reason); + } + +} \ No newline at end of file diff --git a/tests/HttpProxyResponseTest.php b/tests/HttpProxyResponseTest.php new file mode 100644 index 0000000..ec000c4 --- /dev/null +++ b/tests/HttpProxyResponseTest.php @@ -0,0 +1,76 @@ + +// Date: 03/05/2018 +// Time: 11:43 +// Project: Psr7Responses +// +declare(strict_types=1); +namespace CodeInc\Psr7Responses\Tests; +use CodeInc\Psr7Responses\HttpProxyResponse; +use PHPUnit\Framework\TestCase; +use Psr\Http\Message\ResponseInterface; + + +/** + * Class HttpProxyResponseTest + * + * @uses HttpProxyResponse + * @package CodeInc\Psr7Responses\Tests + * @author Joan Fabrégat + */ +final class HttpProxyResponseTest extends TestCase +{ + private const TEST_TXT_URL = 'https://www.sample-videos.com/text/Sample-text-file-10kb.txt'; + private const TEST_IMG_URL = 'https://www.sample-videos.com/img/Sample-jpg-image-50kb.jpg'; + + /** + * @throws \CodeInc\Psr7Responses\ResponseException + */ + public function testTxtResponse():void + { + $response = new HttpProxyResponse(self::TEST_IMG_URL); + self::assertInstanceOf(ResponseInterface::class, $response); + self::assertResponse($response); + } + /** + * @throws \CodeInc\Psr7Responses\ResponseException + */ + public function testImgResponse():void + { + $response = new HttpProxyResponse(self::TEST_TXT_URL); + self::assertInstanceOf(ResponseInterface::class, $response); + self::assertResponse($response); + } + + /** + * @param ResponseInterface $response + */ + public static function assertResponse(ResponseInterface $response):void + { + // detching the stream + $bodyStream = $response->getBody()->detach(); + self::assertInternalType('resource', $bodyStream); + + // downloading the body + $body = stream_get_contents($bodyStream); + self::assertNotEmpty($body); + self::assertEquals(strlen($body), $response->getHeaderLine('Content-Length')); + + fclose($bodyStream); + } +} \ No newline at end of file