How to find asynchronous Location header response PHP cURL - php

I am sending json data as part of post request to the specified target url and able to get the Location url. But the response from the target url is asynchronous response. So how to find and when to call the Location url to get the response. Below is my code to get the Location url.
$target_url = 'http://websieapi.com/api/messaging/post';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url);
curl_setopt($ch, CURLOPT_HEADER, true); //include headers in http data
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,$json_request);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch);
$headers = substr($result, 0, $curl_info["header_size"]); //split out header
preg_match("!\r\n(?:Location|URI): *(.*?) *\r\n!", $headers, $matches);
$location_url = $matches[1];
curl_close($ch);
Now in my $location_url, I am having generated url. But how do I know when to call this url to get the response. Because if there is high traffic then it will take time to generate response. Is there any way to find if the response has been generated or not? Any help would be greatly appreciated.

Related

How to stop PHP cURL upload inserting "Boundary" into the "Content-Type" field?

I'm using the below code to upload an MP4 file to a web service, using PHP cURL.
I've specified the 'Content-Type' as 'video/mp4', in CURLOPT_HTTPHEADER.
Unfortunately, having uploaded the file, the 'Content-Type' stored for it in the service displays as: "content_type":"video/mp4; boundary=----WebKitFormBoundaryfjNZ5VkJS8z3CB9X"
As you can see, the 'boundary' has been inserted into the 'content_type'.
When I then download the file, it fails to play, with a 'file unsupported/file extension incorrect/file corrupt' message.
$authorization = "Authorization: Bearer [token]";
$args['file'] = curl_file_create('C:\example\example.mp4','video/mp4','example');
$url='[example web service URL]';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: multipart/form-data', 'Accept: application/vnd.mendeley-content-ticket.1+json', $authorization));
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS , $args);
$response = curl_exec($ch); // URL encoded output - needs to be URL encoded to get the HREF link header
curl_close($ch);
Would be extremely grateful for any help, advice or pointers!
Maybe the API doesn't expects a POST multipart, but the actual contents in the body itself:
Ref: How to POST a large amount of data within PHP curl without memory overhead?
You need to use PUT method for the actual contents of the file to go inside the body - if you use POST, it will try to send as a form.
$authorization = "Authorization: Bearer [token]";
$file = 'C:\example\example.mp4';
$infile = fopen($file, 'r');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.mendeley.com/file_contents");
curl_setopt($ch, CURLOPT_PUT, 1 ); // needed for file upload
curl_setopt($ch, CURLOPT_INFILESIZE, filesize($file));
curl_setopt($ch, CURLOPT_INFILE, $infile);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST' );
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: video/mp4', 'Accept: application/vnd.mendeley-content-ticket.1+json', $authorization));
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result=curl_exec ($ch);
I have the same problem calling a Openai API from PHP curl.
I send options: Content-Type and Authorization (with my api key) but, when I send request, I receive this error:
Invalid Content-Type header (application/json; boundary=------------------------66a0b850cd1421c8), expected application/json
I tried to use some of your options with no success.
I cannot remove the boundary parameter added automatically.

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.

Sending header with CURL and recieving the Json data - PHP

I receive an error, not sure if this is an header error? The feed works 100% when I use Postman with the same headers and the URL
{"error":{"message":"The content version specified in the request is not supported.","code":101}}
Here is what I tried, my PHP code
$url = 'http://x.x.x.x/api/slot/0/io/';
$headers = array(
'Accept:vdn.v1',
'Content-Type:application/json'
);
$ch = curl_init();
// Now set some options (most are optional)
// Set URL to download
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
// Set a referer
curl_setopt($ch, CURLOPT_REFERER, "http://www.example.org/yay.htm");
// User agent
curl_setopt($ch, CURLOPT_USERAGENT, "MozillaXYZ/1.0");
// Include header in result? (0 = yes, 1 = no)
curl_setopt($ch, CURLOPT_HEADER, 0);
$headers
// Should cURL return or print out the data? (true = return, false = print)
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Timeout in seconds
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
// Download the given URL, and return output
$output = curl_exec($ch);
// Close the cURL resource, and free system resources
curl_close($ch);
print_r($output);exit;
I changed the header from
$headers = array(
'Accept:vdn.v1',
'Content-Type:application/json'
);
TO
$headers = array(
'Accept:vdn.v1'
);
that sorted all the problems

Getting executed URL from CURL

I have a Affiliate URL Like http://track.abc.com/?affid=1234
open this link will go to http://www.abc.com
now i want to execute the http://track.abc.com/?affid=1234 Using CURL
and now how i can Get http://www.abc.com
with Curl ?
If you want cURL to follow redirect headers from the responses it receives, you need to set that option with:
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
You may also want to limit the number of redirects it follows using:
curl_setopt($ch, CURLOPT_MAXREDIRS, 3);
So you'd using something similar to this:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://track.abc.com/?affid=1234");
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_MAXREDIRS, 3);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$data = curl_exec($ch);
Edit: Question wasn't exactly clear but from the comment below, if you want to get the redirect location, you need to get the headers from cURL and parse them for the Location header:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://track.abc.com/?affid=1234");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, true);
$data = curl_exec($ch);
This will give you the headers returned by the server in $data, simply parse through them to get the location header and you'll get your result. This question shows you how to do that.
I wrote a function that will extract any header from a cURL header response.
function getHeader($headerString, $key) {
preg_match('#\s\b' . $key . '\b:\s.*\s#', $headerString, $header);
return substr($header[0], strlen($key) + 3, -2);
}
In this case, you're looking for the value of the header Location. I tested the function by retrieving headers from a TinyURL, that redirects to http://google.se, using cURL.
$url = "http://tinyurl.com/dtrkv";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($ch);
curl_close($ch);
$location = getHeader($data, 'Location');
var_dump($location);
Output from the var_dump.
string(16) "http://google.se"

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