Downloading files using PHP and cURL - php

I used this function for downloading SWF files(flash games) sucessfully. When I use this script for one particular site it downloads all games(I told the script to download 4 games from a list) with exact size of 299bytes? I tried downloading these games with Google Chrome and the download is sucessfull. Is there something missing in the CURL functions I use or the download algorithm is not good enough? Any help will be greatly appreciated.
function saveFlash($fullPaths,$folder,$gamenames,$i){
$curl = curl_init($fullPaths[$i]);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
//Create a new file in the given folder
$fp = fopen($folder."/".$gamenames[$i].".swf", 'w');
if ($fp == FALSE){
echo "File not opened<br>";}
//Ask cURL to write the contents to a file
curl_setopt($curl, CURLOPT_FILE, $fp);
//Execute the cURL session
curl_exec ($curl);
//Close cURL session and file
curl_close ($curl);
fclose($fp);
}
Text editor gives the following
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>302 Found</title>
</head><body>
<h1>Found</h1>
<p>The document has moved here.</p>
<hr>
<address>Apache/2.2.3 (CentOS) Server at freeonlinegames.com Port 80</address>
</body></html>

You'll want to set CURLOPT_FOLLOWLOCATION to allow it to follow the redirects.
You may also want to set a CURLOPT_MAXREDIRS so it doesn't redirect out of control.

That error you're getting is a common way of telling you that no hotlinking is allowed. If you simply want to download the SWF, you need to set the referrer.
curl_setopt($ch, CURLOPT_REFERER, 'http://urlofpagetheswfwasfoundon');
If it still doesn't work after that, you might need to set an appropriate user-agent string.
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 Something Something');
Also, be very sure that you are allowed to do what you are trying to do. Ripping stuff off others' sites is very frowned upon, and usually illegal.

Related

Can't copy images from Tumblr to my site, connection timed out error

Tumblr image example:
https://69.media.tumblr.com/ec3874e541a767ab578495b762201a53/tumblr_ph9je0Akck1r89eh5o1_1280.jpg
Code:
<form method="get">
<input type="text" name="url"/>
<input type="submit" value=" загрузить "/>
</form>
<?php
$name = md5(date('Y-m-d H:i:s').rand(0, 1000));
$folder = 'upload/';
$source = ($_GET['url']);
$dest = $folder.$name.'.png';
copy($source, $dest);
echo 'http://mysite.example/'.$folder.$name.'.png';
?>
I found this in another question on this site:
If you can view the image in a browser that is on the same machine as your program, then it might be that the server won't send the picture unless you look like a user rather than a program. In that case, modifying the browser identification string might fix your problem.
If you cannot view the image from a browser running on the program's PC, you will need to look elsewhere for the source of your problem.
I think, a problem i have is similar to this. Tumblr gives picture to view in a browser, but doesn't allow to copy it with a script.
How to fix that? For example, sites like imgur can upload Tumblr images by url with no any problem.
P.S. For images from other sites copying with this script goes normally.
Addition 01:
As it turned out, the problem is with my site. When i run this code on another site, it works normally with Tumblr images. I have a free domain .ml and free hosting Byethost. I have two guessings. The first is, my domain or hosting is in a blacklist on Tubmlr. The second one, i have some wrong settings on my site. If first guessing is right, is there any way to make it works without changing domain or hosting? If the second is true, what a settings i must check and change?
Tumblr appears to be inspecting the HTTP request and generating different responses depending on how you get it. Your code is fine, as you know, for most sites. When I run it as-is, I get a 403 denied error.
Changing the code to use Curl instead allowed me to download your file. My guess is the default headers used in PHP's copy() are blocked.
<?php
function grab_image($url,$saveto){
$ch = curl_init ($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_BINARYTRANSFER,1);
$raw=curl_exec($ch);
curl_close ($ch);
if(file_exists($saveto)){
unlink($saveto);
}
$fp = fopen($saveto,'x');
fwrite($fp, $raw);
fclose($fp);
}
$name = md5(date('Y-m-d H:i:s').rand(0, 1000));
$folder = 'upload/';
$source = ($_GET['url']);
$dest = $folder.$name.'.png';
grab_image($source, $dest);
The grab_image() function was a SO answer for another question.

php curl return downloaded content to user while file is still downloading

I want to server begins to download a big file. But while this file is downloading output the file content to the user. I tried this code:
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_TIMEOUT, 155000);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$response = curl_exec($ch); // get curl response
echo $response;
But this code takes a long time. I want to use curl instead of readfile.
See this answer: Manipulate a string that is 30 million characters long
Modifing the MyStream class should change it enough so that you can just echo the results to the browser. Assuming the browser is already downloading the file, it should just keep downloading it.

PHP - Download cURL result

