PHP CURL returning 301 Location - php

My curl php code is returning 301 and i can't print out what the curl returned.
this is my code:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://subdomain.thinkific.com/api/public/v1/users/3418346");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
$headers = array();
$headers[] = "X-Auth-Api-Key: myapikey";
$headers[] = "X-Auth-Subdomain: subdomain";
$headers[] = "Content-Type: application/json";
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
curl_close($ch);
var_dump($result);
Here is what it returned:
string(142) "301{"Location"=>"https:subdomain.thinkific.com/api/public/v1/users/3418346", "Cache-Control"=>"no-cache"}#"
i have tried json_decode the result to print it, still the same. as well as i also tried those:
curl_setopt($ch, CURLOPT_ENCODING, "");
curl_setopt($ch, CURLOPT_AUTOREFERER, true);
curl_setopt($ch, CURLOPT_NOBODY, 1); //this one returned string(0) without 301
I need to know if the error is from my server or it has something to do with my code. ( i did not share api key and subdomain for privacy sorry).

The 301 response code is the following :
The HTTP response status code 301 Moved Permanently is used for
permanent URL redirection, meaning current links or records using the
URL that the response is received for should be updated. The new URL
should be provided in the Location field included with the response.
SO it means that you're requesting a resource that has been moved (the url changed) and you should retry the request with the newly provided URL !

Related

PHP CURLOPT PUT method

I am trying to do a PUT call on php using curlopt but the DELETE and POST methods work fine, and the PUT method no, I have an 400 error.
I am using the following code:
$url = 'https://theURL';
echo " \n URL:\n".$url." "; //The URL is correct
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
$headers[] = 'Content-length: 0'; //I don't have a body so the header is 0
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$output = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
If i Don't put the header part, i have this error:
HTTP Error 411. The request must be chunked or have a content length.
But I don't have a body so I just put the content-length as 0. I have also tried to put a number there but I have a different error.
The error I am getting is this:
REQUEST ERROR: The server encountered an error processing the request.

cURL makes page load forever, then gateway timed out

I'm working with a third party API, and it returns 400 HTTP STATUS when you make a mistake.
When using POSTMAN, the 400 HTTP error page shows as expected, but when using PHP's cURL, the page just loads for about a minute, then it gives me a "504 - Gateway timeout", and I need to close the browser to be able to access the page again.
When the cURL request is valid (the API returns a 200 OK) it works normally.
My question is, why is cURL giving the 504 error instead of 400?
And why is it ignoring CURLOPT_CONNECTTIMEOUT and CURLOPT_TIMEOUT?
Below is my cURL code (both $token, $payload and $config variables are declared and valid):
$ch = curl_init("https://api.mercadolibre.com/items?access_token=$token");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"User-Agent: Alcavie/" . $config['version'],
"Accept: application/json",
"Content-Type: application/json",
//"Accept-Encoding: gzip, deflate, br",
//"Connection: keep-alive"
));
$error = false;
try{
$result = curl_exec($ch);
$resultJson = json_decode($result);
}catch(\Exception $e){
var_dump($e);
$error = true;
exit;
}
curl_close($ch);
The API probably sends HTTP302 in between and if so, you'd either need two requests ortell cURL to follow the redirect with curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);HTTP504 means that the client didn't react in a timely manner upon the previous HTTP header;there may be other causes for HTTP504, but it is one of the most common. Postman is insufficient to test this properly (I don't use it at all); better use a web-browser, hit F12 and tick the "preserve logs" checkbox... then you can clearly see which HTTP headers are being sent in succession.
Also useful to debug this would be: curl_setopt($ch, CURLOPT_HEADER, true);

How to pass variables between pages using http headers?

I'm trying to pass an authorization token between two pages of my application and would like to do so using HTTP headers, however my code is not working as expected.
I've tried retrieving the header using getallheaders() from the second page however the header that I pass it from the first page is not present in the list.
This is the flow of what I'm doing
Placing token into the header array
Executing the POST call
Redirecting to second page using header("Location:")
(on second page) Checking the headers
//placing token into header/////////////////////////////////////////
$token_header['Authorization'] = $accessTokenResult['access_token'];
$header = array();
foreach($token_header as $key => $parsed_urlvalue)
{
$header[] = "$key: $parsed_urlvalue";
}
//sending the request//////////////////////////////////////////////
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_USERAGENT, $userAgent);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_URL, "./custom_request.php");
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$result = curl_exec($ch);
curl_close($ch);
//redirecting to the second page////////////////////////////////////
header("Location: custom_request.php");
die("Redirected to custom request page");
Other page
$headers_recieved = getallheaders();
echo $headers_recieved['Authorization'];
However I'm getting an invalid index error since 'Authorization' is not present.

