Laravel is adding/removing characters when using HTTPS - php

I have some zip files in my laravel project and they were downloaded by simple method
return response()->download($path);
now I added forcing https to the website with this:
if (!(isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on' ||
$_SERVER['HTTPS'] == 1) ||
isset($_SERVER['HTTP_X_FORWARDED_PROTO']) &&
$_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https'))
{
$redirect = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
header('HTTP/1.1 301 Moved Permanently');
header('Location: ' . $redirect);
exit();
}
and now I can't read the zip files, they seem corrupted.
I opened one of them in hex editor, and I see that there is an additional 0a0a character at the beginning.
I have no idea why this happens and what that means. And especially how to fix it, without editing the downloaded files.

It might be your headers try looking at this blog post and see if that is the fix to your issues.
https://perishablepress.com/http-headers-file-downloads/
<?php // HTTP Headers for ZIP File Downloads
// https://perishablepress.com/press/2010/11/17/http-headers-file-downloads/
// set example variables
$filename = "Inferno.zip";
$filepath = "/var/www/domain/httpdocs/download/path/";
// http headers for zip downloads
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"".$filename."\"");
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($filepath.$filename));
ob_end_flush();
#readfile($filepath.$filename);
?>

Related

URL Redirect Masking in PHP

I have to show a download link on my site linking it to a file hosted on another domain. I am using the following approach.
1) Pick up the actual URL from the database
$fileDownloadLink = "http://whatever.com/thefile.docx";
2) Encode the url and pass it as parameter to download.php
$shortUrl = base64_encode($fileDownloadLink);
Download Please
3) Download.php decodes the passed string and try reading the file.
<?php
$str = $_GET["session"];
$path = base64_decode($str);
$mm_type="application/octet-stream";
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Type: " . $mm_type);
header("Content-Length: " .(string)(filesize($path)) );
header('Content-Disposition: attachment; filename="'.basename($path).'"');
header("Content-Transfer-Encoding: binary\n");
readfile($path);
exit();
?>
But I am getting this error from download.php
Not Acceptable!
An appropriate representation of the requested resource could not be
found on this server. This error was generated by Mod_Security.
Please help.
You may just redirect in download.php;
$str = #$_GET["session"];
$path = base64_decode($shortUrl );
header("Location: $path");
exit();

PHP script that does not reveal real path generates download with ".php" extension

A file called "transfer.php" should offer a file for download. Instead of the download, it offers a file with a ".php" of the same file size as the original file. Did I get the header wrong?
Thanks!
<?php
session_start();
$path = $_SESSION['myvar'];
$mm_type = "application/octet-stream";
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Type: ".$mm_type);
header("Content-Length: ".(string)(filesize($path)) );
header("Content-Disposition: attachment; filename=".basename($path).'"');
header("Content-Transfer-Encoding: binary\n");
readfile($path); // outputs the content of the file
exit();
While I originally suggested removing the trailing unpaired quote in the disposition header ..
The file name should be enclosed in quotes (thanks Wrikken!). In the posted code the first quote is missing. Using ' for the first string makes the pairing (or lack of) more clear:
header('Content-Disposition: attachment; filename="' . basename($path) . '"');

Php: Keep same filename when downloading from server

