Unleash/unleash-client-php

Bug: DefaultUnleashRepository fails to read entire response body

colinodell opened this issue · 0 comments

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

The DefaultUnleashRepository uses this code to read the response body:

$response = $this->httpClient->sendRequest($request);
if ($response->getStatusCode() === 200) {
$data = $response->getBody()->getContents();
$this->setLastValidState($data);
}

The getContents() method reads "the remaining contents" of the response body. This causes issues when the user supplies a Guzzle instance with middleware that also reads the response body, because the middleware will have read the body through the end of the stream, thus setting the current position at the end of the stream so that all future calls to getContents() will return an empty string.

As a result, the current code to read the response body may produce an empty string which then causes a JsonException : Syntax error later on.

To reproduce

Create an Unleash instance with a user-supplied Guzzle client containing any middleware that reads the response body. It could be Guzzle's Middleware::log() or even something as simple as this:

// Guzzle's `mapResponse()` helper is used to create middleware that manipulates responses
Middleware::mapResponse(
    static function ($response) {
        // Simply read the response body, causing the stream to seek to the end, and return the response as-is
        $response->getBody()->getContents();
        return $response;
    }
)

Sample code (optional)

No response

Version

v1.8.081

Expected behavior

The code should always read the stream from the start because it's possible something else has read the stream first

Logs (optional)

No response

Additional context (optional)

I plan to submit a PR to fix this shortly :)