PHP and cURL - Multiform request with file and text - php

I need to send a cURL request containing a file to upload as well as a JSON string. I can get a properly formatted request when sending the JSON, but the file is throwing it off.
$postData = array(
'JSON'=> json_encode($jsonParams),
$reference => '#'.$tmp_file_path
);
//Borrowed function from: http://scraperblog.blogspot.com/2013/07/php-curl-multipart-form-posting.html
function multipart_build($fields, $boundary){
$retval = '';
foreach($fields as $key => $value){
$retval .= "--$boundary\nContent-Disposition: form-data; name=\"$key\"\n\n$value\n";
}
$retval .= "--$boundary--";
return $retval;
}
$boundary = "--requestboundary-xxx";
$request = $this->multipart_build($postData,$boundary);
$curl = curl_init();
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // stop verifying certificate
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-Type: multipart/form-data; boundary=$boundary"));
curl_setopt($curl, CURLOPT_URL, $target);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $request);
$response = curl_exec($curl);
$info = curl_getinfo($curl);
curl_close($curl);
The $reference needs to be tied to a value in the $jsonParams so the receiving server can ensure uploaded files are attached to the corresponding data string packages.
////////////////////////////////////////////////////////////
Update after Marc B's comment
////////////////////////////////////////////////////////////
So my first approach wasn't using my own multipart. The reason I went with multipart was at least I was getting a response from the server. Here is the original code.
$curl_file_object = curl_file_create($attachmentFile['tmp_name'], $attachmentFile['type'], $reference);
$postData= array(
'JSON'=> json_encode($jsonParams),
$reference => $curl_file_object,
);
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $target);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // stop verifying certificate
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-Type: multipart/form-data;"));
curl_setopt($curl, CURLOPT_POST, true); // enable posting
curl_setopt($curl, CURLOPT_POSTFIELDS, $postData); // post data
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); // if any redirection after upload
$response = curl_exec($curl);
$info = curl_getinfo($curl);
curl_close($curl);
debug($info);
And with this I get:
[url] => --------
[content_type] =>
[http_code] => 0
[header_size] => 0
[request_size] => 0
[filetime] => -1
[ssl_verify_result] => 0
[redirect_count] => 0
[total_time] => 0.031
[namelookup_time] => 0
[connect_time] => 0.031
[pretransfer_time] => 0
[size_upload] => 0
[size_download] => 0
[speed_download] => 0
[speed_upload] => 0
[download_content_length] => -1
[upload_content_length] => -1
[starttransfer_time] => 0
[redirect_time] => 0
[redirect_url] =>
[primary_ip] => --------
[certinfo] => Array
(
)
[primary_port] => --------
[local_ip] => --------
[local_port] => --------
With the multipart I was at least getting a 400.

Don't built your own multipart. Curl is perfectly capable of doing that for you:
curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
it'll take an array and do whatever's needed automatically.
And if you're on PHP 5.5+, you can use curlfile for the file part as well, without the # hack.

Using CURLFile instead of curl_file_create() fixed the problem. Even though they are supposed to be the same...

Related

Php Curl headers not being set

