400 http code error using PHP & CUrl & gifs.com API - php

I looked for a sample code for php & curl and i found this link http://www.php-guru.in/2013/upload-files-using-php-curl/
I tried using the code with gifs.com API to try to convert gif to mp4 (for speed reasons) then display it on my site. i tried using a giphy url to upload to gifs.com and so i ended up with the code below.
$url = 'https://api.gifs.com/media/upload';
$headers = array("Content-Type:multipart/form-data", "Gifs-API-Key:gifkey"); // cURL headers for file uploading
$postfields = array("file" => "#https://media.giphy.com/media/l378drKbCncSKYbS0/giphy.gif", "title" => 'guineapig');
$ch = curl_init();
$options = array(
CURLOPT_URL => $url,
CURLOPT_HEADER => true,
CURLOPT_POST => 1,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_POSTFIELDS => $postfields,
CURLOPT_RETURNTRANSFER => true
); // cURL options
curl_setopt_array($ch, $options);
$server_output = curl_exec($ch);
if (!curl_errno($ch)) {
$info = curl_getinfo($ch);
echo $info['http_code'];
echo $server_output;
} else {
$errmsg = curl_error($ch);
echo $errmsg;
}
curl_close ($ch);
The problem is, it's always showing a 400 http_code and i don't know what the problems is
here is the full error it displays
HTTP/1.1 100 Continue HTTP/1.1 400 Bad Request Server: nginx Date: Thu, 02 Nov 2017 13:44:05 GMT Content-Type: text/plain; charset=utf-8 Content-Length: 0 Access-Control-Allow-Credentials: false Access-Control-Allow-Headers: Origin, Accept,Content-Type,Gifs-API-Key Access-Control-Allow-Methods: GET,POST,OPTIONS Access-Control-Allow-Origin: * Access-Control-Max-Age: 43200 Request-Id: 9b78a2d3-0f25-4f13-bb2d-a40b75e6fa8f Via: 1.1 google Alt-Svc: clear
I don't understand the error
note: I'm using a localhost xampp server, Is this the cause of it messing up?

turns out i only needed to use their import API since it's a link to a gif rather than a file upload, so i changed the header with a json instead of a multipart-form
$url = 'https://api.gifs.com/media/import';
$headers = array("Gifs-API-Key: gifkey", "Content-Type: application/json"); // cURL headers for file uploading
$postfields = "{\n \"source\": \"https://media.giphy.com/media/l378drKbCncSKYbS0/giphy.gif\",\n \"title\": \"guineapig\",\n \"tags\": [\"crazy\", \"hand drawn\", \"2015\", \"art\"],\n \"attribution\": {\n \"site\": \"vine\",\n \"user\": \"someone\"\n }\n}";
$ch = curl_init();
$options = array(
CURLOPT_URL => $url,
CURLOPT_HEADER => true,
CURLOPT_POST => 1,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_POSTFIELDS => $postfields,
CURLOPT_RETURNTRANSFER => true
); // cURL options
curl_setopt_array($ch, $options);
$server_output = curl_exec($ch);
if (!curl_errno($ch)) {
$info = curl_getinfo($ch);
echo $info['http_code'];
echo $server_output;
} else {
$errmsg = curl_error($ch);
echo $errmsg;
}
curl_close ($ch);

Related

How do I use Oauth2 using cURL and PHP

I can't get the folling script to work:
I'm using an api called swiftdil. Their example is as follows:
Example request:
curl -X POST https://sandbox.swiftdil.com/v1/oauth2/token \
-H 'Content-Type: application/x-www-form-urlencoded' \
-u 'your_username:your_password'
Example output:
{
"access_token":"your_access_token",
"expires_in": 3600,
"refresh_expires_in": 1800,
"refresh_token": "your_refresh_token",
"token_type": "bearer",
"not-before-policy": 0,
"session_state": "your_session_state"
}
So the url I've to submit my credentials to is https://sandbox.swiftdil.com/v1/oauth2/token
I've tried the following code:
// Api Credentials
$url = 'https://sandbox.swiftdil.com/v1/oauth2/token';
$username = "my_username";
$password = "my_password";
// Set up api environment
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:
application/x-www-form-urlencoded'));
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_USERPWD, $username . ":" .
$password);
// Give back curl result
$output = curl_exec($ch);
$info = curl_getinfo($ch);
$curl_error = curl_error($ch);
curl_close($ch);
print_r($output);
print_r($info);
print_r($curl_error);
?>
The script is giving me back the following result:
HTTP/1.1 400 Bad Request Server: nginx/1.13.8 Date: Tue, 15 May 2018 09:17:26 GMT Content-Type: text/html Content-Length: 173 Connection: close
400 Bad Request.
Am I missing something? I do fullfill the needs of the example given above right? I do make a postcall, give all the credenatials as asked, but still can't get anything back.
I am not a PHP developer, I mostly do JavaScript. When I integrate with other REST services I tend to use Postman (https://www.getpostman.com/).
Try the following:
Attempt to successfully connect with the API using Postman (should be relatively straightforward).
When successful, Postman has the ability to generate PHP code automatically, which you can then copy and paste. Works like a charm with JavaScript, don't see why it will be any different with PHP.
I just filled in the details in postman based on what you provided:
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://sandbox.swiftdil.com/v1/oauth2/token",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => array(
"Authorization: Basic bXlfdXNlcm5hbWU6bXlfcGFzc3dvcmQ=",
"Content-Type: application/x-www-form-urlencoded"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
Please note, 'Authorization: Basic' can be used as basic authorization mechanism instead of 'Bearer' (it should work too). So replace 'bXlfdXNlcm5hbWU6bXlfcGFzc3dvcmQ' with the base64 encoded string 'username:password' (use actual username and password).
You also need to set the curl post fields by setting the below option as per your data.
"curl_setopt($ch, CURLOPT_POSTFIELDS, array(
'code' => $code,
'client_id' => $client_id,
'client_secret' => $client_secret,
'redirect_uri' => $redirect_uri,
'grant_type' => 'authorization_code'
))";
If still not work, you can find the curl error as :
if(curl_error($ch))
{
echo 'error:' . curl_error($ch);
}

