friendship ended with social-app. php is my new best friend
1<?php
2
3namespace React\Http\Io;
4
5use Evenement\EventEmitter;
6use React\Stream\ReadableStreamInterface;
7use React\Stream\Util;
8use React\Stream\WritableStreamInterface;
9
10/**
11 * [Internal] Limits the amount of data the given stream can emit
12 *
13 * This is used internally to limit the size of the underlying connection stream
14 * to the size defined by the "Content-Length" header of the incoming request.
15 *
16 * @internal
17 */
18class LengthLimitedStream extends EventEmitter implements ReadableStreamInterface
19{
20 private $stream;
21 private $closed = false;
22 private $transferredLength = 0;
23 private $maxLength;
24
25 public function __construct(ReadableStreamInterface $stream, $maxLength)
26 {
27 $this->stream = $stream;
28 $this->maxLength = $maxLength;
29
30 $this->stream->on('data', array($this, 'handleData'));
31 $this->stream->on('end', array($this, 'handleEnd'));
32 $this->stream->on('error', array($this, 'handleError'));
33 $this->stream->on('close', array($this, 'close'));
34 }
35
36 public function isReadable()
37 {
38 return !$this->closed && $this->stream->isReadable();
39 }
40
41 public function pause()
42 {
43 $this->stream->pause();
44 }
45
46 public function resume()
47 {
48 $this->stream->resume();
49 }
50
51 public function pipe(WritableStreamInterface $dest, array $options = array())
52 {
53 Util::pipe($this, $dest, $options);
54
55 return $dest;
56 }
57
58 public function close()
59 {
60 if ($this->closed) {
61 return;
62 }
63
64 $this->closed = true;
65
66 $this->stream->close();
67
68 $this->emit('close');
69 $this->removeAllListeners();
70 }
71
72 /** @internal */
73 public function handleData($data)
74 {
75 if (($this->transferredLength + \strlen($data)) > $this->maxLength) {
76 // Only emit data until the value of 'Content-Length' is reached, the rest will be ignored
77 $data = (string)\substr($data, 0, $this->maxLength - $this->transferredLength);
78 }
79
80 if ($data !== '') {
81 $this->transferredLength += \strlen($data);
82 $this->emit('data', array($data));
83 }
84
85 if ($this->transferredLength === $this->maxLength) {
86 // 'Content-Length' reached, stream will end
87 $this->emit('end');
88 $this->close();
89 $this->stream->removeListener('data', array($this, 'handleData'));
90 }
91 }
92
93 /** @internal */
94 public function handleError(\Exception $e)
95 {
96 $this->emit('error', array($e));
97 $this->close();
98 }
99
100 /** @internal */
101 public function handleEnd()
102 {
103 if (!$this->closed) {
104 $this->handleError(new \Exception('Unexpected end event'));
105 }
106 }
107
108}