I am trying to set 2 variables to the curl headers and can't seem to see what's wrong. I am not receiving any errors in the php logs, but when I print out the curl info I can see that the headers are not being set. Any point in the right direction would be helpful. Thanks
The Example I'm using
PHP cURL custom headers
class GetAuctions
{
private $APIKeyID = "theIDhere";
private $APIKeyPass = "thePasswordHere";
private $BaseURL = "https://someurlHere";
public function __construct()
{
//get list of upcoming auctions
$get_data = $this->callAPI('GET', $this->BaseURL, false);
//turn the response into a json
$response = json_decode($get_data, true);
//display the response for testing
echo print_r($response);
$errors = $response['response']['errors'];
$data = $response['response']['data'][0];
echo print_r($data);
}
function callAPI($method, $url, $data){
$curl = curl_init();
switch ($method){
case "POST":
curl_setopt($curl, CURLOPT_POST, 1);
if ($data)
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
break;
case "PUT":
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
if ($data)
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
break;
default:
if ($data)
$url = sprintf("%s?%s", $url, http_build_query($data));
}
// OPTIONS:
curl_setopt($curl, CURLOPT_URL, $url);
$headers =array();
$headers['apiKeyID'] = $this->APIKeyID;
$headers['apiKeyPass'] = $this->APIKeyPass;
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
echo "<br/>";
echo print_r(curl_getinfo($curl));
echo "<br/>";
// EXECUTE:
$result = curl_exec($curl);
if(!$result){die("Connection Failure");}
curl_close($curl);
return $result;
}
}
I've also tried this:
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
"apiKeyID: $this->APIKeyID",
"apiKeyPass: $this->APIKeyPass"
));
My response looks like this:
Array ( [url] => https://MyURLHere [content_type] => [http_code] => 0 [header_size] => 0 [request_size] => 0 [filetime] => -1 [ssl_verify_result] => 0 [redirect_count] => 0 [total_time] => 0 [namelookup_time] => 0 [connect_time] => 0 [pretransfer_time] => 0 [size_upload] => 0 [size_download] => 0 [speed_download] => 0 [speed_upload] => 0 [download_content_length] => -1 [upload_content_length] => -1 [starttransfer_time] => 0 [redirect_time] => 0 [redirect_url] => [primary_ip] => [certinfo] => Array ( ) [primary_port] => 0 [local_ip] => [local_port] => 0 ) 1
Connection Failure
It looks like your headers are incorrectly formatted:
"apiKeyID : $this->APIKeyID",
You should remove space before your colon:
"apiKeyID: ${this->APIKeyID}",
BTW: for debugging purpose you may also use CURLOPT_VERBOSE to see what's is being send by cURL. If you cannot peek stderr at runtime, redirect it to the file:
curl_setopt($c, CURLOPT_STDERR, fopen('curl-log.txt', 'w+'));

Getting Robinhood options data in PHP

I'm trying to get Robinhood option data in PHP, which requires authentication. I feel like I am a breath away from my solution, but after trying for a day I am ready to ask for help.
So far, I have been able to log in to Robinhood and get the token, then use that token to authenticate a request for a second (oauth) token successfully. But for some reason, I am unable to get options data for the option of my choice (MSFT Put 75 Exp 1/17/2020, found here with proper authentication https://api.robinhood.com/marketdata/options/0fd40096-9cbc-4b14-9df4-c1c9ea5f5729/ )
Here is how I login
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"https://api.robinhood.com/api-token-auth/");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "username=example#gmail.com&password=mypassword");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$server_output = curl_exec ($ch);
$result = json_decode($server_output);
$token = $result->token;
curl_close ($ch);
Then I take that token and convert it
$url = 'https://api.robinhood.com/oauth2/migrate_token/';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Token '.$token));
$server_output = curl_exec ($ch);
$result = json_decode($server_output);
$oauth_token = $result->access_token;
curl_close ($ch);
Up to here so far so good, but I am only getting a blank response when I try the following:
$url = 'https://api.robinhood.com/marketdata/options/0fd40096-9cbc-4b14-9df4-c1c9ea5f5729/';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Bearer '.$oauth_token));
$server_output = curl_exec ($ch);
var_dump($server_output);
curl_close ($ch);
Any help or ideas why I'm having issues on the last part would be immensely appreciated :)
EDIT: In answer to WebCode.ie, the result of print_r(curl_getinfo($ch)) is:
Array
(
[url] => https://api.robinhood.com/marketdata/options/0fd40096-
cbc-4b14-9df4-c1c9ea5f5729/
[content_type] => application/json
[http_code] => 405
[header_size] => 187
[request_size] => 453
[filetime] => -1
[ssl_verify_result] => 0
[redirect_count] => 0
[total_time] => 0.386518
[namelookup_time] => 2.8E-5
[connect_time] => 0.094845
[pretransfer_time] => 0.289176
[size_upload] => 0
[size_download] => 0
[speed_download] => 0
[speed_upload] => 0
[download_content_length] => 0
[upload_content_length] => -1
[starttransfer_time] => 0.386491
[redirect_time] => 0
[redirect_url] =>
[primary_ip] => 52.200.3.207
[certinfo] => Array
(
)
[primary_port] => 443
[local_ip] => 84.x.x.x //my IP
[local_port] => 60974
)
Looks like I was making POST call when I should have been making a GET call. If you are having trouble remove this line from my last code block.
curl_setopt($ch, CURLOPT_POST, 1);

Issue using PHP cURL with the Streamable API

