vapor/vapor

HEAD response should allow non-zero Content-Length

Opened this issue · 3 comments

Describe the issue

HTTPHeaders.updateContentLength(_:) overrides the “Content-Length” value provided in the response headers with the size of the body (0) in contravention of RFC9110.

Vapor version

4.92.3

Operating system and version

14.4.1

Swift version

Swift Package Manager - Swift 5.10.0-dev

Steps to reproduce

  1. Perform a HEAD request for a resource with a non-zero content length
  2. Set the "Content-Length" header of the 200 response with the size of the resource in bytes
  3. Observe the response includes the header content-length: 0 instead of the expected non-zero value.

Outcome

Vapor responses to HEAD requests do not behave according to the RFC and the required functionality from non-zero Content-Length headers in HEAD responses cannot be achieved.

Additional notes

In https://www.rfc-editor.org/rfc/rfc9110.html#section-9.3.2 the statement

The HEAD method is identical to GET except that the server MUST NOT send content in the response.

which is in agreement with https://www.rfc-editor.org/rfc/rfc9110.html#section-8.6-6

A server MAY send a Content-Length header field in a response to a HEAD request (Section 9.3.2); a server MUST NOT send Content-Length in such a response unless its field value equals the decimal number of octets that would have been sent in the content of a response if the same request had used the GET method.

HTTPHeaders.updateContentLength(_:) overrides the “Content-Length” value provided in the response headers with the size of the body (0) in contravention of RFC9110.

This prevents HEAD responses from behaving correctly.

#2749 may be an existing report of the same issue, with an incomplete (?) fix available #3147

The workaround from #3084 of adding the header value after creating the response works, but is non-obvious and should not be necessary to be compliant with the RFC.