I wrote function below:
function download_xfs($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_COOKIE, 'login=michael; xfss=08ruiweu4tuhb5xqs8');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
$string = curl_exec ($ch);
curl_close ($ch);
// Set headers
}
When I use download_xfs("http://address.com/file.html"); it returns binary of file instead of actual file. Can anyone re-write this code to handle file for download?
Your error is not in downloading a file, PNG is propably downloaded OK, but you propably just echo'ing it to screen. You must set HTTP header proper for this file mime type:
header( 'Content-type: image/png' );
But remember do do not echo any other strings/characters before and after image contents (absolutelly nothing, even invisible BOM info about UTF created by Windows notepad on a begining of a php file). If you want to include a image downloadable by your server in your HTML page, you must create another .php with this header and image contents and include it by:
<img src="image_from_download.php">
if you want to receive plain text, but have a unexpected binary
There can be some unknown solution on remote serverer, that sends something different or redirects you to a image dependly on user agent.
Try to set user agent in cUrl to same as your original browser.
Also, make sure that content served by remote server is not gzipped or chunked (i don't know, that curl unzip it automatically?) by sending proper Accept header in HTTP request.
This problem can be also state-depended, maybe you need some cookies set or be logged in remote web application from where you are retreiving .html
Try to turn off your FOLLOWLOCATION, maybe you received a 30x redirect to a image.

PHP rel=NOFOLLOW

I want to download files, from an website using PHP.
And i want to create an php script to download files without going on their website to download files. I just want to pun their link on my script an download the file automatically.
I try with CURL, but doesn't work.... The link is like this <a rel="nofollow" href="/download-15866-114621.srt"><b>Download</b></a>
the code :
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,
'http://subtitrari.regielive.ro/download-15866-114621.srt');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$contents = curl_exec ($ch);
echo $contents;
curl_close ($ch);
I get "download failed!" as content, which means they probably have some sort of download protection. The best thing is probably to ask them what you should do (assuming you have their permission to download the file) or stop trying (assuming you don't).
Eitherway, try setting a referer header with CURLOPT_REFERER. Maybe they check that header to see that no-one is hotlinked to the file.

PHP cURL sending and receive Images Client / Server

I have been researching this for a while and have not been find an answer for this.
I have a Client Site making calls to our API Server. What I would like to transfer an image to the Client Site when a special call is made.
I have some code that downloads the image from the server, but this is causing us to make multiple calls forcing us to create all these images in the server that we don't want to keep, even if we delete them afterward.
$originalFileUrl = createImage('createImage', $fileName);
downloadImage($originalFileUrl, $fileDestination);
deleteFileFromServer('deleteImage', $fileName);
function serverCall ($action, $fileName) {
$serverCall = $SERVER.'/api.php?fileName=' . $fileName . '&action=' . $action;
ob_start();
$ch = curl_init();
$timeout = 5;
curl_setopt ($ch, CURLOPT_URL, $serverCall);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 0);
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
curl_exec($ch);
$fileContents = ob_get_contents();
curl_close($ch);
ob_end_clean();
return $fileContents;
}
function downloadImage ($originalFileUrl, $fileDestination) {
// Starting output buffering
ob_start();
// create a new CURL resource
$ch = curl_init();
// set URL and other appropriate options
curl_setopt($ch, CURLOPT_URL, $originalFileUrl);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// set timeouts
set_time_limit(30); // set time in secods for PHP
curl_setopt($ch, CURLOPT_TIMEOUT, 30); // and also for CURL
// open a stream for writing
$outFile = fopen($fileDestination, 'wb');
curl_setopt($ch, CURLOPT_FILE, $outFile);
// grab file from URL
curl_exec($ch);
fclose($outFile);
// close CURL resource, and free up system resources
curl_close($ch);
ob_end_clean();
}
Where $originalFileUrl is the current location of the file, and $fileDestination is the path to where I want my new file to be.
My question is: Can I make a call to a PHP file in the Server that will be in charge of create, transfer and delete the image all in one call rather than doing multiple calls?
Also for multiple reasons ftp the file from the server to the client is not a good option.
Thank you
This will not be a trivial task. However, you should be able to design a successful approach. This won't be the most error-safe method of accomplishing the task, though. You're thinking right now of a HTTP-esque stateless protocol, which is manageable. If the description below doesn't sound good enough, consider another protocol which can maintain a constant bi-directional connection (like an SSH tunnel).
You'd likely suffer data overhead, but that would generally be more than acceptable in order to save multiple calls. To that end, I'd advise creating an XML interface. On the receiving end, your XML would have an element with either a Base64 representation of the image, or possibly a gzipped CDATA implementation. You don't have to stick to any XML standard, but if you do, the PHP XML Parser could help with some of the legwork.
So, to recap, in this model, the server end could receive a set of commands which do what you've called out: move the file into a processing folder, create a Base64 string of the file contents, craft the XMl package, and return it. The client will send a request, and process the response. If the client detects an error, it could retry and the server can still grab the file data from the processing queue.
If error becomes an issue and an open socket isn't a good option (because the coding is difficult), you could also develop a delete-batching system, where you track the files in the processing folder and only delete them on request. But, you'd only make delete requests from the client every once in a while, and possibly not as a part of any particular page with a user experience, but from a cron.

Categories