Accept-Language of CURLOPT_HTTPHEADER does not work

cUrl set language header
I was trying to get the source code of Facebook's homepage by using cURL, but it was all Chinese due to the location of my server host. For this reason, I added Accept-Language of CURLOPT_HTTPHEADER to change the language to English, but failed. According to the answer I quoted above, below is the PHP code of cURL I tried:
<?php
$url = "http://www.facebook.com/";
if(isset($_SERVER['HTTP_USER_AGENT']))
$user_agent = $_SERVER['HTTP_USER_AGENT'];
else
$user_agent = "";
$options = array(
CURLOPT_RETURNTRANSFER => true, // return web page
CURLOPT_HEADER => false, // don't return headers
CURLOPT_FOLLOWLOCATION => true, // follow redirects
CURLOPT_HTTPHEADER => array("Accept-Language: en-US;q=0.6,en;q=0.4"),
CURLOPT_USERAGENT => $user_agent);
$ch = curl_init($url);
curl_setopt_array($ch, $options);
$content = curl_exec($ch);
$err = curl_errno($ch);
$errmsg = curl_error($ch);
$header = curl_getinfo($ch);
curl_close($ch);
echo $content;
?>
But it still showed Chinese:
How can I solve this problem?

PHP curl() get all header at one time

<?php
$url = 'http://fb.com';
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $url,
CURLOPT_HEADER => true,
));
$header = explode("\n", curl_exec($curl));
curl_close($curl);
print_r($header);
Result
HTTP/1.1 301 Moved Permanently
Location: http://www.facebook.com/?_rdr
Vary: Accept-Encoding
Content-Type: text/html
X-FB-Debug: rVg0o+qDt9z/zJu7jTW1gi1WSRC8YIMu3e6XnPagx39zZ4pbV0k2yrNfZmkdTLZyfzg713X+M0Lr2jS2P018xA==
Date: Thu, 25 Feb 2016 08:48:08 GMT
Connection: keep-alive
Content-Length: 0
But I want to get all Location at one time
I enter > http://fb.com
then 301 redirect: http://www.facebook.com/?_rdr
then 302 redirect: https://www.facebook.com/
I want to get All this link at one time with status 301 302
or any better idea to get redirect location url . THANKS
You can get all headers from every request made until no Location header is sent using this:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_NOBODY, true);
$headers = curl_exec($ch);
curl_close($ch);
But then, you'll have to extract the information yourself because $headers is only a string, not an array.
If you only need the last location, simply do curl_getinfo($ch,CURLINFO_EFFECTIVE_URL).
Use curl_getinfo() to check if you got a 301 or 302 response and then repeat the same code again as long as that's the case. So, put your code in a function like:
$headers = array();
function getHeaders($url) {
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $url,
CURLOPT_HEADER => true,
));
$header = explode("\n", curl_exec($curl));
if (in_array(curl_getinfo($curl, CURLINFO_HTTP_CODE), array(301, 302))) {
// Got a 301 or 302, store this stuff and do it again
$headers[] = $header;
curl_close($curl);
return getHeaders($url);
}
$headers[] = $header;
curl_close($curl);
}
Then $headers will hold all the headers encountered up until the first non-301/302 response.

How to header stream_context_create?

