1<?php 2 3declare(strict_types=1); 4 5namespace GuzzleHttp\Psr7; 6 7use Psr\Http\Message\StreamInterface; 8 9/** 10 * Uses PHP's zlib.inflate filter to inflate zlib (HTTP deflate, RFC1950) or gzipped (RFC1952) content. 11 * 12 * This stream decorator converts the provided stream to a PHP stream resource, 13 * then appends the zlib.inflate filter. The stream is then converted back 14 * to a Guzzle stream resource to be used as a Guzzle stream. 15 * 16 * @see https://datatracker.ietf.org/doc/html/rfc1950 17 * @see https://datatracker.ietf.org/doc/html/rfc1952 18 * @see https://www.php.net/manual/en/filters.compression.php 19 */ 20final class InflateStream implements StreamInterface 21{ 22 use StreamDecoratorTrait; 23 24 /** @var StreamInterface */ 25 private $stream; 26 27 public function __construct(StreamInterface $stream) 28 { 29 $resource = StreamWrapper::getResource($stream); 30 // Specify window=15+32, so zlib will use header detection to both gzip (with header) and zlib data 31 // See https://www.zlib.net/manual.html#Advanced definition of inflateInit2 32 // "Add 32 to windowBits to enable zlib and gzip decoding with automatic header detection" 33 // Default window size is 15. 34 stream_filter_append($resource, 'zlib.inflate', STREAM_FILTER_READ, ['window' => 15 + 32]); 35 $this->stream = $stream->isSeekable() ? new Stream($resource) : new NoSeekStream(new Stream($resource)); 36 } 37} 38