skip to Main Content

I’m trying to request events through the skiddle API, using endpoint http://www.skiddle.com/api/v1/events/search/, but when I try I get the following response:

HTTP/1.1 301 Moved Permanently
Server: CloudFront
Date: Wed, 19 Apr 2023 14:21:19 GMT
Content-Type: text/html
Content-Length: 167
Connection: keep-alive
Location: https://www.skiddle.com/api/v1/events/search/?api_key=adda7f84a6e81df4c571792014aa321a&latitude=51.509865&longitude=-0.118092&radius=30&keyword=trance&limit=100&offset=0
X-Cache: Redirect from cloudfront
Via: 1.1 3fff5cbe8229c22a8e7cfe60a8827a1e.cloudfront.net (CloudFront)
X-Amz-Cf-Pop: LHR61-P6
Alt-Svc: h3=":443"; ma=86400
X-Amz-Cf-Id: SLXpElnGSXFF0oD360hjXiwDF2sqfuHD5LggX96rDlUaoHGecskp1Q==

Here’s my code:

$skiddle = new Skiddle();
$rr = $skiddle->searchEvents('london','trance');
echo $rr->get();

class Locations
{
    public static $london = [
        'latitude'=>51.509865,
        'longitude'=>-0.118092,
        'radius'=>30
    ];
}
class Skiddle
{
    const EVENTS_SEARCH_URL = 'http://www.skiddle.com/api/v1/events/search/';
    const KEY = "adda7f84a6e81df4c571792014aa321a";
    public function __construct(){}
    public function searchEvents($location = "", $keyword = "")
    {
        $params = [
            'api_key' => self::KEY
        ];
        if ($location)
        {
            $params['latitude'] = Locations::$$location['latitude'];
            $params['longitude'] = Locations::$$location['longitude'];
            $params['radius'] = Locations::$$location['radius'];
        }
        if ($keyword)
        {
            $params['keyword'] = $keyword;
        }
        return new SkiddlePaginatedRequestResponse(
            self::EVENTS_SEARCH_URL,
            $params
        );
    }
}
class SkiddlePaginatedRequestResponse extends RequestResponse
{
    protected $limit;
    protected $offset;
    public function __construct($url, $params = [], $limit = 100, $offset = 0)
    {
        parent::__construct($url, $params);
        $this->limit = $limit;
        $this->offset = $offset;
    }
    public function get()
    {
        return parent::get();
    }
    public function nextPage()
    {
        return new SkiddlePaginatedRequestResponse(
            $this->url,
            $this->params,
            $this->limit,
            $this->offset + $this->limit
        );
    }
    protected function buildRequest()
    {
        parent::buildRequest();
        $this->request['limit'] = $this->limit;
        $this->request['offset'] = $this->offset;
    }
    protected function handleBadStatus($rawBody, $status, $headers)
    {
        $errorBody = json_decode($rawBody);
        if (isset($errorBody->errormessage) && isset($errorBody->error)) {
            // Error from the API
            fault("Skiddle error", $errorBody->errormessage."n".$errorBody->error);
            die();
        } else {
            $this->dieHttpErrorFault($status, $headers);
        }
    }
}
class RequestResponse
{
    protected $params;
    protected $url;
    protected $request;
    protected $cookies = false;
    public function __construct($url, $params = [])
    {
        $this->params = $params;
        $this->url = $url;
    }
    public function setCookies($cookies)
    {
        //"mycookie1=value1; mycookie2=value2"
        $this->cookies = $cookies;
    }
    public function get()
    {
        $this->buildRequest();
        $url = $this->url . '?' . http_build_query($this->request);
        $ch = curl_init();
        curl_setopt_array($ch, [
            CURLOPT_CUSTOMREQUEST => "GET",
            CURLOPT_HEADER => true,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_URL => $url,
            CURLOPT_SSL_VERIFYPEER => false
        ]);
        if ($this->cookies) curl_setopt($ch, CURLOPT_COOKIE, $this->cookies);
        $response = curl_exec($ch);
        //$rawBody = curl_exec($ch);
        if (curl_error($ch))
        {
            fault('cURL transport error', curl_errno($ch).'n'.curl_error($ch));
            die();
        }
        list($headers, $rawBody) = explode("rnrn", $response, 2);
        $status = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        if ($status < 200 || $status > 299) {
            $this->handleBadStatus($rawBody, $status, $headers);
        }
        $object = json_decode($rawBody, true);
        if (json_last_error() !== JSON_ERROR_NONE) {
            fault('JSON parsing', "Error ".json_last_error_string()." (".json_last_error().")");
        }
        return $object;
    }
    protected function buildRequest()
    {
        $this->request = $this->params;
    }
    protected function handleBadStatus($rawBody, $status, $headers)
    {
        $this->dieHttpErrorFault($status, $headers);
    }
    protected function dieHttpErrorFault($status, $headers)
    {
        fault('HTTP error', "Code $status, nHeaders:n$headers");
        die();
    }
}

Please advise
Thank you

2

Answers


  1. 301 indicates moved resource (or redirection if you like). There can be couple of reasons but my guess is that they redirect your http request to https so the solution would simply be to correct URL to using https. Alternatively you can set CURLOPT_FOLLOWLOCATION as others suggest, yet that’d be sub-optimal, because you will be doing two requests even if you now know first is in vein + your first one goes unencrypted.

    EDIT: I also noticed a bug in your searchEvents() implementaion. These lines:

    $params['latitude'] = Locations::$$location['latitude'];
    $params['longitude'] = Locations::$$location['longitude'];
    $params['radius'] = Locations::$$location['radius'];
    

    stinks to me as you are using variable variables ($$). I suspect copy-paste bug so I recommend start using any static linter or at least smarter IDE 🙂

    Login or Signup to reply.
  2. Generally speaking, use the CURLOPT_FOLLOWLOCATION (https://www.php.net/manual/en/function.curl-setopt.php) option to make cURL automatically follow redirects.

    In your specific case, it seems to be only a http:// to https:// protocol redirect, which you could simply overcome by making the request directly to the https:// version. This would avoid making 2 requests all the time.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search