Skip to content

Commit 6fec25b

Browse files
committed
Keep request body in memory also after consuming request body
1 parent a19a34d commit 6fec25b

File tree

2 files changed

+70
-9
lines changed

2 files changed

+70
-9
lines changed

src/Middleware/RequestBodyBufferMiddleware.php

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44

55
use OverflowException;
66
use Psr\Http\Message\ServerRequestInterface;
7+
use React\Http\Io\BufferedBody;
78
use React\Http\Io\IniUtil;
89
use React\Promise\Stream;
910
use React\Stream\ReadableStreamInterface;
10-
use RingCentral\Psr7\BufferStream;
1111

1212
final class RequestBodyBufferMiddleware
1313
{
@@ -38,7 +38,7 @@ public function __invoke(ServerRequestInterface $request, $stack)
3838
if ($size === 0 || !$body instanceof ReadableStreamInterface) {
3939
// replace with empty body if body is streaming (or buffered size exceeds limit)
4040
if ($body instanceof ReadableStreamInterface || $size > $this->sizeLimit) {
41-
$request = $request->withBody(new BufferStream(0));
41+
$request = $request->withBody(new BufferedBody(''));
4242
}
4343

4444
return $stack($request);
@@ -51,9 +51,7 @@ public function __invoke(ServerRequestInterface $request, $stack)
5151
}
5252

5353
return Stream\buffer($body, $sizeLimit)->then(function ($buffer) use ($request, $stack) {
54-
$stream = new BufferStream(\strlen($buffer));
55-
$stream->write($buffer);
56-
$request = $request->withBody($stream);
54+
$request = $request->withBody(new BufferedBody($buffer));
5755

5856
return $stack($request);
5957
}, function ($error) use ($stack, $request, $body) {

tests/ServerTest.php

Lines changed: 67 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,35 @@ function (ServerRequestInterface $request) use (&$called) {
110110
$this->assertSame('beforeokafter', $called);
111111
}
112112

113+
public function testPostFormData()
114+
{
115+
$loop = Factory::create();
116+
$deferred = new Deferred();
117+
$server = new Server($loop, function (ServerRequestInterface $request) use ($deferred) {
118+
$deferred->resolve($request);
119+
});
120+
121+
$server->listen($this->socket);
122+
$this->socket->emit('connection', array($this->connection));
123+
$this->connection->emit('data', array("POST / HTTP/1.0\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 7\r\n\r\nfoo=bar"));
124+
125+
$request = Block\await($deferred->promise(), $loop);
126+
assert($request instanceof ServerRequestInterface);
127+
128+
$form = $request->getParsedBody();
129+
130+
$this->assertTrue(isset($form['foo']));
131+
$this->assertEquals('bar', $form['foo']);
132+
133+
$this->assertEquals(array(), $request->getUploadedFiles());
134+
135+
$body = $request->getBody();
136+
137+
$this->assertSame(7, $body->getSize());
138+
$this->assertSame(7, $body->tell());
139+
$this->assertSame('foo=bar', (string) $body);
140+
}
141+
113142
public function testPostFileUpload()
114143
{
115144
$loop = Factory::create();
@@ -132,18 +161,52 @@ public function testPostFileUpload()
132161
}
133162
});
134163

135-
$parsedRequest = Block\await($deferred->promise(), $loop);
136-
$this->assertNotEmpty($parsedRequest->getUploadedFiles());
137-
$this->assertEmpty($parsedRequest->getParsedBody());
164+
$request = Block\await($deferred->promise(), $loop);
165+
assert($request instanceof ServerRequestInterface);
166+
167+
$this->assertEmpty($request->getParsedBody());
168+
169+
$this->assertNotEmpty($request->getUploadedFiles());
138170

139-
$files = $parsedRequest->getUploadedFiles();
171+
$files = $request->getUploadedFiles();
140172

141173
$this->assertTrue(isset($files['file']));
142174
$this->assertCount(1, $files);
143175

144176
$this->assertSame('hello.txt', $files['file']->getClientFilename());
145177
$this->assertSame('text/plain', $files['file']->getClientMediaType());
146178
$this->assertSame("hello\r\n", (string)$files['file']->getStream());
179+
180+
$body = $request->getBody();
181+
182+
$this->assertSame(220, $body->getSize());
183+
$this->assertSame(220, $body->tell());
184+
}
185+
186+
public function testPostJsonWillNotBeParsedByDefault()
187+
{
188+
$loop = Factory::create();
189+
$deferred = new Deferred();
190+
$server = new Server($loop, function (ServerRequestInterface $request) use ($deferred) {
191+
$deferred->resolve($request);
192+
});
193+
194+
$server->listen($this->socket);
195+
$this->socket->emit('connection', array($this->connection));
196+
$this->connection->emit('data', array("POST / HTTP/1.0\r\nContent-Type: application/json\r\nContent-Length: 6\r\n\r\n[true]"));
197+
198+
$request = Block\await($deferred->promise(), $loop);
199+
assert($request instanceof ServerRequestInterface);
200+
201+
$this->assertNull($request->getParsedBody());
202+
203+
$this->assertSame(array(), $request->getUploadedFiles());
204+
205+
$body = $request->getBody();
206+
207+
$this->assertSame(6, $body->getSize());
208+
$this->assertSame(0, $body->tell());
209+
$this->assertSame('[true]', (string) $body);
147210
}
148211

149212
public function testServerReceivesBufferedRequestByDefault()

0 commit comments

Comments
 (0)