Image corrupted after php curl transfer FTP - php

I am using the following code to transfer an image and it is working except the jpg is corrupted after the transfer. Is says invalid image format and shows a blurred image.
I tried using regular php without curl and get the same results.
Does anyone know why whatever I try works but corrupts the image.jpg
$curl = curl_init();
$fh = fopen("test.jpg", 'w');
curl_setopt($curl, CURLOPT_URL, "ftp://{$serverInfo['user']}: {$servererInfo['password']}#{$serverInfo['ftp1.server.com']}/{$serverInfo['For_Web/Web Images/Full Size/00-99/file']}");
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($curl);
fwrite($fh, $result);
fclose($fh);
curl_close($curl);`

There are a few problems;
You should open your file for writing in binary mode, that is;
$fh = fopen("test.jpg", 'wb');
curl_exec returns a bool (success), not the contents of the file, the file should instead be passed to CURLOPT_FILE.
You should set the username/password using CURLOPT_USERPWD, not sure if the URL way could be made to work too, though.
You should set CURLOPT_BINARYTRANSFER.
Working sample;
$curl = curl_init();
$fh = fopen("fips.exe", 'wb');
curl_setopt($curl, CURLOPT_URL, 'ftp://ftp.sunet.se/pub/FreeBSD/tools/fips.exe');
curl_setopt($curl, CURLOPT_BINARYTRANSFER, 1);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_FILE, $fh);
curl_setopt($curl, CURLOPT_USERPWD, 'anonymous:olle');
$result = curl_exec($curl);
fclose($fh);
curl_close($curl);

Related

Download image from website that requires authentication/credentials using php

The $source is the url link of an image from a website that requires authentication/login. I was able to download the image but the downloaded image can't be opened. I knew the image is not downloaded properly as it is asking for credentials. I use CURL to download the image and now, I have no idea what's wrong with the code, what else should i add to it??
<?php
$username = $_SESSION["username"];
$password = $_SESSION["password"];
$source = 'https://example.com/sequence.png';
$fp = fopen('C:/image/'.basename($source), 'w');
$ch = curl_init($source);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY ) ;
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");// to use for connection
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 1);// content type
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_exec($ch);
fclose($fp);
?>
If your authentication is not basic, you need some library like Guzzle.
You can do the login process and then download the image

How to tell if curl download is complete using CURLOPT_FILE in PHP

I have a function that downloads a specific zip file from a remote server to my local Windows server. The file ranges in size from 1-10 mb and I want my script to wait until it's complete. How can I tell with certainty that it's done? The actual downloading works fine.
The function is:
function get_download($url, $path)
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL,$url);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($curl, CURLOPT_RETURNTRANSFER,1);
curl_setopt($curl, CURLOPT_COOKIEFILE, 'cookie2.txt');
curl_setopt($curl, CURLOPT_FILE, $path);
$results = curl_exec($curl);
return $results;
}
I thought I would get the size of the remote file first then compare to the local file size. However, this doesn't seem to work. Not sure if its a function of the file being a .zip file but it always returns -1 or -11. I tried this function:
function remotefileSize($url)
{
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_NOBODY, 1);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 0);
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($curl, CURLOPT_MAXREDIRS, 3);
curl_exec($curl);
$filesize = curl_getinfo($curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
curl_close($curl);
return $filesize;
}
Did you see anything on your browser that shows Unknown time remaining or Unknown bytes remaining while downloading a file? It is because the browser couldn't retrieve the size and failed to calculate remaining time or size. This is what is happening with you. Your filesize retrieval code is correct.
Another reason could be: Sometime the server doesn't support the HEAD request(when you use CURLOPT_NOBODY).

How to solve cUrl corrupting file during download

I really, really need help as to how to solve this issue I'm having:
Using script:
<?php
$curl = curl_init();
$fp = fopen("somefile.zip", "w");
curl_setopt ($curl, CURLOPT_URL, "http://website.com/test.zip");
curl_setopt($curl, CURLOPT_FILE, $fp);
curl_setopt($curl, CURLOPT_BINARYTRANSFER, 1);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_exec ($curl);
curl_close ($curl);
I have asked before, and no-one seems to have a solution as to how I solve this... If someone can even tell me why it's happening ie. is it file size, binary transfer etc. I can work with that!
The file ZIP file downloads and creates somefile.zip but the XML file within is partially corrupt.
Sample:
K#Teº22)dVTð¼ÜvØ
rÏ*HIê±dE*¬òPÜÊâR}ÝbJÉÂX:Î#z|Eª2Ér tk­2UÄOK¼É,·,­Ûs¦ê1Z°VÝk6Ù«ËGÝw©5Æ]ÛQcq¥¼½ØïÒÐ]êÈy¨ð¶Çùûü]ÛßþW¤ùâÝÀw|~§ïúÁ¸ÛHBq®*YtrÛÕiî$ /ñ¥n?è¶;_ò
É¡ä ç&ýOr óß)yÿ¤$+`~TÙAófHU ¢SÝvW¶¦xA5Å׶Ãrå<8^ÐË4w­ qz Ø«<Ñ"*ººÝ?èO^;ÃQûÉOÏÀ¾?ìw|Õ±¥©3w©Ýr£ ÃÊÀ ¿^Á^UÛLß_ôÜÎh4îÖWcíF^8¾ö÷ؼ¾¿`âX3Ûú^{ À<.Æ¡(±1f¢.¸®k/ìÝeÓçê'PAnÓõ¸K`TeQ÷b|'¥Ñ)1ÓãnsÞèàÎZ|ê*+kuw×cªëÇ:§$¤ã¸Î1ü±Úh6ÕÀQ¦©D4Âp4b{Èo¾
,4"R
Can you set CURLOPT_HEADER to 0 and try again?
Edit:
Or try this:
$url = 'http://website.com/test.zip';
$path = 'somefile.zip';
$ch = curl_init($url);
if($ch === false)
{
die('Failed to create curl handle');
}
$fp = fopen($path, 'w');
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_FILE, $fp);
$data = curl_exec($ch);
curl_close($ch);
fclose($fp);

