File indexing completed on 2024-12-29 05:27:23

0001 <?php
0002 namespace GuzzleHttp\Psr7;
0003 
0004 use Psr\Http\Message\StreamInterface;
0005 
0006 /**
0007  * Uses PHP's zlib.inflate filter to inflate deflate or gzipped content.
0008  *
0009  * This stream decorator skips the first 10 bytes of the given stream to remove
0010  * the gzip header, converts the provided stream to a PHP stream resource,
0011  * then appends the zlib.inflate filter. The stream is then converted back
0012  * to a Guzzle stream resource to be used as a Guzzle stream.
0013  *
0014  * @link http://tools.ietf.org/html/rfc1952
0015  * @link http://php.net/manual/en/filters.compression.php
0016  */
0017 class InflateStream implements StreamInterface
0018 {
0019     use StreamDecoratorTrait;
0020 
0021     public function __construct(StreamInterface $stream)
0022     {
0023         // read the first 10 bytes, ie. gzip header
0024         $header = $stream->read(10);
0025         $filenameHeaderLength = $this->getLengthOfPossibleFilenameHeader($stream, $header);
0026         // Skip the header, that is 10 + length of filename + 1 (nil) bytes
0027         $stream = new LimitStream($stream, -1, 10 + $filenameHeaderLength);
0028         $resource = StreamWrapper::getResource($stream);
0029         stream_filter_append($resource, 'zlib.inflate', STREAM_FILTER_READ);
0030         $this->stream = new Stream($resource);
0031     }
0032 
0033     /**
0034      * @param StreamInterface $stream
0035      * @param $header
0036      * @return int
0037      */
0038     private function getLengthOfPossibleFilenameHeader(StreamInterface $stream, $header)
0039     {
0040         $filename_header_length = 0;
0041 
0042         if (substr(bin2hex($header), 6, 2) === '08') {
0043             // we have a filename, read until nil
0044             $filename_header_length = 1;
0045             while ($stream->read(1) !== chr(0)) {
0046                 $filename_header_length++;
0047             }
0048         }
0049 
0050         return $filename_header_length;
0051     }
0052 }