Chris@0
|
1 <?php
|
Chris@0
|
2 namespace GuzzleHttp\Psr7;
|
Chris@0
|
3
|
Chris@0
|
4 use Psr\Http\Message\StreamInterface;
|
Chris@0
|
5
|
Chris@0
|
6 /**
|
Chris@0
|
7 * Uses PHP's zlib.inflate filter to inflate deflate or gzipped content.
|
Chris@0
|
8 *
|
Chris@0
|
9 * This stream decorator skips the first 10 bytes of the given stream to remove
|
Chris@0
|
10 * the gzip header, converts the provided stream to a PHP stream resource,
|
Chris@0
|
11 * then appends the zlib.inflate filter. The stream is then converted back
|
Chris@0
|
12 * to a Guzzle stream resource to be used as a Guzzle stream.
|
Chris@0
|
13 *
|
Chris@0
|
14 * @link http://tools.ietf.org/html/rfc1952
|
Chris@0
|
15 * @link http://php.net/manual/en/filters.compression.php
|
Chris@0
|
16 */
|
Chris@0
|
17 class InflateStream implements StreamInterface
|
Chris@0
|
18 {
|
Chris@0
|
19 use StreamDecoratorTrait;
|
Chris@0
|
20
|
Chris@0
|
21 public function __construct(StreamInterface $stream)
|
Chris@0
|
22 {
|
Chris@0
|
23 // read the first 10 bytes, ie. gzip header
|
Chris@0
|
24 $header = $stream->read(10);
|
Chris@0
|
25 $filenameHeaderLength = $this->getLengthOfPossibleFilenameHeader($stream, $header);
|
Chris@0
|
26 // Skip the header, that is 10 + length of filename + 1 (nil) bytes
|
Chris@0
|
27 $stream = new LimitStream($stream, -1, 10 + $filenameHeaderLength);
|
Chris@0
|
28 $resource = StreamWrapper::getResource($stream);
|
Chris@0
|
29 stream_filter_append($resource, 'zlib.inflate', STREAM_FILTER_READ);
|
Chris@17
|
30 $this->stream = $stream->isSeekable() ? new Stream($resource) : new NoSeekStream(new Stream($resource));
|
Chris@0
|
31 }
|
Chris@0
|
32
|
Chris@0
|
33 /**
|
Chris@0
|
34 * @param StreamInterface $stream
|
Chris@0
|
35 * @param $header
|
Chris@0
|
36 * @return int
|
Chris@0
|
37 */
|
Chris@0
|
38 private function getLengthOfPossibleFilenameHeader(StreamInterface $stream, $header)
|
Chris@0
|
39 {
|
Chris@0
|
40 $filename_header_length = 0;
|
Chris@0
|
41
|
Chris@0
|
42 if (substr(bin2hex($header), 6, 2) === '08') {
|
Chris@0
|
43 // we have a filename, read until nil
|
Chris@0
|
44 $filename_header_length = 1;
|
Chris@0
|
45 while ($stream->read(1) !== chr(0)) {
|
Chris@0
|
46 $filename_header_length++;
|
Chris@0
|
47 }
|
Chris@0
|
48 }
|
Chris@0
|
49
|
Chris@0
|
50 return $filename_header_length;
|
Chris@0
|
51 }
|
Chris@0
|
52 }
|