Skip to content

invalid Transfer-Encoding header for 1xx and 204 responses #2375

@alexrashed

Description

@alexrashed

With werkzeug 2.1.0, the connection / transfer-encoding handling changed a bit (#2091).
Werkzeug now sends a Transfer-Encoding: chunked instead of a Connection: close (when using HTTP1.1).
A later commit removed a check where this was only done for certain responses (d062807).
Unfortunately I'm experiencing issues on clients (and tests) with the upgrade, as it seems that this behavior now is directly violating RFC 7230 / HTTP 1.1:

A server MUST NOT send a Transfer-Encoding header field in any response with a status code of 1xx (Informational) or 204 (No Content). A server MUST NOT send a Transfer-Encoding header field in any 2xx (Successful) response to a CONNECT request (Section 4.3.6 of [RFC7231]).

This can easily be reproduced with a simple Flask server:

from flask import Flask, Response
from flask_cors import CORS

app = Flask(__name__)

@app.route("/", methods=["DELETE"])
def empty_response():
    return Response("", status=204)

if __name__ == "__main__":
    app.run()

With Werkzeug/Flask 2.0.3, a response would look as follows (mind HTTP 1.0 and the absence of the Transfer-Encoding header):

Hypertext Transfer Protocol
    HTTP/1.0 204 NO CONTENT\r\n
    Content-Type: text/html; charset=utf-8\r\n
    Access-Control-Allow-Origin: *\r\n
    Server: Werkzeug/2.0.3 Python/3.8.10\r\n
    Date: Mon, 04 Apr 2022 08:30:26 GMT\r\n
    \r\n

With Werkzeug/Flask 2.1.1, a response now looks like this:

Hypertext Transfer Protocol
    HTTP/1.1 204 NO CONTENT\r\n
    Server: Werkzeug/2.1.1 Python/3.8.10\r\n
    Date: Mon, 04 Apr 2022 08:42:24 GMT\r\n
    Content-Type: text/html; charset=utf-8\r\n
    Transfer-Encoding: chunked\r\n
    \r\n

I would expect Werkzeug to not set the Transfer-Encoding header for responses with 1xx and 204 status codes.
This could easily be done by re-adding the check which was removed with d062807 when checking if the Transfer-Encoding header should be set here:

if self.protocol_version >= "HTTP/1.1":

Environment:

  • Python version: 3.8.10
  • Werkzeug version: 2.1.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions