Reputation: 14728
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=xxxxxx&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 = "xxxxxxx";
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("\r\n\r\n", $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
Upvotes: 0
Views: 55
Reputation: 75609
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 :)
Upvotes: 1
Reputation: 4534
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.
Upvotes: 0