Skip to content

Commit 137faed

Browse files
committed
:octocat: use ext-brotli if available
1 parent b512b40 commit 137faed

File tree

2 files changed

+50
-12
lines changed

2 files changed

+50
-12
lines changed

src/message_helpers.php

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@
88

99
namespace chillerlan\HTTP\Utils;
1010

11-
use TypeError;
11+
use RuntimeException, TypeError;
1212
use Psr\Http\Message\{MessageInterface, RequestInterface, ResponseInterface, UriInterface};
1313

14-
use function array_filter, array_map, explode, gzdecode, gzinflate, gzuncompress, implode,
14+
use function array_filter, array_map, explode, extension_loaded, function_exists, gzdecode, gzinflate, gzuncompress, implode,
1515
is_array, is_scalar, json_decode, json_encode, parse_url, preg_match, preg_replace_callback, rawurldecode,
16-
rawurlencode, simplexml_load_string, trim, urlencode;
16+
rawurlencode, simplexml_load_string, strtolower, trim, urlencode;
1717

1818
const CHILLERLAN_PSR7_UTIL_INCLUDES = true;
1919

@@ -210,19 +210,32 @@ function message_to_string(MessageInterface $message):string{
210210
* @param \Psr\Http\Message\MessageInterface $message
211211
*
212212
* @return string
213+
* @throws \RuntimeException
213214
*/
214215
function decompress_content(MessageInterface $message):string{
215-
$data = $message->getBody()->__toString();
216+
$data = (string)$message->getBody();
217+
$encoding = strtolower($message->getHeaderLine('content-encoding'));
216218
$message->getBody()->rewind();
217219

218-
switch($message->getHeaderLine('content-encoding')){
219-
# case 'br' : return brotli_uncompress($data); // @todo: https://github.com/kjdev/php-ext-brotli
220-
case 'compress': return gzuncompress($data);
221-
case 'deflate' : return gzinflate($data);
222-
case 'gzip' : return gzdecode($data);
223-
default: return $data;
220+
if($encoding === 'br'){
221+
// https://github.com/kjdev/php-ext-brotli
222+
if(extension_loaded('brotli') && function_exists('brotli_uncompress')){
223+
return brotli_uncompress($data); // @codeCoverageIgnore
224+
}
225+
226+
throw new RuntimeException('cannot decompress brotli compressed message body');
227+
}
228+
elseif($encoding === 'compress'){
229+
return gzuncompress($data);
230+
}
231+
elseif($encoding === 'deflate'){
232+
return gzinflate($data);
233+
}
234+
elseif($encoding === 'gzip' || $encoding === 'x-gzip'){
235+
return gzdecode($data);
224236
}
225237

238+
return $data;
226239
}
227240

228241
const URI_DEFAULT_PORTS = [

tests/MessageHelpersTest.php

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,15 @@
1010

1111
namespace chillerlan\HTTPTest\Utils;
1212

13-
use TypeError;
13+
use RuntimeException, TypeError;
1414

1515
use function chillerlan\HTTP\Utils\{
1616
decompress_content, get_json, get_xml, message_to_string, parseUrl, r_rawurlencode,
1717
uriIsAbsolute, uriIsAbsolutePathReference, uriIsDefaultPort, uriIsNetworkPathReference,
1818
uriIsRelativePathReference, uriWithoutQueryValue, uriWithQueryValue
1919
};
2020

21+
use function extension_loaded, function_exists;
2122
use const chillerlan\HTTP\Utils\URI_DEFAULT_PORTS;
2223

2324
class MessageHelpersTest extends TestAbstract{
@@ -106,6 +107,7 @@ public function testMessageToString():void{
106107

107108
public function decompressDataProvider():array{
108109
return [
110+
'br' => ['brotli_compress', 'br'],
109111
'compress' => ['gzcompress', 'compress'],
110112
'deflate' => ['gzdeflate', 'deflate'],
111113
'gzip' => ['gzencode', 'gzip'],
@@ -117,7 +119,14 @@ public function decompressDataProvider():array{
117119
* @dataProvider decompressDataProvider
118120
*/
119121
public function testDecompressContent(string $fn, string $encoding):void{
120-
$data = $expected = str_repeat('compressed string ', 100);
122+
123+
// https://github.com/kjdev/php-ext-brotli
124+
if($encoding === 'br' && (!extension_loaded('brotli') || !function_exists('brotli_compress'))){
125+
$this::markTestSkipped('N/A (ext-brotli not isntalled)');
126+
}
127+
128+
$data = str_repeat('compressed string ', 100);
129+
$expected = $data;
121130
$response = $this->responseFactory->createResponse();
122131

123132
if($fn){
@@ -130,6 +139,22 @@ public function testDecompressContent(string $fn, string $encoding):void{
130139
$this::assertSame($expected, decompress_content($response));
131140
}
132141

142+
public function testDecompressContentUnableToDecompressBrotliException():void{
143+
144+
if(extension_loaded('brotli') && function_exists('brotli_uncompress')){
145+
$this::markTestSkipped('N/A (ext-brotli isntalled)');
146+
}
147+
148+
$this->expectException(RuntimeException::class);
149+
$this->expectExceptionMessage('cannot decompress brotli compressed message body');
150+
151+
$response = $this->responseFactory
152+
->createResponse()
153+
->withHeader('Content-Encoding', 'br');
154+
155+
decompress_content($response);
156+
}
157+
133158
public function testUriIsAbsolute():void{
134159
$this::assertTrue(uriIsAbsolute($this->uriFactory->createUri('http://example.org')));
135160
$this::assertFalse(uriIsAbsolute($this->uriFactory->createUri('//example.org')));

0 commit comments

Comments
 (0)