Curl and php download file from url not working - php

I'm trying do retrieve and download a file (image) from a remote location.
Inside the php.ini the allow_url_fopen is enabled, but i can't download the image.
Code i'm using is described below
$local_file = "test.jpg";
$remote_file = "http://somehost:6346/cgi-bin/CGIProxy.fcgi?cmd=snapPicture2&usr=xxxx&pwd=xxxx";
$ch = curl_init();
$fp = fopen ($local_file, 'w+');
$ch = curl_init($remote_file);
curl_setopt($ch, CURLOPT_TIMEOUT, 50);
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_ENCODING, "");
curl_exec($ch);
curl_close($ch);
fclose($fp);
with any other url that contains a real jpg file, it's working perfectly, i suppose that the issue is that the url use some special characters that doesn't like to curl.
If i try to execute the php snippet above,page load for almost 1 minute,and it seems that no error are displayed,the image test.jpg is created, but it's empty.
Do you have any suggestion?
Thanks!

Try this
$local_file = "test.jpg";
$remote_file = "http://somehost:6346/cgi-bin/CGIProxy.fcgi?cmd=snapPicture2&usr=xxxx&pwd=xxxx";
function getPage($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_REFERER, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
function saveToFile($base, $decode=false, $output_file)
{
$ifp = fopen($output_file, "wb");
if ($decode){
fwrite($ifp, base64_decode($base));
}else{
fwrite($ifp, $base);
}
fclose($ifp);
return($output_file);
}
$remote_page = getPage($remote_file);
$saved_file = saveToFile($remote_page , false, $local_file);

when debugging issues like this, set CURLOPT_VERBOSE, it will probably reveal why the page loaded for almost 1 minute, with no apparent output.
i suppose that the issue is that the url use some special characters - this is fully possible, for example your username and password, they're supposed to be urlencoded. urlencoding is binary safe, meaning you can have any special characters you'd like, you just need to encode it properly. use urlencode() or http_build_query() for that, eg
$remote_file = "http://somehost:6346/cgi-bin/CGIProxy.fcgi?" . http_build_query ( array (
'cmd' => 'snapPicture2',
'usr' => 'username',
'pwd' => 'password'
) );
now http_build_query will properly urlencode any special characters in your username and password (for example, if your username is an email address, the # becomes %40).
if that doesn't fix it, what does CURLOPT_VERBOSE say?
also, final note, here you're sending the download request with credentials in a GET request. that's very unusual, the vast majority of websites want you to login with a POST request, and there are good security-related reasons for that, are you sure your website allows sending credentials in GET parameters? the vast majority of websites doesn't allow it... (and the best way to find out, is to record a browser logging in, does the browser use GET parameters, or POST parameters?)

Related

PHP copy() doesn't work for random URLS which redirect to files

trying to copy() .MP3 file from remote url but it always fails.
$link = str_replace(' ','%20','http://mp3hungama.com/music/download.php?song_id=80522');
if (!copy($link,'/home2/muser/tmp/newname.mp3')) {
echo 'copy failed !';
}
$link url redirects to http://mp3hungama.com/music/audio//Indian%20Movies/Indian%20Movies%20Hindi%20Mp3%20Songs/Singh%20Is%20Bling%20(2015)/songs/Cinema%20Dekhe%20Mamma%20#%20Mp3HunGama.Com.mp3
same code works for others random urls like www.example.com/download.php?id=2332. what's the specifically problem here or any other way to do this job ?
I've tested your code and I also couldn't download the file, then, I've used curl an it work as expected:
$local_file = "/home2/muser/tmp/newname.mp3";//This is the file where we save the information
$remote_file = "http://mp3hungama.com/music/download.php?song_id=80522"; //Here is the file we are downloading
$ch = curl_init();
$fp = fopen ($local_file, 'w+');
$ch = curl_init($remote_file);
curl_setopt($ch, CURLOPT_TIMEOUT, 50);
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_ENCODING, "");
curl_exec($ch);
curl_close($ch);
fclose($fp);
NOTE:
Make sure /home2/muser/tmp/ has write permissions.
TIP:
In the future, if you need to encode/decode a url, use urlencode or urldecode instead of str_replace
This link
already redirects to second link. So it's working already.

Collecting file with PHP CURL after validating request downloads an empty file

I am doing a system where one of my sites goes to the other to get documents.
On the first site I am using Curl to make a request to get the file wanted:
I am using the solution from Download file from URL using CURL :
function collect_file($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_AUTOREFERER, false);
curl_setopt($ch, CURLOPT_REFERER, "http://example.com");
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_HEADER, 0);
$result = curl_exec($ch);
curl_close($ch);
echo $result;
return($result);
}
function write_to_file($text,$new_filename){
$fp = fopen($new_filename, 'w');
fwrite($fp, $text);
fclose($fp);
}
$curlUrl = 'http://site2.com/file-depository/14R4NP8JkoIHwIyjnexSUmyJibdpHs5ZpFs3NLFCxcs54kNhHj';
$new_file_name = "testfile-new.png";
$temp_file_contents = collect_file($curlUrl);
write_to_file($temp_file_contents,$new_file_name);
I am testing downloading an image. If i use a direct URL into $curlUrl , for instance http://site2.com/file-depository/image.png it works perfect.
What I am doing is that the URL http://site2.com/file-depository/14R4NP8JkoIHwIyjnexSUmyJibdpHs5ZpFs3NLFCxcs54kNhHj is then parsed and checked against a database to match the document requested, once there is a document matched I need to provide this document to the Curl response.
I have tried many ways to read the file but everytime i am getting a file on the other end but it is only 1kb in size (45 expected) and when trying to open it i get an error unkown file type etc.
On the second site, once the URL is validated here is what I have:
$file = readfile('some-image.png');
echo $file;
I am guessing there is part of the information which belongs to the file missing but can't figure it out, any pointers appreciated!
I have replaced
function write_to_file($text,$new_filename){
$fp = fopen($new_filename, 'w');
fwrite($fp, $text);
fclose($fp);
}
by file_put_contents($new_file_name,trim($temp_file_contents));
Please note the trim(), the issue was that I was apparently collecting some empty space in front of the file content.

