Skip to content

Commit 4e8d254

Browse files
committed
RequestBodyParserMiddleware does not reject requests that exceed post_max_size
1 parent f3eb11e commit 4e8d254

File tree

2 files changed

+55
-23
lines changed

2 files changed

+55
-23
lines changed

src/Middleware/RequestBodyBufferMiddleware.php

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22

33
namespace React\Http\Middleware;
44

5+
use OverflowException;
56
use Psr\Http\Message\ServerRequestInterface;
6-
use React\Http\Response;
7+
use React\Promise\Promise;
78
use React\Promise\Stream;
89
use React\Stream\ReadableStreamInterface;
910
use RingCentral\Psr7\BufferStream;
10-
use OverflowException;
1111

1212
final class RequestBodyBufferMiddleware
1313
{
@@ -30,27 +30,35 @@ public function __construct($sizeLimit = null)
3030

3131
public function __invoke(ServerRequestInterface $request, $stack)
3232
{
33+
$sizeLimit = $this->sizeLimit;
3334
$body = $request->getBody();
3435

3536
// request body of known size exceeding limit
3637
if ($body->getSize() > $this->sizeLimit) {
37-
return new Response(413, array('Content-Type' => 'text/plain'), 'Request body exceeds allowed limit');
38+
$sizeLimit = 0;
3839
}
3940

4041
if (!$body instanceof ReadableStreamInterface) {
4142
return $stack($request);
4243
}
4344

44-
return Stream\buffer($body, $this->sizeLimit)->then(function ($buffer) use ($request, $stack) {
45+
return Stream\buffer($body, $sizeLimit)->then(function ($buffer) use ($request, $stack) {
4546
$stream = new BufferStream(strlen($buffer));
4647
$stream->write($buffer);
4748
$request = $request->withBody($stream);
4849

4950
return $stack($request);
50-
}, function($error) {
51+
}, function ($error) use ($stack, $request, $body) {
5152
// request body of unknown size exceeding limit during buffering
5253
if ($error instanceof OverflowException) {
53-
return new Response(413, array('Content-Type' => 'text/plain'), 'Request body exceeds allowed limit');
54+
return new Promise(function ($resolve, $reject) use ($stack, $request, $body) {
55+
$body->on('error', function ($error) use ($reject) {
56+
$reject($error);
57+
});
58+
$body->on('close', function () use ($stack, $request, $resolve) {
59+
$resolve($stack($request));
60+
});
61+
});
5462
}
5563

5664
throw $error;

tests/Middleware/RequestBodyBufferMiddlewareTest.php

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,16 @@
22

33
namespace React\Tests\Http\Middleware;
44

5+
use Clue\React\Block;
56
use Psr\Http\Message\ServerRequestInterface;
67
use React\EventLoop\Factory;
78
use React\Http\Io\HttpBodyStream;
89
use React\Http\Io\ServerRequest;
910
use React\Http\Middleware\RequestBodyBufferMiddleware;
11+
use React\Http\Response;
1012
use React\Stream\ThroughStream;
1113
use React\Tests\Http\TestCase;
1214
use RingCentral\Psr7\BufferStream;
13-
use Clue\React\Block;
1415

1516
final class RequestBodyBufferMiddlewareTest extends TestCase
1617
{
@@ -65,7 +66,7 @@ function (ServerRequestInterface $request) use (&$exposedRequest) {
6566
$this->assertSame($body, $exposedRequest->getBody()->getContents());
6667
}
6768

68-
public function testExcessiveSizeImmediatelyReturnsError413ForKnownSize()
69+
public function testKnownExcessiveSizedBodyIsDisgardedTheRequestIsPassedDownToTheNextMiddleware()
6970
{
7071
$loop = Factory::create();
7172

@@ -79,17 +80,18 @@ public function testExcessiveSizeImmediatelyReturnsError413ForKnownSize()
7980
);
8081

8182
$buffer = new RequestBodyBufferMiddleware(1);
82-
$response = $buffer(
83+
$response = Block\await($buffer(
8384
$serverRequest,
8485
function (ServerRequestInterface $request) {
85-
return $request;
86+
return new Response(200, array(), $request->getBody()->getContents());
8687
}
87-
);
88+
), $loop);
8889

89-
$this->assertSame(413, $response->getStatusCode());
90+
$this->assertSame(200, $response->getStatusCode());
91+
$this->assertSame('', $response->getBody()->getContents());
9092
}
9193

92-
public function testExcessiveSizeReturnsError413()
94+
public function testExcessiveSizeBodyIsDisgardedTheRequestIsPassedDownToTheNextMiddleware()
9395
{
9496
$loop = Factory::create();
9597

@@ -105,23 +107,19 @@ public function testExcessiveSizeReturnsError413()
105107
$promise = $buffer(
106108
$serverRequest,
107109
function (ServerRequestInterface $request) {
108-
return $request;
110+
return new Response(200, array(), $request->getBody()->getContents());
109111
}
110112
);
111113

112114
$stream->end('aa');
113115

114-
$exposedResponse = null;
115-
$promise->then(
116-
function($response) use (&$exposedResponse) {
117-
$exposedResponse = $response;
118-
},
116+
$exposedResponse = Block\await($promise->then(
117+
null,
119118
$this->expectCallableNever()
120-
);
121-
122-
$this->assertSame(413, $exposedResponse->getStatusCode());
119+
), $loop);
123120

124-
Block\await($promise, $loop);
121+
$this->assertSame(200, $exposedResponse->getStatusCode());
122+
$this->assertSame('', $exposedResponse->getBody()->getContents());
125123
}
126124

127125
/**
@@ -151,4 +149,30 @@ function (ServerRequestInterface $request) {
151149

152150
Block\await($promise, $loop);
153151
}
152+
153+
public function testFullBodyStreamedBeforeCallingNextMiddleware()
154+
{
155+
$promiseResolved = false;
156+
$middleware = new RequestBodyBufferMiddleware(3);
157+
$stream = new ThroughStream();
158+
$serverRequest = new ServerRequest(
159+
'GET',
160+
'https://example.com/',
161+
array(),
162+
new HttpBodyStream($stream, null)
163+
);
164+
165+
$middleware($serverRequest, function () {
166+
return new Response();
167+
})->then(function () use (&$promiseResolved) {
168+
$promiseResolved = true;
169+
});
170+
171+
$stream->write('aaa');
172+
$this->assertFalse($promiseResolved);
173+
$stream->write('aaa');
174+
$this->assertFalse($promiseResolved);
175+
$stream->end('aaa');
176+
$this->assertTrue($promiseResolved);
177+
}
154178
}

0 commit comments

Comments
 (0)