getsentry / responses

A utility for mocking out the Python Requests library.
Apache License 2.0
4.08k stars 347 forks source link

requests.head raises ChunkedEncodingError if header without content-length is sent #721

Open zepaz opened 3 weeks ago

zepaz commented 3 weeks ago

Describe the bug

When mocking requests.head() a ChunkedEncodingError is raised if you send something in the header but omit content-length in said header.

Additional context

No response

Version of responses

0.25.2

Steps to Reproduce

run pytest

import responses
import requests

@responses.activate
def test_get_head_success() -> None:
    """Tests a successful HEAD request."""
    responses.get(
        url="http://example.com/",
        body="hello world",
        match=[responses.matchers.header_matcher({"Accept": "text/plain"})],
    )

    responses.get(
        url="http://example.com/",
        json={"content": "hello world"},
        match=[responses.matchers.header_matcher({"Accept": "application/json"})],
    )
    responses.head(
        url="http://example.com/",
        json={"content": "hello world"},
        match=[responses.matchers.header_matcher({"Accept": "application/json"})],
    )
    responses.head(
        url="http://example.com/",
        body="hello world",
        match=[responses.matchers.header_matcher({"Accept": "text/plain"})],
    )
    responses.head(
        url="http://example.com/",
        match=[responses.matchers.header_matcher({"Accept": "text/html"})],
        status = 404,
    )
    # request in reverse order to how they were added!
    resp = requests.head("http://example.com/", headers={"Accept": "application/json"})
    assert resp.status_code == 200

    resp = request.head("http://example.com/", headers={"Accept": "text/html"})
    assert resp.status_code == 404

Expected Result

I would expect the test to succeed.

Actual Result

the test raises an ChunkedEncodingError

    def generate():
        # Special case for urllib3.
        if hasattr(self.raw, "stream"):
            try:
                yield from self.raw.stream(chunk_size, decode_content=True)
            except ProtocolError as e:
>               raise ChunkedEncodingError(e)
E               requests.exceptions.ChunkedEncodingError: ('Response may not contain content.', IncompleteRead(26 bytes read, -26 more expected))

..\..\..\..\venv\Lib\site-packages\requests\models.py:818: ChunkedEncodingError