friendship ended with social-app. php is my new best friend
1<?php
2
3namespace React\Http\Io;
4
5use Evenement\EventEmitter;
6use Psr\Http\Message\StreamInterface;
7use React\Stream\ReadableStreamInterface;
8use React\Stream\Util;
9use React\Stream\WritableStreamInterface;
10
11/**
12 * [Internal] Bridge between StreamInterface from PSR-7 and ReadableStreamInterface from ReactPHP
13 *
14 * This class is used in the server to stream the body of an incoming response
15 * from the client. This allows us to stream big amounts of data without having
16 * to buffer this data. Similarly, this used to stream the body of an outgoing
17 * request body to the client. The data will be sent directly to the client.
18 *
19 * Note that this is an internal class only and nothing you should usually care
20 * about. See the `StreamInterface` and `ReadableStreamInterface` for more
21 * details.
22 *
23 * @see StreamInterface
24 * @see ReadableStreamInterface
25 * @internal
26 */
27class HttpBodyStream extends EventEmitter implements StreamInterface, ReadableStreamInterface
28{
29 public $input;
30 private $closed = false;
31 private $size;
32
33 /**
34 * @param ReadableStreamInterface $input Stream data from $stream as a body of a PSR-7 object4
35 * @param int|null $size size of the data body
36 */
37 public function __construct(ReadableStreamInterface $input, $size)
38 {
39 $this->input = $input;
40 $this->size = $size;
41
42 $this->input->on('data', array($this, 'handleData'));
43 $this->input->on('end', array($this, 'handleEnd'));
44 $this->input->on('error', array($this, 'handleError'));
45 $this->input->on('close', array($this, 'close'));
46 }
47
48 public function isReadable()
49 {
50 return !$this->closed && $this->input->isReadable();
51 }
52
53 public function pause()
54 {
55 $this->input->pause();
56 }
57
58 public function resume()
59 {
60 $this->input->resume();
61 }
62
63 public function pipe(WritableStreamInterface $dest, array $options = array())
64 {
65 Util::pipe($this, $dest, $options);
66
67 return $dest;
68 }
69
70 public function close()
71 {
72 if ($this->closed) {
73 return;
74 }
75
76 $this->closed = true;
77
78 $this->input->close();
79
80 $this->emit('close');
81 $this->removeAllListeners();
82 }
83
84 public function getSize()
85 {
86 return $this->size;
87 }
88
89 /** @ignore */
90 public function __toString()
91 {
92 return '';
93 }
94
95 /** @ignore */
96 public function detach()
97 {
98 return null;
99 }
100
101 /** @ignore */
102 public function tell()
103 {
104 throw new \BadMethodCallException();
105 }
106
107 /** @ignore */
108 public function eof()
109 {
110 throw new \BadMethodCallException();
111 }
112
113 /** @ignore */
114 public function isSeekable()
115 {
116 return false;
117 }
118
119 /** @ignore */
120 public function seek($offset, $whence = SEEK_SET)
121 {
122 throw new \BadMethodCallException();
123 }
124
125 /** @ignore */
126 public function rewind()
127 {
128 throw new \BadMethodCallException();
129 }
130
131 /** @ignore */
132 public function isWritable()
133 {
134 return false;
135 }
136
137 /** @ignore */
138 public function write($string)
139 {
140 throw new \BadMethodCallException();
141 }
142
143 /** @ignore */
144 public function read($length)
145 {
146 throw new \BadMethodCallException();
147 }
148
149 /** @ignore */
150 public function getContents()
151 {
152 return '';
153 }
154
155 /** @ignore */
156 public function getMetadata($key = null)
157 {
158 return null;
159 }
160
161 /** @internal */
162 public function handleData($data)
163 {
164 $this->emit('data', array($data));
165 }
166
167 /** @internal */
168 public function handleError(\Exception $e)
169 {
170 $this->emit('error', array($e));
171 $this->close();
172 }
173
174 /** @internal */
175 public function handleEnd()
176 {
177 if (!$this->closed) {
178 $this->emit('end');
179 $this->close();
180 }
181 }
182}