'file_get_contents' The contents are encrypted?

The problem is when i use file_get_contents to get source (HTML) from this site, the result that i receive is NOT a plain html code.
The code i used:
$source = file_get_contents("http://mp3.zing.vn/bai-hat/Dance-With-My-Father-Luther-Vandross/ZWZ9D6FD.html");
echo $source;
// OR print_r($source);
The source i received:
��}{�#Ǒ��-��!E��=��Mv�5�B���R�����h��E�HV7YE�������a�X��p{��[�:�!{��;,v��u��Or��̬��Y��M��ʌ̌�����������F��ޖ����ػ��S� #�~��H�7k�����ʎȦ2���M?�ު&D�����t���$u�O��N���>%(Y����I��Vb�[���VN�=�[�![*�dE*�]3:�ޑ�xiA���Z��g ��祇VejI �R�y�֨�ea��o��s�M/�... *MORE
I tried with cURL, but i also received the same result:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://mp3.zing.vn/bai-hat/Dance-With-My-Father-Luther-Vandross/ZWZ9D6FD.html");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$source = curl_exec($ch);
curl_close($ch);
I think the source i received must have been encrypted, but if i use browser to view source, the source will NOT be encrypted.
Eventually, i dont really know what happened, and how to get the plain source (plain HTML) ?
It's gzip compressed, just set the correct encoding and you're good to go
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://mp3.zing.vn/bai-hat/Dance-With-My-Father-Luther-Vandross/ZWZ9D6FD.html");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch,CURLOPT_ENCODING , "gzip");
$source = curl_exec($ch);
curl_close($ch);
Take a look at gzdecode (requires the ZLIB PHP module, though - if you don't have it, I'd strongly consider to use JimL's method using cURL).
string gzdecode ( string $data [, int $length ] )
$source = file_get_contents("http://mp3.zing.vn/bai-hat/Dance-With-My-Father-Luther-andross/ZWZ9D6FD.html");
echo gzdecode($source);
// OR print_r($source);

How can I upload a file that has spaces is its name with curl + php?

I'm using this code for uploading a file to my server, using HTTP POST:
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_VERBOSE, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
$post = array(
"upload" => '#' . $filepath
);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
$curl_result = curl_exec($ch);
This code works when $filepath does not contain spaces. However, it is possible that it might. When I test a path with spaces, I get the curl error "failed creating formpost data".
The curl manual does not tell me what to do, all it gives me are unix filenames without spaces. I tried following http://curl.haxx.se/mail/archive-2006-01/0079.html like so, but it didn't help me either:
"upload" => '"#' . $filepath . '"'
"upload" => '#"' . $filepath . '"'
Anyone have an idea?
Current versions of cURL (and PHP-cURL) handle spaces in filenames with no problems. Older versions may have had bugs, I'm not sure. Check you're using reasonably recent versions.
I can confirm spaces in filenames are no problem at all under PHP 5.2.13 and libcurl/7.19.4 on Linux.
The error message you're getting is the same one as when PHP/cURL can't find a file. Odds are the problems are somewhere else in your code. Probably an issue of having under- or over-escaped the spaces in the filename but probably not an issue with cURL itself.
I'd suggest looking elsewhere in your code for the problem or producing a hard-coded example of the problem occurring (where $filename is being set in the PHP directly rather than read from elsewhere).
You need the realpath
$filepath = 'D:\7 habits copy.txt';
$url = 'http://www.speedyshare.com/upload.php?'.rand(10000000, 99999999);
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_VERBOSE, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
$post = array(
"upload" => '#' . realpath($filepath)
);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
$curl_result = curl_exec($ch);
echo $curl_result;
Worked even on Windows. I'm pretty sure it will work on *NIX systems
I faced the same problem and I couldn't upgrade CURL on the system.
So I wrote a simple escape function that iterated on the string to replace the space character for the + sign, which is the traditional way to represent URLs with spaces.
For my surprise, it worked. :)
C++ code:
#include <algorithm>
#include <string>
std::string s = "";
std::replace(s.begin(), s.end(), ' ', '+');
You will need to escape the spaces. Not sure of the syntax you would use but maybe something like this:
'This is the file name with spaces.txt'
to
'This\ is\ the\ file\ name\ with\ spaces.txt'
again I'm not sure of the syntax it's just an example
or you might just need to add quotes to the file name, like this:
'This is the file name with spaces.txt'
Put the target file in a variable, such as 'while read', and pass the variable in the curl the command. Be sure the variable is in double quotes and curl will handle it.
For example:
curl -T /PATH/TO/YOUR/FILE/DIRECTORY/"$f"

Updating Twitter background via API

I'm having a little trouble updating backgrounds via Twitter's API.
$target_url = "http://www.google.com/logos/11th_birthday.gif";
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
curl_setopt($ch, CURLOPT_USERAGENT, $userAgent);
curl_setopt($ch, CURLOPT_URL,$target_url);
curl_setopt($ch, CURLOPT_FAILONERROR, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_AUTOREFERER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$html = curl_exec($ch);
$content = $to->OAuthRequest('http://twitter.com/account/update_profile_background_image.xml', array('profile_background_image_url' => $html), 'POST');
When I try to pull the raw data via cURL or file_get_contents, I get this...
Expectation Failed The expectation given in the Expect request-header
field could not be met by this server.
The client sent
Expect: 100-continue but we only allow the 100-continue expectation.
OK, you can't direct Twitter to a URL, it won't accept that. Looking around a bit I've found that the best way is to download the image to the local server and then pass that over to Twitter almost like a form upload.
Try the following code, and let me know what you get.
// The URL from an external (or internal) server we want to grab
$url = 'http://www.google.com/logos/11th_birthday.gif';
// We need to grab the file name of this, unless you want to create your own
$filename = basename($url);
// This is where we'll be saving our new file to. Replace LOCALPATH with the path you would like to save the file to, i.e. www/home/content/my_directory/
$newfilename = 'LOCALPATH' . $filename;
// Copy it over, PHP will handle the overheads.
copy($url, $newfilename);
// Now it's OAuth time... fingers crossed!
$content = $to->OAuthRequest('http://twitter.com/account/update_profile_background_image.xml', array('profile_background_image_url' => $newfilename), 'POST');
// Echo something so you know it went through
print "done";
Well, given the error message, it sounds like you should load the URL's contents yourself, and post the data directly. Have you tried that?

Categories