Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/aphront/requeststream/AphrontRequestStream.php
12241 views
1
<?php
2
3
final class AphrontRequestStream extends Phobject {
4
5
private $encoding;
6
private $stream;
7
private $closed;
8
private $iterator;
9
10
public function setEncoding($encoding) {
11
$this->encoding = $encoding;
12
return $this;
13
}
14
15
public function getEncoding() {
16
return $this->encoding;
17
}
18
19
public function getIterator() {
20
if (!$this->iterator) {
21
$this->iterator = new PhutilStreamIterator($this->getStream());
22
}
23
return $this->iterator;
24
}
25
26
public function readData() {
27
if (!$this->iterator) {
28
$iterator = $this->getIterator();
29
$iterator->rewind();
30
} else {
31
$iterator = $this->getIterator();
32
}
33
34
if (!$iterator->valid()) {
35
return null;
36
}
37
38
$data = $iterator->current();
39
$iterator->next();
40
41
return $data;
42
}
43
44
private function getStream() {
45
if (!$this->stream) {
46
$this->stream = $this->newStream();
47
}
48
49
return $this->stream;
50
}
51
52
private function newStream() {
53
$stream = fopen('php://input', 'rb');
54
if (!$stream) {
55
throw new Exception(
56
pht(
57
'Failed to open stream "%s" for reading.',
58
'php://input'));
59
}
60
61
$encoding = $this->getEncoding();
62
if ($encoding === 'gzip') {
63
// This parameter is magic. Values 0-15 express a time/memory tradeoff,
64
// but the largest value (15) corresponds to only 32KB of memory and
65
// data encoded with a smaller window size than the one we pass can not
66
// be decompressed. Always pass the maximum window size.
67
68
// Additionally, you can add 16 (to enable gzip) or 32 (to enable both
69
// gzip and zlib). Add 32 to support both.
70
$zlib_window = 15 + 32;
71
72
$ok = stream_filter_append(
73
$stream,
74
'zlib.inflate',
75
STREAM_FILTER_READ,
76
array(
77
'window' => $zlib_window,
78
));
79
if (!$ok) {
80
throw new Exception(
81
pht(
82
'Failed to append filter "%s" to input stream while processing '.
83
'a request with "%s" encoding.',
84
'zlib.inflate',
85
$encoding));
86
}
87
}
88
89
return $stream;
90
}
91
92
public static function supportsGzip() {
93
if (!function_exists('gzencode') || !function_exists('gzdecode')) {
94
return false;
95
}
96
97
$has_zlib = false;
98
99
// NOTE: At least locally, this returns "zlib.*", which is not terribly
100
// reassuring. We care about "zlib.inflate".
101
102
$filters = stream_get_filters();
103
foreach ($filters as $filter) {
104
if (!strncasecmp($filter, 'zlib.', strlen('zlib.'))) {
105
$has_zlib = true;
106
break;
107
}
108
}
109
110
return $has_zlib;
111
}
112
113
}
114
115