I am hoping to build a video upload using the Streamable API and PHP with cURL. https://streamable.com/documentation#upload-video-file
What I'm trying to accomplish is:
User fills out a form of info and selects a video file from their computer/device to upload
Submits the form, PHP handles it from there to talk to the Streamable API to upload the video via the form to my Streamable account, then return the shortcode from Streamable for me to store in a MySQL database with the rest of their info
I've tried, with success, using the curl command via terminal. But, I'm having issues with pulling it off via php form submission.
This is an example of the command I used in terminal to upload, which worked:
curl https://api.streamable.com/upload -u my_email:my_pass -F file=#path/to/file.mp4
With PHP, I have a pretty simple cURL script thanks to the tons of help online. I guess you could say I'm pretty new to using cURL.
$url = 'https://api.streamable.com/upload -u my_email.com:my_pass -F file=#path/to/file.mp4';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$server_output = curl_exec ($ch);
curl_close ($ch);
With that, I'm getting a HTTP 400 error.
https://streamable.com/documentation#errors
..codes in the 400 range indicate client errors...
I guess that's what's messing me up here?
I tried it this way, but I get the same error.
$pass = 'my_email:my_pass';
$postFields = array(
'file' => '/path/to/file.mp4',
'title' => 'Example Title'
);
$url = 'https://api.streamable.com/upload';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_USERPWD, $pass);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$server_output = curl_exec ($ch);
curl_close ($ch);
I used print_r(curl_getinfo($ch)); to see what's happening, and this is what it's spitting out - maybe this can be useful for some help:
Array ( [url] => https://api.streamable.com/upload
-u my_email:my_pass -F file=#/Path/to/file.mp4 [content_type] => [http_code] => 400 [header_size] => 66 [request_size] => 277 [filetime] => -1 [ssl_verify_result] => 0 [redirect_count] => 0 [total_time] => 0.36033 [namelookup_time] => 0.00138 [connect_time] => 0.082871 [pretransfer_time] => 0.283219 [size_upload] => 0 [size_download] => 0 [speed_download] => 0 [speed_upload] => 0 [download_content_length] => 0 [upload_content_length] => 275 [starttransfer_time] => 0.36031 [redirect_time] => 0 [redirect_url] => [primary_ip] => xx.xx.xxx.xxx [certinfo] => Array ( ) [primary_port] => 443 [local_ip] => 192.168.0.1 [local_port] => 57288 )
There are couple of things you need to change here:
Set CURLOPT_SSL_VERIFYPEER to false. It can be used to verify peer's certificate. If we specify it as false, it will accept any server(peer) certificate.
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
Here's a good read on the implication of turning CURLOPT_SSL_VERIFYPEER on and off, If CURLOPT_SSL_VERIFYPEER is false, is the data transfer no longer secure?
CURLOPT_POSTFIELDS is used to specify full data we want to submit with the POST request. The $postFields array should be converted to URL-encoded query string using http_build_query() function, so that it could be sent as application/x-www-form-urlencoded.
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postFields));
Try this:
$fields = array("file"=>curl_file_create("video.mp4"));
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.streamable.com/upload");
curl_setopt($ch, CURLOPT_USERPWD, "email:pass");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields );
$result = curl_exec($ch);
I think curl_file_create makes the trick, it seems using #fileName no more work for PHP 5.5+

Final URL - PHP (Effective URL) How to