XML in curl PHP

I am calling an API using CURL.
When I run it directly in browser or via ajax request it runs well and gives xml output.The Api am calling stores the xml in a database table and would only then work well.
However when I call it via PHP curl their table is not getting updated.
The code am doing it with PHP curl is
curl_setopt($ch, CURLOPT_URL, $api);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
$headers = array();
$headers[] = "Accept: application/json";
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
Sample URL : http://example.com/code=x05a&businessKeyValue=8519ada0-9e2f-e265-8698-5b6145af9704&entity=funded_program_concession&parameters=fpc_funded_program_concession_id%7C8519ada0-9e2f-e265-8698-5b6145af9704&parameters=fps_funded_program_subsidy_id%7Cf320f2d9-7c6a-0b56-2940-5b61147a0f3d
If I open this link which opens it in browser, it works good, but if I run it via curl the API is not receiving xml content.
How can I resolve this issue?
$api='http://example.com/code=x05a&businessKeyValue=8519ada0-9e2f-e265-8698-5b6145af9704&entity=funded_program_concession&parameters=fpc_funded_program_concession_id%7C8519ada0-9e2f-e265-8698-5b6145af9704&parameters=fps_funded_program_subsidy_id%7Cf320f2d9-7c6a-0b56-2940-5b61147a0f3d';
$ch = curl_init();
$headers = array();//put your headers only if you need them
curl_setopt($ch, CURLOPT_URL, $api);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result= curl_exec($ch);
return $result;
This should work for you. Inside your headers array make sure you put the headers you need and not extra. This is a simple curl, get call so i guess the above code will work without any trouble.
If you want to accept xml then you can got for Accept:application/xml or Accept:application/xhtml+xml
If the above methods don't work provide us with your error.
echo 'Curl error: ' . curl_error($ch);
Add the above line as a breaking point in your code and see what's the error.

Curl, follow location but only get header of the new location?

I know that when I set CURLOPT_FOLLOWLOCATION to true, cURL will follow the Location header and redirect to new page. But is it possible only to get header of the new page without actually redirecting there? Or is it not possible?
Appears to be a duplicate of PHP cURL: Get target of redirect, without following it
However, this can be done in 3 easy steps:
Step 1. Initialise curl
curl_init($ch); //initialise the curl handle
//COOKIESESSION is optional, use if you want to keep cookies in memory
curl_setopt($ch, CURLOPT_COOKIESESSION, true);
Step 2. Get the headers for $url
curl_setopt($ch, CURLOPT_URL, $url); //specify your URL
curl_setopt($ch, CURLOPT_HEADER, true); //include headers in http data
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false); //don't follow redirects
$http_data = curl_exec($ch); //hit the $url
$curl_info = curl_getinfo($ch);
$headers = substr($http_data, 0, $curl_info["header_size"]); //split out header
Step 3. Parse the headers to get the new URL
preg_match("!\r\n(?:Location|URI): *(.*?) *\r\n!", $headers, $matches);
$url = $matches[1];
Once you have the new URL you can then repeat steps 2-3 as often as you like.
No. You'd have to disable FOLLOWLOCATION, extract the redirect URL from the response, and then issue a new HEAD request with that URL.
Set CURLOPT_FOLLOWLOCATION as false and CURLOPT_HEADER as true, and get the "Location" from the response header.
Yes, you can set it to follow the redirect until you get the last location on the header response.
The function to get the last redirect:
function get_redirect_final_target($url)
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_NOBODY, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // follow redirects
curl_setopt($ch, CURLOPT_AUTOREFERER, 1); // set referer on redirect
curl_setopt($ch,CURLOPT_HEADER,false); // if you want to print the header response change false to true
$response = curl_exec($ch);
$target = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
curl_close($ch);
if ($target)
return $target; // the location you want
return false;
}
You can get the redirect URL directly with curl_getinfo:
$ch = curl_init();
curl_setopt($ch, CURLOPT_COOKIESESSION, false);
curl_setopt($ch, CURLOPT_URL, $url); //specify your URL
curl_setopt($ch, CURLOPT_HEADER, true); //include headers in http data
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false); //don't follow redirects
$http_data = curl_exec($ch); //hit the $url
$redirect = curl_getinfo($ch)['redirect_url'];
curl_close($ch);
return $redirect;
And for analyze headers, your can use CURLOPT_HEADERFUNCTION
Make sure you set CURLOPT_HEADER to True to get the headers in the response, otherwise the response returned as blank string

Categories