Skip to content

Do not send a response body for 204/304, per RFC 9110 - #156

Open
bcordis wants to merge 1 commit into
joomla-framework:3.x-devfrom
bcordis:fix-204-304-body
Open

bcordis wants to merge 1 commit into
joomla-framework:3.x-devfrom
bcordis:fix-204-304-body

Conversation

@bcordis

@bcordis bcordis commented Oct 2, 2026

Copy link
Copy Markdown

Summary

respond() unconditionally echoes the response body regardless of status code. Per RFC 9110 §15.3.5 (204 No Content) and §15.4.5 (304 Not Modified), neither response may include a message body.

Also skips the Content-Type header specifically for 204, since a 204 has no representation to describe. 304 deliberately keeps it -- per §15.4.5 a 304 is expected to carry the same representation metadata headers the 200 it validates would have sent; only the body is withheld.

Found via

A real Joomla CMS API DELETE, on Joomla 5 (which pins this package at ^3.0): PHP's built-in dev server plus a strict HTTP/1.1 client (Playwright's Node HTTP client) fails to parse the response at all (Parse Error: Data after \Connection: close``), because the 204 carries a non-empty JSON:API body. Apache is more lenient about the extra bytes, which is likely why this has gone unnoticed in practice.

Reported at joomla/joomla-cms#48553, traced to this package per @brianteeman's comment there.

Testing

Two new tests added, mirroring the existing testRespond()/testRespondWithAllowedCaching() pattern (adapted to this branch's getMockForAbstractClass() convention): one asserting no body and no Content-Type for 204, one asserting no body but Content-Type preserved for 304. Full existing suite still passes (same 5 pre-existing, unrelated failures present on a clean 3.x-dev checkout before this change too -- confirmed via git stash).

Note: this branch's composer.json caps laminas/laminas-diactoros below PHP 8.4 support; verified locally with --ignore-platform-reqs since that's an environment constraint unrelated to this change.

Companion PR

Same fix on 4.x-dev: #155

respond() unconditionally echoed the response body regardless of
status code. Per RFC 9110 §15.3.5 (204 No Content) and §15.4.5 (304
Not Modified), neither response may include a message body.

Confirmed via a real Joomla CMS API DELETE: PHP's built-in dev server
plus a strict HTTP/1.1 client (Playwright's Node HTTP client) fails to
parse the response at all ("Parse Error: Data after `Connection:
close`"), because a 204 is carrying a non-empty JSON:API body. Apache
is more lenient about the extra bytes, which is likely why this has
gone unnoticed.

Also skips the Content-Type header specifically for 204, since a 204
has no representation to describe. 304 keeps it deliberately -- per
RFC 9110 §15.4.5 a 304 is expected to carry the same representation
metadata headers the 200 it validates would have sent; only the body
is withheld.

Reported at joomla/joomla-cms#48553, traced
upstream to this package per @brianteeman's comment there.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant