Skip to content

Commit b685a2a

Browse files
authored
Merge pull request #291 from clue-labs/happy-empty
Improve performance by skipping buffering empty request body
2 parents c412846 + 1c31d20 commit b685a2a

File tree

2 files changed

+54
-5
lines changed

2 files changed

+54
-5
lines changed

src/Middleware/RequestBodyBufferMiddleware.php

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,12 @@ public function __construct($sizeLimit = null)
3232
public function __invoke(ServerRequestInterface $request, $stack)
3333
{
3434
$body = $request->getBody();
35+
$size = $body->getSize();
3536

36-
// skip if body is already buffered
37-
if (!$body instanceof ReadableStreamInterface) {
38-
// replace with empty buffer if size limit is exceeded
39-
if ($body->getSize() > $this->sizeLimit) {
37+
// happy path: skip if body is known to be empty (or is already buffered)
38+
if ($size === 0 || !$body instanceof ReadableStreamInterface) {
39+
// replace with empty body if body is streaming (or buffered size exceeds limit)
40+
if ($body instanceof ReadableStreamInterface || $size > $this->sizeLimit) {
4041
$request = $request->withBody(new BufferStream(0));
4142
}
4243

@@ -45,7 +46,7 @@ public function __invoke(ServerRequestInterface $request, $stack)
4546

4647
// request body of known size exceeding limit
4748
$sizeLimit = $this->sizeLimit;
48-
if ($body->getSize() > $this->sizeLimit) {
49+
if ($size > $this->sizeLimit) {
4950
$sizeLimit = 0;
5051
}
5152

tests/Middleware/RequestBodyBufferMiddlewareTest.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,54 @@ function (ServerRequestInterface $request) use (&$exposedRequest) {
6868
$this->assertSame($body, $exposedRequest->getBody()->getContents());
6969
}
7070

71+
public function testEmptyStreamingResolvesImmediatelyWithEmptyBufferedBody()
72+
{
73+
$stream = new ThroughStream();
74+
$serverRequest = new ServerRequest(
75+
'GET',
76+
'https://example.com/',
77+
array(),
78+
$body = new HttpBodyStream($stream, 0)
79+
);
80+
81+
$exposedRequest = null;
82+
$buffer = new RequestBodyBufferMiddleware();
83+
$buffer(
84+
$serverRequest,
85+
function (ServerRequestInterface $request) use (&$exposedRequest) {
86+
$exposedRequest = $request;
87+
}
88+
);
89+
90+
$this->assertSame(0, $exposedRequest->getBody()->getSize());
91+
$this->assertSame('', $exposedRequest->getBody()->getContents());
92+
$this->assertNotSame($body, $exposedRequest->getBody());
93+
}
94+
95+
public function testEmptyBufferedResolvesImmediatelyWithSameBody()
96+
{
97+
$serverRequest = new ServerRequest(
98+
'GET',
99+
'https://example.com/',
100+
array(),
101+
''
102+
);
103+
$body = $serverRequest->getBody();
104+
105+
$exposedRequest = null;
106+
$buffer = new RequestBodyBufferMiddleware();
107+
$buffer(
108+
$serverRequest,
109+
function (ServerRequestInterface $request) use (&$exposedRequest) {
110+
$exposedRequest = $request;
111+
}
112+
);
113+
114+
$this->assertSame(0, $exposedRequest->getBody()->getSize());
115+
$this->assertSame('', $exposedRequest->getBody()->getContents());
116+
$this->assertSame($body, $exposedRequest->getBody());
117+
}
118+
71119
public function testKnownExcessiveSizedBodyIsDisgardedTheRequestIsPassedDownToTheNextMiddleware()
72120
{
73121
$loop = Factory::create();

0 commit comments

Comments
 (0)