jwilsson / spotify-web-api-php

A PHP wrapper for Spotify's Web API.
MIT License
867 stars 156 forks source link

cURL transport error: 28 Failed to connect #238

Closed dinandmentink closed 2 years ago

dinandmentink commented 3 years ago

I have a small personal application which I use to connect to spotify. It's fairly simple, I run it locally.

However, sometimes™, sending any request to the SpotifyWebAPI will result in the process hanging for rougly 30 seconds, after which I get the following error:

127.0.0.1:59078 [200]: GET /?refresh=true - Uncaught SpotifyWebAPI\SpotifyWebAPIException: cURL transport error: 28 Failed to connect to api.spotify.com port 443: Connection timed out in /home/.../srcdir/vendor/jwilsson/spotify-web-api-php/src/Request.php:223

I don't think there's an issue with access/refresh tokens, those are handled and any error in the access token causes a raise like I would expect.

I also don't think there's a rate limit, because I'm not receiving 429 errors, just a timeout.

I would personally be fine if curl just returned an error after a timeout of 1 second. But for some reason setting curlopts doesn't cause a timeout any faster than the 60 seconds I'm now seeing.

Anyone experience with this? Am I missing something? This is roughly my implementation:

<?php

function spotify()
{
  global $_spotify;

  if(! isset($_spotify)) {
    $_spotify = new SpotifyWebAPI\SpotifyWebSPI(
      [
        'auto_refresh' => false,
        'auto_retry' => false,
      ],
      spotify_session()
    );
  }

  if(time() >= (value("spotify_token_expiration") - 120)) {
    spotify_session()->refreshAccessToken(spotify_session()->getRefreshToken());

    value("spotify_token_expiration", spotify_session()->getTokenExpiration());
    value("spotify_access_token", spotify_session()->getAccessToken());
    value("spotify_refresh_token", spotify_session()->getRefreshToken());
  }

  return $_spotify;
}

function spotify_session()
{
  global $_spotify_session;

  if(! isset($_spotify_session)) {
    $SPOTIFY_CLIENT_ID = 'redacted';
    $SPOTIFY_CLIENT_SECRET = 'redacted';

    $SPOTIFY_ACCESS_TOKEN = value("spotify_access_token");
    $SPOTIFY_REFRESH_TOKEN = value("spotify_refresh_token");

    $_spotify_session = new SpotifyWebAPI\Session(
        $SPOTIFY_CLIENT_ID,
        $SPOTIFY_CLIENT_SECRET
    );

    $_spotify_session->setAccessToken($SPOTIFY_ACCESS_TOKEN);
    $_spotify_session->setRefreshToken($SPOTIFY_REFRESH_TOKEN);
  }

  return $_spotify_session;
}

(and then using spotify()->me() and such in the application).

jwilsson commented 2 years ago

Hey! That's strange. How are you setting the cURL options? Via the curl_options setting?

dinandmentink commented 2 years ago

Yes, like that.

jwilsson commented 2 years ago

I forgot to ask you in the last comment, which timeout option are you using? CURLOPT_CONNECTTIMEOUT, CURLOPT_TIMEOUT, or both?

dinandmentink commented 2 years ago

I have tried multiple approaches. Both CURLOPT_CONNECTTIMEOUT and CURLOPT_TIMEOUT and both. It almost seems that a timeout isn't registered by PHP, or something.

jwilsson commented 2 years ago

Hmm, that sounds really weird. But I'm afraid I can't be of much help, I've never encountered this error myself. I do know of a few people who have posted about similar cURL issues here over the years but we've never really been able to find the root cause.

I'll leave this issue open for a while to see if someone else might has the same problem and have a solution for it.

dinandmentink commented 2 years ago

Ok. Thanks for your response. At the moment I am using the php dev server php -S as a server. I'll migrate this to a simple lighttp/apache/nginx server to see if it helps.

dinandmentink commented 2 years ago

Update: I have migrated my app to a lighttp webserver using php through fastcgi. Still the same issue. Tried it both in ubuntu 20.04 and 21.10, but no luck.

2021-12-11 16:42:41: mod_fastcgi.c.487) FastCGI-stderr:PHP Fatal error:  Uncaught SpotifyWebAPI\SpotifyWebAPIException: cURL transport error: 28 Failed to connect to api.spotify.com port 443: Connection timed out in /dir/vendor/jwilsson/spotify-web-api-php/src/Request.php:223
2021-12-11 16:42:41: mod_fastcgi.c.487) FastCGI-stderr:Stack trace:
2021-12-11 16:42:41: mod_fastcgi.c.487) FastCGI-stderr:#0 /dir/vendor/jwilsson/spotify-web-api-php/src/Request.php(132): SpotifyWebAPI\Request->send()
2021-12-11 16:42:41: mod_fastcgi.c.487) FastCGI-stderr:#1 /dir/vendor/jwilsson/spotify-web-api-php/src/SpotifyWebAPI.php(124): SpotifyWebAPI\Request->api()
2021-12-11 16:42:41: mod_fastcgi.c.487) FastCGI-stderr:#2 /dir/vendor/jwilsson/spotify-web-api-php/src/SpotifyWebAPI.php(1107): SpotifyWebAPI\SpotifyWebAPI->sendRequest()
2021-12-11 16:42:41: mod_fastcgi.c.487) FastCGI-stderr:#3 /dir/app.php(280): SpotifyWebAPI\SpotifyWebAPI->getMyPlaylists()
2021-12-11 16:42:41: mod_fastcgi.c.487) FastCGI-stderr:#4 /dir/app.php(307): spotify_playlists()
2021-12-11 16:42:41: mod_fastcgi.c.487) FastCGI-stderr:#5 /dir/views/navbar/spotify.php(57): spotify_favourites()
2021-12-11 16:42:41: mod_fastcgi.c.487) FastCGI-stderr:#6 /dir/app.php(111): require('...')
2021-12-11 16:42:41: mod_fastcgi.c.487) FastCGI-stderr:#7 /dir/app.php(126): requireToVar()
2021-12-11 16:42:41: mod_fastcgi.c.487) FastCGI-stderr:#8 /dir/app.php(154): replace_content()
2021-12-11 16:42:41: mod_fastcgi.c.487) FastCGI-stderr:#9 /dir/routes.php(4): inline_refresh()
2021-12-11 16:42:41: mod_fastcgi.c.487) FastCGI-stderr:#10 /dir/public/index.php(4): require('...')
2021-12-11 16:42:41: mod_fastcgi.c.487) FastCGI-stderr:#11 {main}
2021-12-11 16:42:41: mod_fastcgi.c.487) FastCGI-stderr:  thrown in /dir/vendor/jwilsson/spotify-web-api-php/src/Request.php on line 223
jwilsson commented 2 years ago

Hmm, and you're not behind a proxy, firewall, or similar?

dinandmentink commented 2 years ago

No I'm not.

It seems, however, I have fixed the issue where curl timeouts did not trigger. After carefully checking my work against https://github.com/jwilsson/spotify-web-api-php/blob/646b49a10430883f16985704b0c19142f75eb5b0/docs/examples/setting-custom-curl-options.md I realized a request (with curl options) needs to be set both for the Session and the SpotifyWebAPI. After amending this now I, at least, get a curl timeout error after a reasonable few seconds instead of a minute. So for me this works, for now.

Edit: if anyone has the same issue I'll be happy to have a look, but for me it seems to work now. Thanks for your responses and input!