Check if a remote file is a valid mp3

Could you tell me a good way to check if a remote(http) file is a valid mp3, WITHOUT downloading the whole file?
Do not trust anything that comes from the server. MIME type may be fake. Even the filename. Just assume that you are expecting a MP3 file. Store the correct extension and verify it.
Well at least the header along with the correct extension to the filename. At worst they get a horrible noise in their ears and you get a complaint.
You can try
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, "http://...music.mp3");
curl_setopt($curl, CURLOPT_HEADER, true);
curl_setopt($curl, CURLOPT_FILETIME, true);
curl_setopt($curl, CURLOPT_NOBODY, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$header = curl_exec($curl);
$info = curl_getinfo($curl, CURLINFO_CONTENT_TYPE);
curl_close($curl);
$mp3_mimes = array('audio/mpeg','application/mp3','audio/mpeg3','audio/x-mpeg-3');
if (in_array($info, $mp3_mimes)) {
// Somthign cooking
}
Another suggestion is download the file and validated by reading header information
$curl = curl_init();
$localfile = "local.temp";
unlink($localfile);
$file = fopen($localfile, 'w+');
curl_setopt($curl, CURLOPT_URL, "http://robtowns.com/music/blind_willie.mp3"); // nput
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_FILE, $file);
curl_exec($curl);
curl_close($curl);
fclose($file);
$mp3 = new mp3();
if ($info = $mp3->get_mp3($localfile, true, false)) {
var_dump($info);
} else {
unlink($localfile);
// bad File
}
MP3Class
Check the filesize and if its >1mb validate... Not the answer but the best for now...

Moving a file on an ftp site using php cURL

I have a need to rename a file after download using php cURL.
Here's what I have:
$localFile = fopen($fileName, 'w');
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_FILE, $localFile);
curl_setopt($curl, CURLOPT_USERPWD, "$ftpUsername:$ftpPassword");
curl_setopt($curl, CURLOPT_POSTQUOTE, array("RNFR $remoteFile", "RNTO $remoteFile.downloaded"));
curl_exec($curl) === false) {
throw new Exception(curl_error($curl));
}
If I remove the CURLOPT_POSTQUOTE part, the file downloads fine. I've also tried a couple different combinations of the postquote array:
curl_setopt($curl, CURLOPT_POSTQUOTE, array("RNFR $remoteFile RNTO $remoteFile.downloaded"));
curl_setopt($curl, CURLOPT_POSTQUOTE, array("-RNFR $remoteFile", "-RNTO $remoteFile.downloaded"));
curl_setopt($curl, CURLOPT_POSTQUOTE, array("-RNFR $remoteFile -RNTO $remoteFile.downloaded"));
curl_setopt($curl, CURLOPT_POSTQUOTE, array("rename $remoteFile $remoteFile.downloaded"));
The error I've been getting look like:
ERROR : QUOT string not accepted: -RNFR $remoteFile -RNTO $remoteFile.downloaded
In case anybody finds themselves here in the future.
My issue was that $remoteFile resolved to something like /remote_folder/remote_file.txt, but since my ftp connection already included the folder, something like ftp://www.example.com/remote_folder/remote_file.txt, I wasn't supposed to specify the folder in RNFR and RNTO.

Categories