Skip to content

Commit 03838e2

Browse files
committed
Fix issue with rewound response bodies
When middleware returns an `HtmlResponse`, the body stream is typically rewound, with the pointer at position 0. Unfortunately, this means that any `write()` operations will *overwrite*! This patch does a check to see if the response is at `eof()`, and, if not and the response is seekable, sets the pointer to the end of the stream prior to writing.
1 parent c6fe7aa commit 03838e2

File tree

2 files changed

+26
-1
lines changed

2 files changed

+26
-1
lines changed

Diff for: src/PhpDebugBarMiddleware.php

+5-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,11 @@ public function __invoke(ServerRequestInterface $request, ResponseInterface $res
4848
$debugBarBody = $this->debugBarRenderer->render();
4949

5050
if ($this->isHtmlResponse($outResponse)) {
51-
$outResponse->getBody()->write($debugBarHead . $debugBarBody);
51+
$body = $outResponse->getBody();
52+
if (! $body->eof() && $body->isSeekable()) {
53+
$body->seek(0, SEEK_END);
54+
}
55+
$body->write($debugBarHead . $debugBarBody);
5256

5357
return $outResponse;
5458
}

Diff for: test/PhpDebugBarMiddlewareTest.php

+21
Original file line numberDiff line numberDiff line change
@@ -80,4 +80,25 @@ public function testAttachToHtmlResponse()
8080
$this->assertSame($response, $result);
8181
$this->assertSame("ResponseBodyRenderHeadRenderBody", (string) $result->getBody());
8282
}
83+
84+
public function testAppendsToEndOfHtmlResponse()
85+
{
86+
$html = '<html><head><title>Foo</title></head><body>Content</body>';
87+
$request = new ServerRequest([], [], null, null, 'php://input', ['Accept' => 'text/html']);
88+
$response = new Response\HtmlResponse($html);
89+
$calledOut = false;
90+
$outFunction = function ($request, $response) use (&$calledOut) {
91+
$calledOut = true;
92+
return $response;
93+
};
94+
95+
$this->debugbarRenderer->expects($this->once())->method('renderHead')->willReturn('RenderHead');
96+
$this->debugbarRenderer->expects($this->once())->method('render')->willReturn('RenderBody');
97+
98+
$result = call_user_func($this->middleware, $request, $response, $outFunction);
99+
100+
$this->assertTrue($calledOut, 'Out is not called');
101+
$this->assertSame($response, $result);
102+
$this->assertSame($html . 'RenderHeadRenderBody', (string) $result->getBody());
103+
}
83104
}

0 commit comments

Comments
 (0)