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
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 tohttps
so the solution would simply be to correct URL to usinghttps
. Alternatively you can setCURLOPT_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: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 🙂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://
tohttps://
protocol redirect, which you could simply overcome by making the request directly to thehttps://
version. This would avoid making 2 requests all the time.