I apologize in advance for my English.
I need from a url http://www.streamuj.tv/video/2f15014c90a9f62af511?streamuj=hd&authorize=7736cdf0f3719ed75b26132aee184525 get the final redirected to url redirection (.flv) url.
I tried this, but somehow it doesn't get the info I need:
<?php
function getMainUrl($url) {
$headers = get_headers($url, 1);
return $headers['Location'];
}
echo getMainUrl("http://www.streamuj.tv/video/2f15014c90a9f62af511?streamuj=hd&authorize=7736cdf0f3719ed75b26132aee184525");
?>
When use:
http://getlinkinfo.com/info?link=http%3A%2F%2Fwww.streamuj.tv%2Fvideo%2F2f15014c90a9f62af511%3Fstreamuj%3Dhd%26authorize%3D7736cdf0f3719ed75b26132aee184525+&x=45&y=6
it redirects to:
http://s14.streamuj.tv:8080/vid/8f18cade6df7fc2d54a3522e7515771e/58a1ecfa/2f15014c90a9f62af511_hd.flv?start=0
and this is the one I need from php
Any help would be appreciated. Thanks
Using cURL, we tell it only to fetch the header and to follow redirects.
<?php
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, 'http://www.streamuj.tv/video/2f15014c90a9f62af511?streamuj=hd&authorize=7736cdf0f3719ed75b26132aee184525');
curl_setopt($curl, CURLOPT_FILETIME, true);
curl_setopt($curl, CURLOPT_NOBODY, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, true);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, TRUE);
$header = curl_exec($curl);
$info = curl_getinfo($curl);
curl_close($curl);
print_r($info);
Outputs:
Array
(
[url] => http://s14.streamuj.tv:8080/vid/c7194f1279591f88c162382a0a5a49d1/58a1f0a5/2f15014c90a9f62af511_hd.flv?start=0
[content_type] => video/x-flv
...
)
This Work:
<?php
session_start();
include "simple_html_dom.php";
$proxy = array("88.159.43.160:80");
$proxyNum = 0;
$proxy = explode(':', $proxy[$proxyNum]);
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, 'http://www.streamuj.tv/video/2f15014c90a9f62af511?streamuj=hd&authorize=7736cdf0f3719ed75b26132aee184525');
curl_setopt($curl, CURLOPT_FILETIME, true);
curl_setopt($curl, CURLOPT_NOBODY, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, true);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($curl, CURLOPT_PROXY, $proxy[0]);
curl_setopt($curl, CURLOPT_PROXYPORT, $proxy[1]);
$header = curl_exec($curl);
$info = curl_getinfo($curl);
curl_close($curl);
print_r($info);
?>
Outputs:
Array ( [url] => http://s14.streamuj.tv:8080/vid/0b9ac442e33b2f0fe72dd45295b6e7bd/58a1f3b0/2f15014c90a9f62af511_hd.flv?start=0 [content_type] => video/x-flv [http_code] => 200 [header_size] => 738 [request_size] => 326 [filetime] => 1481886073 [ssl_verify_result] => 0 [redirect_count] => 1 [total_time] => 3.485 [namelookup_time] => 0 [connect_time] => 3.063 [pretransfer_time] => 3.063 [size_upload] => 0 [size_download] => 0 [speed_download] => 0 [speed_upload] => 0 [download_content_length] => 674855667 [upload_content_length] => -1 [starttransfer_time] => 3.188 [redirect_time] => 0.297 [redirect_url] => [primary_ip] => 88.159.43.160 [certinfo] => Array ( ) [primary_port] => 80 [local_ip] => 192.168.0.8 [local_port] => 57532 )
How to can please echo only this: http://s14.streamuj.tv:8080/vid/0b9ac442e33b2f0fe72dd45295b6e7bd/58a1f3b0/2f15014c90a9f62af511_hd.flv?start=0
?

PHP cURL Problems: HTTP Code 0

I am trying to bring up a website/API through cURL and PHP. Whatever URL I try I am getting an HTTP Code of 0. I have tried several different URLs. No matter what I try I am getting the following curl_getinfo back (see below). I have verified that cURL is enabled in PHP.ini file.
Code:
// create a new cURL resource
$ch = curl_init();
// set URL and other appropriate options
curl_setopt($ch, CURLOPT_URL, "http://www.yahoo.com");
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
$report=curl_getinfo($ch);
print_r($report);
// grab URL and pass it to the browser
curl_exec($ch);
if(curl_errno($ch)) {
echo 'Curl error: ' . curl_error($ch);
}
print curl_error($ch);
// close cURL resource, and free up system resources
curl_close($ch);
cURL_getinfo:
Array
(
[url] => http://www.yahoo.com
[content_type] =>
[http_code] => 0
[header_size] => 0
[request_size] => 0
[filetime] => 0
[ssl_verify_result] => 0
[redirect_count] => 0
[total_time] => 0
[namelookup_time] => 0
[connect_time] => 0
[pretransfer_time] => 0
[size_upload] => 0
[size_download] => 0
[speed_download] => 0
[speed_upload] => 0
[download_content_length] => -1
[upload_content_length] => -1
[starttransfer_time] => 0
[redirect_time] => 0
[certinfo] => Array
(
)
[primary_ip] =>
[primary_port] => 0
[local_ip] =>
[local_port] => 0
[redirect_url] =>
)
You need to call curl_exec($ch); before curl_getinfo($ch); cause this is the actual connection to the server:
also there is no need in the flag CURLOPT_POST since it's a get call:
// create a new cURL resource
$ch = curl_init();
//for post calls:
//$post = 'a=b&d=c';
//$headers[] = 'Content-type: application/x-www-form-urlencoded;charset=utf-8';
//$headers[] = 'Content-Length: ' . strlen($post);
//for get calls:
$headers = array();
$headers[] = 'Content-type: charset=utf-8';
$headers[] = 'Connection: Keep-Alive';
// set URL and other appropriate options
curl_setopt($ch, CURLOPT_URL, "http://www.yahoo.com");
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
//curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_exec($ch);
$report=curl_getinfo($ch);
print_r($report);
// grab URL and pass it to the browser
if(curl_errno($ch)) {
echo 'Curl error: ' . curl_error($ch);
}
print curl_error($ch);
// close cURL resource, and free up system resources
curl_close($ch);

Categories