pallets / flask

The Python micro framework for building web applications.

Home Page:https://flask.palletsprojects.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

transfer-encoding: debug server behavior differs from test client

bdc34 opened this issue · comments

With code like:

resp = make_response(file.open("rb")) return resp

the debug server automatically kicks into transfer-encoding chunked mode:

curl -svo /dev/null -X GET localhost:8080/src/cond-mat/9805021 2>&1 | grep "^<"
< HTTP/1.1 200 OK
< Server: Werkzeug/2.3.7 Python/3.11.2
< Date: Thu, 29 Feb 2024 21:14:59 GMT
< Transfer-Encoding: chunked
< Connection: close`

but in a unit test it does not go into Transfer-Encoding chunked mode or the header is missing:


client_with_test_fs = <FlaskClient <Flask 'browse'>>, path = '/src/', paperid = 'cond-mat/9805021'
expected_file = 'arXiv-cond-mat9805021v2.gz', desc = 'single file .gz'

    @pytest.mark.parametrize("path,paperid,expected_file,desc", [ ["/src/"]+c for c in cases] )
    def test_src(client_with_test_fs, path, paperid, expected_file, desc ):
        client = client_with_test_fs
        resp = client.get(path + paperid)
        assert resp
        assert resp.status_code == 200
>       assert resp.headers["Transfer-Encoding"] == "chunked" # Must do chunked on a raw get for Cloud run large obj

tests/test_src.py:70: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = Headers([])
key = 'Transfer-Encoding', _get_mode = False

    def __getitem__(self, key, _get_mode=False):
        if not _get_mode:
            if isinstance(key, int):
                return self._list[key]
            elif isinstance(key, slice):
                return self.__class__(self._list[key])
        if not isinstance(key, str):
            raise BadRequestKeyError(key)
        ikey = key.lower()
        for k, v in self._list:
            if k.lower() == ikey:
                return v
        # micro optimization: if we are in get mode we will catch that
        # exception one stack level down so we can raise a standard
        # key error instead of our special one.
        if _get_mode:
            raise KeyError()
>       raise BadRequestKeyError(key)
E       werkzeug.exceptions.BadRequestKeyError: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand.

../../.pyenv/versions/3.11.2/envs/browse-311/lib/python3.11/site-packages/werkzeug/datastructures/headers.py:73: BadRequestKeyError              
`


I would expect the debug server and the test client to work the same.

Environment:

- Python version:  3.11
- Flask version: 2.2.5

Whether Transfer-Encoding: chunked is used is a property of any given WSGI server in front of the application. It's not something Flask/Werkzeug the WSGI application chooses, it's something the server chooses. Besides the presence of the header, there should be no difference in the data received in the response, so there's no reason to test if the encoding was chunked. That would be testing the behavior of the server, not of the application.