I check the MD5sum of an .iso file before uploading to my website using Filezilla in active mode. The MD5sum is calculated on the website and matches what was calculated before upload. If I download the same file from the website using the following code, the MD5sum is different.
<?php
$php_scripts = '../../php/';
require $php_scripts . 'PDO_Connection_Select.php';
require $php_scripts . 'GetUserIpAddr.php';
function mydloader($l_filename=NULL)
{
$ip = GetUserIpAddr();
if (!$pdo = PDOConnect("foxclone"))
{
echo "Failed to connect to database" ;
exit;
}
if( isset( $l_filename ) ) {
// var_dump($ip,$l_filename);
$stmt = $pdo->prepare("INSERT INTO download (IP_ADDRESS, FILENAME) VALUES (?, ?)");
$stmt->execute([$ip, $l_filename]) ;
header('Content-Type: octet-stream');
header("Content-Disposition: attachment; filename={$l_filename}");
header('Pragma: no-cache');
header('Expires: 0');
readfile($l_filename);
echo "Made it here";
}
else {
echo "isset failed";
}
}
mydloader($_GET["f"]);
Why is this happening?
EDIT: I found the difference by opening both the original iso and the downloaded iso in atom editor. The downloaded version has the following added to the start of the file:
herestring(14) “xx.xxx.xxx.xxx” <— my ip
string(17) “foxclone35-02.iso”
herestring(14) “xx.xxx.xxx.xxx”
string(17) “foxclone35-02.iso”
Solved by removing some debugging code that was being added to the downloaded file.
Related
I would like to export data from sql to xls (better would be xlsx) without a third party library.
This is my code:
// DB Connection included by a config.php file
$sql = $db->prepare( "SELECT * FROM myTable" );
$sql->execute();
$result = $sql->fetchAll(PDO::FETCH_ASSOC);
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment; filename=Export.csv');
ExportFile($result);
function ExportFile($records) {
$heading = false;
foreach($records as $row) {
if(!$heading) {
echo implode("\t", array_keys($row)) . "\n";
$heading = true;
}
echo implode("\t", array_values($row)) . "\n";
}
}
exit;
This works.
But if I change the header to Export.xls it works but with an "error message" of excel.
The file format and the file extension of 'Export.xls' do not match. The file may be corrupted or unsafe. You should not open it if you do not trust its source. Do you still want to open the file?
and if I changed it to Export.xlsx:
The file 'Export.xlsx' cannot be opened by Excel because the file format or extension is invalid. Check if the file is corrupted and if the file extension matches the file format.
How can I solve it, to realize it with xls without error message (better with xlsx)?
I am having trouble debugging a php script that I use for downloading .pdf files.
The script works fine for one user but doesn't work for another giving blank page.
What I am pretty sure is:
the part responsible for downloading works fine for both users
The query works fine and gets correct data from the serwer
All of the files are in the same directory (and as I already wrote it works perfectly for the first user)
Please give me a hint on where the bug might be or how to find it.
Thanks so much in advance.
Here's my code:
.htacces :
<Directory /faktury/>
Order deny,allow
Deny from all
</Directory>
html :
<form action="downloadfv.php" method="post">
<input type="text" name="fv" id="fv" value="$rowvariable" hidden />
<button type="submit"">Download</button>
</form>
downloadfv.php :
<?php
session_start();
if(!isset($_SESSION['zalogowany']))
{
header('Location: logowanie.php');
exit();
}
require_once "connect.php";
mysqli_report(MYSQLI_REPORT_STRICT);
$polaczenie = new mysqli($host, $db_user, $db_password, $db_name);
mysqli_query($polaczenie, "SET CHARSET utf8");
mysqli_query($polaczenie, "SET NAMES `utf8` COLLATE `utf8_polish_ci`");
if (mysqli_connect_errno())
{
echo "Could not connect to server" . mysqli_connect_error();
}
$idogloszenia = htmlspecialchars($_POST['fv'], ENT_QUOTES,'UTF-8');
$sql = "SELECT * FROM faktury WHERE user='{$_SESSION['user']}' AND idogloszenia = '$idogloszenia' ORDER BY idogloszenia DESC LIMIT 1";
$result = $polaczenie->query($sql);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
$file = "./faktury/".$row["nazwapdf"].".pdf";
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
}
}
} else {
echo " <div class='itemsname'>
<span style='padding:10px; font-size:90%'><u>No invoice available.</u></span>
</div>";
}
$polaczenie->close();
?>
The script works fine. The bug was inside my test database. It ocurred that I've had duplicated rows with similar data in them and the query selected wrong rows.
So the script can be used although as #mehdi pointed out it is not secure.
Thank you #chris85 for your hints.
I was wondering if anyone know why the code after the header(Content-disposition: ...) will not run? It writes and downloads the file, but it will not run the unlink() line...
This code is within a few other if statements originally.
Here is the code:
$form1Array = array($_POST["namn"], $_POST["stad"]);
$form1String = serialize($form1Array);
$form1Fil = $_POST["namn"].".txt";
$midMappe = "midlertidig\\";
$fo_form1Fil = fopen($midMappe.$form1Fil, "w");
//
if (fwrite($fo_form1Fil, $form1String)) {
ignore_user_abort(true);
//
header("Content-type: text/plain");
header("Content-disposition: attachment; filename=".$form1Fil);
//
unlink($midMappe.$form1Fil);
} else {
echo "Could not save the file for download.";
}
Thank you. :)
The code will be correctly executed and as someone pointed out in the comments, it is very likely that the problem is in the unlink() function. I recommend you to do a quick debug and see what unlink() returns. More in particular, see if it return false (it will if it fails to unlink the file).
Here an example of what i mean
I figured it out with the help of 'CBroe', thank you.
I also added a connection_abort() line which I found out about here.
Here is the updated code:
$form1Array = array($_POST["namn"], $_POST["stad"]);
$form1String = serialize($form1Array);
$form1Fil = $_POST["namn"].".txt";
$midMappe = "midlertidig\\";
$fo_form1Fil = fopen($midMappe.$form1Fil, "w");
//
if (fwrite($fo_form1Fil, $form1String)) {
fclose($fo_form1Fil); // ** Here is the updated/added line 1 **
//
ignore_user_abort(true);
//
header("Content-type: text/plain");
header("Content-disposition: attachment; filename=".$form1Fil);
//
if (connection_abort()) { // ** Here is the updated/added line 2 **
unlink($midMappe.$form1Fil);
} else {
unlink($midMappe.$form1Fil);
}
} else {
echo "Could not save the file for download.";
}
When I generate an export to a CSV file, I have a tab that is inserted at the beginning.
I don't understand why.
Here is my code :
public function hookExportAll($params){
header('Content-Type: application/csv');
header('Content-Disposition: inline; filename="clients.csv"');
header('Cache-Control: private, max-age=0, must-revalidate');
//mysql request
$sql = "..."
$clientlist = Db::getInstance()->ExecuteS($sql);
//separator recovered the post of the form
$filter['sep']=Tools::getValue('sep');
//; or , or \t
$entete = array('email','nom','prenom','anniversaire','newsletter','adresse','pays','téléphone');
echo $this->getcsvline($entete, $sep);
foreach($clientlist AS $client){
echo $this->getcsvline($client, $sep);
}
}
private function getcsvline($list, $sep="\t"){
return implode($sep, $list)."\r\n";
}
A little help?
Finally, Ivar Bonsaksen must be right. A tab must have been generated in the CMS Prestashop before a . With no time to dwell on this case, I consider this issue as resolved.
Thank you all for your support, see you soon =)
Using PHP, I'm trying to download a blob file that has already been uploaded to an Oracle 10g database. I've seen and imitated numerous examples I've found. When I access the page a File Download dialog appears allowing me to Open or Save. If I click Open, media player comes up as it should but never retrieves the file. If I choose Save, I always get an error message stating "Internet Explorer was not able to open this Internet site. The requested site is either unavailable or cannot be found. Please try again later."
Below is my code which is pretty straight forward and pretty much like the examples I've found.
<?php
header('Content-Disposition: attachment; filename='.$_GET['fileName']);
header('Content-length: '.$_GET['fileSize']);
header('Content-type: '.$_GET['mimeType']);
require_once("Include/Application.php");
$connection = oci_connect ($userID, $password, $TNS);
$phpCur = oci_new_cursor($connection);
$stmt = oci_parse($connection, "BEGIN MOR.DOWNLOAD_ATTACHMENT (:morID, :attachmentType, :phpCur); END;");
oci_bind_by_name($stmt, ":morID", $_GET['morID'], -1);
oci_bind_by_name($stmt, ":attachmentType", $_GET['attachmentType'], -1);
oci_bind_by_name($stmt, "phpCur", $phpCur, -1, OCI_B_CURSOR);
oci_execute($stmt);
oci_free_statement($stmt);
$output = '';
oci_execute($phpCur);
while( $row = oci_fetch_array($phpCur) )
$output .= $row['ATTACHMENT_BL'];
oci_free_statement($phpCur);
oci_close($connection);
echo $output;
exit;
?>
Use your db query and excecute first here is the data field is blob data:
$sql="SELECT FILE_NAME,data,length(data) as filesize FROM branch_data where id='$id'";
$r = $db->execute($sql);
$filename=$r->data[0]['FILE_NAME'];
$d=$r->data[0]['DATA'];
$filesize = $r->data[0]['FILESIZE'];
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.$filename.'"');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' .$filesize);
echo $d->load();
Add more error handling to your script. Any of the oci* function can fail and then subsequent steps will also fail. The documentation tells you what happens if a function fails and what the return value will be. E.g.
Return Values
Returns a connection identifier or FALSE on error.
If you set the Content-type header as late as possible, i.e. directly before the first output, you can send plain text or html that contains some sort of error message instead.
<?php
// error_reporting/ini_set: for testing purposes only.
error_reporting(E_ALL); ini_set('display_errors', 1);
require_once("Include/Application.php");
$connection = oci_connect ($userID, $password, $TNS);
if ( !$connection) {
die('database connection failed');
}
$phpCur = oci_new_cursor($connection);
if ( !$phpCur) {
die('creating cursor failed');
}
$stmt = oci_parse($connection, "BEGIN MOR.DOWNLOAD_ATTACHMENT (:morID, :attachmentType, :phpCur); END;");
if ( !$stmt) {
die('creating statement failed');
}
// and so on and on. Test the return values of each oci* function.
oci_close($connection);
header('Content-Disposition: attachment; filename='.$_GET['fileName']); // at least at basename() here
header('Content-length: '.$_GET['fileSize']); // strange...
header('Content-type: '.$_GET['mimeType']); // possible but still strange...
echo $output;
exit;