What steps will reproduce the problem?
RemoveBodyMiddleware empties the body for statuses like 204, but does not remove an existing Content-Length header:
private function removeBody(ResponseInterface $response): ResponseInterface
{
return $response->withBody(
$this->streamFactory->createStream(),
);
}
ContentLengthMiddleware also leaves a pre-existing Content-Length alone even on those statuses (shouldSkipContentLength returns early when the header is already set):
return !$this->add
|| $response->hasHeader('Content-Length')
|| in_array($response->getStatusCode(), $this->doNotAddOnStatusCode, true);
Minimal reproduce:
$response = $factory->createResponse(204)
->withHeader('Content-Length', '12')
->withBody($streamFactory->createStream('hello world!'));
$out = (new RemoveBodyMiddleware($streamFactory))->process($request, fn () => $response);
// body empty, Content-Length: 12 still present
Same problem after a typical pipeline: remove body -> then content-length middleware - existing Content-Length is still not stripped for 204.
What is the expected result?
For statuses where the body must not be sent (defaults include 1xx / 204 / 205 / 304), response must not advertise a non-matching Content-Length. Per RFC 9110 §8.6, a sender MUST NOT generate a Content-Length header field in 1xx (Informational) or 204 (No Content) responses.
After RemoveBodyMiddleware, at least Content-Length (and typically Transfer-Encoding) for those codes should be removed.
What do you get instead?
Empty body with leftover Content-Length: N -> inconsistent message (clients / proxies may mis-frame the connection).
Additional info
| Q |
A |
| Version |
yiisoft/http-middleware 1.2.0 |
| PHP version |
8.3 |
Suggested fix
In RemoveBodyMiddleware::removeBody() (and/or ContentLengthMiddleware for statuses in doNotAddOnStatusCode): withoutHeader('Content-Length') (and Transfer-Encoding if present) when body is removed / when status forbids length.
What steps will reproduce the problem?
RemoveBodyMiddlewareempties the body for statuses like204, but does not remove an existingContent-Lengthheader:ContentLengthMiddlewarealso leaves a pre-existingContent-Lengthalone even on those statuses (shouldSkipContentLengthreturns early when the header is already set):Minimal reproduce:
Same problem after a typical pipeline: remove body -> then content-length middleware - existing
Content-Lengthis still not stripped for 204.What is the expected result?
For statuses where the body must not be sent (defaults include 1xx / 204 / 205 / 304), response must not advertise a non-matching
Content-Length. Per RFC 9110 §8.6, a sender MUST NOT generate aContent-Lengthheader field in 1xx (Informational) or 204 (No Content) responses.After
RemoveBodyMiddleware, at leastContent-Length(and typicallyTransfer-Encoding) for those codes should be removed.What do you get instead?
Empty body with leftover
Content-Length: N-> inconsistent message (clients / proxies may mis-frame the connection).Additional info
yiisoft/http-middleware1.2.0Suggested fix
In
RemoveBodyMiddleware::removeBody()(and/orContentLengthMiddlewarefor statuses indoNotAddOnStatusCode):withoutHeader('Content-Length')(andTransfer-Encodingif present) when body is removed / when status forbids length.