I have the following code:
$options = array(
'http' => array(
'header' => "Content-type: text/html\r\n",
'method' => 'POST'
),
);
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
This is not giving the appropriate result (no result at all), since the equivalent curl is:
function curl($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_POST, 1);
$data = curl_exec($ch);
curl_close($ch);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
echo $httpcode;
return $data;
}
curl($url);
actually gives the actual result.
Since i'd like to avoid curl in production server, i'd really like the file_get_contents to work. To debug this, I have decided to examine the header for both curl and file_get_contents. In the curl code above, you can notice an echo, which prints the header:
HTTP/1.0 411 Length Required Content-Type: text/html; charset=UTF-8
Content-Length: 1564 Date: Thu, 03 Dec 2015 18:00:25 GMT Server:
GFE/2.0
I'd like to do the same for file_get_contents to examine its headers and hope fully see what is wrong. (you could point out what's wrong yourself if you like).
Something like this should work:
<?php
$url = 'http://example.com/';
$data = ''; // empty post
$options = array(
'http' => array(
'header' => "Content-type: text/html\r\nContent-Length: " . strlen($data) . "\r\n",
'method' => 'POST'
),
);
$context = stream_context_create($options);
$fp = fopen($url, 'r', false, $context);
$meta = stream_get_meta_data($fp);
if (!$fp) {
echo "Failed!";
} else {
echo "Success";
$response = stream_get_contents($fp);
}
fclose($fp);
var_dump($meta);
To get the stream meta data, you will need to switch from file_get_contents to fopen. It makes no difference as under the hood, PHP will connect and issue the response in the same way (using the http:// wrapper).
If php.ini is set to disable allow_url_fopen, the both file_get_contents and fopen will be affected and won't be able to open remote URLs. As long as this isn't the case, fopen of a URL will work the same way as file_get_contents; using fopen just gives you access to the stream which you can then call stream_get_meta_data on.

curl fails to correctly send headers

My initial project was of checking whether a certain Apple ID exists or not, I have proceeded doing this in php by navigating to apppleid.apple.com/account/ and pretending to register an account with all the fields blank except the account field, and if I got an error it meant the account existed, otherwise If I got other errors but not an "account exists" error I would return false. However I have encountered a few problems on the way. The first was that you need to preserve all the headers/cookies on the way (which I did) but it still does not work, and apparently always answers with "1". The code can be found here : PASTEBIN. Please follow the link and try to solve this problem, I really need this done. Thank you very much whoever got some time to read this post.
EDIT
code:
<?php
require("simplehtmldom_1_5/simple_html_dom.php");
$input = get_data('https://appleid.apple.com/account');
$html = new simple_html_dom();
$html->load($input);
//echo $input;
$table = array();
foreach($html->find('input') as $inn)
{
$val = "";
try
{
$val = $inn->getAttribute('value');
}
catch (Exception $e)
{
$val = "";
}
//echo $inn->getAttribute('name') . $val . "\n";
if($inn->getAttribute('name') != "" && $inn->getAttribute('name') != "account.name")
{
$table[$inn->getAttribute("name")] = $val;
}
if($inn->getAttribute('name') == "account.name")
{
$table[$inn->getAttribute("name")] = "naclo3samuel#gmail.com";
}
}
$NIX = http_build_query($table);
//set the url, number of POST vars, POST data
$ch = curl_init();
$hs = get_headers("https://appleid.apple.com/account", 0);
$headers = $hs;
curl_setopt($ch,CURLOPT_URL, "https://appleid.apple.com/account/");
curl_setopt($ch,CURLOPT_POST, count($NIX));
curl_setopt($ch,CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch,CURLOPT_POSTFIELDS, $NIX);
//execute post
$result = curl_exec($ch);
echo $result;
//close connection
curl_close($ch);
/* gets the data from a URL */
function get_data($url) {
$ch = curl_init();
$timeout = 5000;
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
?>
One of the problems is right here: get_headers("https://appleid.apple.com/account", 0);
This will return something like:
[0] => HTTP/1.1 200 OK
[1] => Date: Sat, 29 May 2004 12:28:13 GMT
[2] => Server: Apache/1.3.27 (Unix) (Red-Hat/Linux)
[3] => Last-Modified: Wed, 08 Jan 2003 23:11:55 GMT
[4] => ETag: "3f80f-1b6-3e1cb03b"
[5] => Accept-Ranges: bytes
[6] => Content-Length: 438
[7] => Connection: close
[8] => Content-Type: text/html
What is cURL supposed to do with that? This is not in a format acceptable by CURLOPT_HTTPHEADER and neither headers a Server would expect from a Client request.
I suppose you are trying to stablish Cookie session. I recommend you do all that without use of get_headers() or putting your finger in the headers at all.
Enable cURL's Cookie support by setting the options CURLOPT_COOKIEJAR and CURLOPT_COOKIEFILE, make a call to https://appleid.apple.com/account to initialize your Cookies, and then do the rest.
Example:
$cookies = tmpfile();
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://appleid.apple.com/account/",
CURLOPT_COOKIEJAR => $cookies,
CURLOPT_COOKIEFILE => $cookies,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HEADER => true
]);
curl_exec();
curl_setopt_array($curl, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $NIX
]);
$result = curl_exec($ch);
$hsize = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
$headers = explode("\r\n", substr($result, 0, $hsize));
$result = substr($result, $hsize);

Categories