Problem with HttpClient and API request

Hi there,

I’m trying to get every realm by requesting the wow’s API.

My code :

public function getRealms()
{
    $response = $this->client->request(
        'GET',
        'https://eu.api.blizzard.com/data/wow/realm/index',
        [
            'auth_bearer' => $this->auth_bearer,
            'headers' => [
                'Cache-Control' => 'no-cache',
                'Connection' => 'keep-alive'
            ],
            'query' => [
                'namespace' => 'dynamic-eu',
                'locale' => 'en_EN'
            ]
        ]
    );

    $statusCode = $response->getStatusCode();
    dump($statusCode); // show "200"

    $contentType = $response->getHeaders()['content-type'][0];
    dump($contentType); // show "application/json;charset=UTF-8"

    $contentArray = $response->toArray(); // <== TIMEOUT ERROR 
    dump($contentArray); 

    return $contentArray;
}

And after default timeout I get this error

Idle timeout reached for “https:// eu.api.blizzard .com/data/wow/realm/index?namespace=dynamic-eu&locale=en_EN”.

I do not understand why I’m getting this error while I’m getting a 200 success code. I’m using HttpClient which is embedded with Symfony framework. And my function is on a service class.

Any ideas ?

EDIT : I’m testing every request with Postman. And it works on Postman. And I tested with more items on another API (500+ items), this function works fine.

My guess it has something to do with the content you are expecting. On top-level this is not an array, but an object containing a property (“realms”) which is an array.
I am not familiar with Symfony or its HttpClient. But most examples will call $response->getContent() before proceeding.

1 Like

I would try changing the Connection header to close instead of keep-alive. I remember people had some trouble with the API server not closing the connection properly before.

1 Like

Hi ! Thank’s for the help ! I tried with getContent() before that and it leads to the same trouble.

I changed my code to be sure that it’s neither the dump() nor the code after the return’s function that is causing this.

public function getRealms()
{
    $response = $this->client->request(
        'GET',
        'https://eu.api.blizzard.com/data/wow/realm/index',
        [
            'auth_bearer' => $this->auth_bearer,
            'headers' => [
                'Cache-Control' => 'no-cache',
                'Connection' => 'keep-alive'
            ],
            'query' => [
                'namespace' => 'dynamic-eu',
                'locale' => 'fr_FR'
            ]
        ]
    );

    $statusCode = $response->getStatusCode();
    $contentType = $response->getHeaders()['content-type'][0];
    $contentArray = $response->getContent();
    echo "ok";
    die;
    return $contentArray;
}

Unfortunately the echo never comes and I get the same error.

EDIT: I tried to replace keep-alive by close but nothing changed and I tried to remove it. Same :frowning:

I just wanna make sure I’m following, you do receive the response headers with a 200 status. I mean this line is working:

dump($contentType); // show "application/json;charset=UTF-8"

however it stops on this line until it times out ?

$contentArray = $response->toArray(); // <== TIMEOUT ERROR 

or you receive the timeout error just after the 200 is received ?

The timeout comes when I try to do a getContent() or a toArray();

Lines dumping contentType and statusCode are working and they return
statusCode : 200
contentType : application/json;charset=UTF-8

EDIT: Other requests work, if I try to call
https:// eu.api.blizzard. com/data/wow/realm/hyjal?namespace=dynamic-eu&locale=en-EN
I get my response. So I thought it was a “length/weight” problem, but when I try with larger request on others API (500+ items) it works too.

Interesting, I don’t think that is the problem but just in case, can you add the request header 'Accept' => 'application/json' ?

Just tried, but no :frowning:

Ok, one last try :roll_eyes:. Set the header 'Accept-Encoding' => 'gzip'.

Hmm I have not tried this one yet, but it did nothing. I’m up for any ideas, even crazy ones, I do not understand why THIS call is crashing while responding 200.
And it is good on Postman, It must come from these getContent and toArray methods. I want to try another lib to make http requests like Guzzle but I can’t stand not understanding this one.

Unfortunately I gotta go back to work now, consider joining the Community Discord Server there are a lot of nice people over there who can help you.
And I’ll try to help you more later if you still need. Good luck.

1 Like

Thank you very much Schiller, I’ll join the Discord, nice tip. Have a nice day !

EDIT :

Ok, we solved this by replacing HttpClient and adding the Curl layer, CurlHttpClient which is normaly embedded with HttpClient. I still don’t know why HttpClient was not enough for this request.

public function __construct()
{
    // $this->client = HttpClient::create();
    $this->client = new CurlHttpClient();
    $this->auth_bearer = $this->getAuthBearer();
}

thx Schiller !

Had the same problem with HttpClient after updating php and symfony.
At the end this was a problem with the php.ini setting:

default_socket_timeout = -1

somehow the HttpClient seems not to like the default value “-1”

I changed it to “60” and everything was OK.
This solved my problem.