symfony: MockResponse with empty body getContent(false) gives http_code 200, should be 0 or 204

Symfony version(s) affected: 4.4.1

Description

Perhaps I don’t understand how the MockResponse('') is intended, but an empty http response is either status code 0 (timeout or some such) or status code 204 No Content.

  • using $response->getStatusCode() always gives 200, which is always wrong, although should perhaps be possible to create if for some reason you create it that way in your API.
  • using $response->getContent(true) gives TransportException, which is wrong if a 204 was intended.
  • using $response->getContent(false) correctly gives an empty string ('')

How to reproduce

$responses = [
    new MockResponse('', ['http_code' => 0]), // transfer problem
    new MockResponse('', ['http_code' => 204]), // intended no content
    new MockResponse(''), // probably should default to statuscode=204
];

$client = new MockHttpClient($responses);

// each of the responses incorrectly gives a 200 response
foreach ($response as $res) {
    $response = $client->request('GET', 'http://some/url');
    $this->assertEquals(200, $response->getStatuscode(), 'should be 0 or 204 instead!');
}

Possible Solution
Change the order in the MockResponse constructor

$this->info = $info + ['http_code' => 200] + $this->info;

to

$this->info = ['http_code' => 200] + $info + $this->info;

Aside from this, in the ResponseTrait we have

line 144, this wil create a TransportException when no body. That seems fundamentally incorrect, as a 204 No Content is a real thing.

        if ('' === $content = $this->getContent($throw)) {
            throw new TransportException('Response body is empty.');
        }

line 249. This will trigger for http_code=0, why? At least for mocks this might be intended

        if (!$info['http_code']) {
            throw new TransportException('Invalid or missing HTTP status line.');
        }

Additional Context

All I’m really looking for actually is a way to mock a transfer problem… and in my code I use $response->getContent(false), so the only thing I can think of is look at the statusCode of 0

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 15 (15 by maintainers)

Most upvoted comments

Sorry for disturbing this issue…

@vasilvestre sadly, I’ve found another way to resolve my initial problem, so my application does not contain any code to trigger the bug either.

@nicolas-grekas fair point, but I still have to find any way to reproduce first 😛

@vasilvestre well, now I’m sad: my reproducer at https://github.com/NicoHaase/symfony-35007-reproducer shows that everything is alright 😦 Need to look into this again as soon as I come across this again, but currently, I cannot reproduce the problem myself which I was confident of four weeks ago