I'm downloading a file through php script and everything work perfectly except one ugly truth. The downloaded file keep the same url and with original name appended. How do I maintain the same filename when file downloaded?
http://bachday.com/index.php?page=custom&file=mmailer/download.php?mfile=sample.docx
if (isset($_GET['mfile'])) {
$file = $_SERVER['DOCUMENT_ROOT'].'/oc-content/plugins/mmailer/pfile/'.$_GET['mfile'];
if (file_exists($file) && is_readable($file) && preg_match('/\.docx$/',$file)) {
header('Content-Type: application/docx');
header("Content-Disposition: attachment; filename=\"$file\"");
readfile($file);
/*
header("Expires: 0");
header("Cache-Control: no-cache, must-revalidate");
header("Pragma: no-cache");
echo (readfile($file));*/
}
else
{
header("HTTP/1.0 404 Not Found");
echo "Error 404: File Not Found: $file";
}
header('Content-Disposition: attachment; filename="name_of_file_here"') would have done the trick. You are passing the full path of the file there as header("Content-Disposition: attachment; filename=\"$file\""); since your $file contains full path. Instead just send the name of the file.
header('Content-Disposition: attachment; filename='.basename($file));
This line can perhaps solve the issue.
if (isset($_GET['mfile'])) {
$file = $_SERVER['DOCUMENT_ROOT'].'/oc-content/plugins/mmailer/pfile/'.$_GET['mfile'];
if (file_exists($file) && is_readable($file) && preg_match('/\.docx$/',$file)) {
header('Content-Type: application/docx');
header("Content-Disposition: attachment; filename=\"".basename($file)."\"");//use basename to extract filename from full file path
readfile($file);
/*
header("Expires: 0");
header("Cache-Control: no-cache, must-revalidate");
header("Pragma: no-cache");
echo (readfile($file));*/
}
else
{
header("HTTP/1.0 404 Not Found");
echo "Error 404: File Not Found:
$file";
}

In php Instead of downloading csv file it gets open in the browser

I'm trying to download a CSV file through the browser. The script is partially working, because so far I managed to display the CSV on screen, but the download is not starting.
Here is what i tried so far:
if(isset($currency)) {
header("Content-Type: application/csv");
header("Content-Disposition: attachment;Filename=Pricelogs.csv");
ob_clean();
$filename = "/tmp/".uniqid().".csv";
exportCSVFile($filename, $currency, $country, $provider);
readfile($filename);
//unlink("'".$filename."'");
} else {
echo "ERR_USERNAME_PASSWORD";
exit();
}
I had already read all questions of this type from FAQ & also tried but it gets open on browser only,instead of downloading.
I had also used header with single quotes.
I also tried header("Content-Type: text/csv");
Also:
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false); // required for certain browsers
header("Content-Type: application/force-download");
header("Content-Disposition: attachment; filename=\"".$filename."\";" );
header("Content-Transfer-Encoding: binary");
PUT your CSV file URL, it will display in browser in place of force browser to download. You can open it in iframe in your site.
http://docs.google.com/viewer?embedded=true&url=www.yoursite.com/filename.csv
I usually just do:
header('Content-type: text/csv');
header("Content-Disposition: attachment; filename=my_csv_filename.csv");
// print CSV lines here
exit();
I can tell you this combination is working for me:
$bom = chr(0xEF) . chr(0xBB) . chr(0xBF);
header("Content-type: application/csv; charset=UTF-8");
header("Content-Disposition: attachment; filename=$filename.csv");
header("Pragma: no-cache");
header("Expires: 0");
print $bom . $data;
exit;
If I were you, I would first test this plainly (outside of all your buffering), first see that you manage to make this work, and only then test it in your specific set up.
You might try this.
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false);
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"$filename.csv\";" );
print $content;
For large files you need to get your output buffer started
add : ob_start(); at the start
ob_clean(); at the end of you file

Download gzipped file through CloudFlare

I have a PHP file protector script:
.htaccess
RewriteEngine on
RewriteRule ^(.*).(zip|tgz)$ ../wp-file-protector.php?file=$1.$2 [QSA]
wp-file-protector.php
<?php
global $wpdb;
/** Make sure that the WordPress bootstrap has run before continuing. */
require( dirname(__FILE__) . '/wp-load.php' );
$current_user = wp_get_current_user();
if ($current_user->ID > 0){
$order = $_GET['order'];
$items = new_get_order_by_id_and_user($order, $current_user->ID);
if($items != false){
$file_enabled = true;
//Some authentication
$filepath = dirname(__FILE__).'/../downloads/'.$_GET['file'];
if($file_enabled && file_exists($filepath)){
$filename = basename($filepath);
$extension = end(explode('.', $filename));
ob_clean();
// http headers for zip downloads
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public");
header("Content-Description: File Transfer");
if($extension == 'tgz'){
header("Content-Type: application/gzip");
}else{
header("Content-type: application/octet-stream");
}
header("Content-Disposition: attachment; filename=\"".$filename."\"");
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($filepath));
ob_end_flush();
#readfile($filepath);
}
}
}
I works fine with zipped and other files. The problem appears with gzipped files. I got unexpected results (also different results for Firefox download and open action).
I think I need some good header for the gzipped files. What should I use?
Also good to know that the request is running through the Cloudflare service, so maybe I should send out some header, which tells cloudflare server to not to gzip it.
I'm stuck :(
Update #1
header("Content-type: application/x-gzip");
This also doesn't work. When I choose save in firefox, it tells when opening that corrupted. When I choose open, I got a file without extension, but it seems tar as I can go deeper into the dir.

Categories