J. Grunder
J. Grunder

Reputation: 143

Laravel 5.7 Storage download CSV file adds a .txt extension

In Laravel 5.7 I'm using a simple route to allow a user to download a local stored csv file.

Route::get('download/{file}', function($file) {
            return Storage::disk('s3')->download($file, $file, ['Content-Type: text/csv"']);
           })->name('download');

And in my Blade template :

<a href="{{ Route('download', ['file' => 'import.csv']) }}" class="btn btn-primary btn-sm btn-line btn-rect" data-original-title="" title=""> <i class="fa fa-download" aria-hidden="true"></i>

When user clicks on the link, Laravel is finding import.csv file into s3 disk and allow user to download the file but it adds a .txt extension. So the user is downloading import.csv.txt and this file corresponds to import.csv data.

How can I prevent Laravel to add a .txt extension to the CSV file ? I tried return Storage::disk('s3')->download($file, $file); and return Storage::disk('s3')->download($file); and same result each time.

Running environment: This is a production server running Apache2 with PHP 7.1 under Debian 9.

EDIT1: I've made the same test on a fresh Laravel 5.7 install, same issue :

Route::get('/', function () {
return Storage::disk('public')->download('import.csv', 'import.csv', ['Content-Type: text/csv"','Content-disposition: attachment;filename=MyVerySpecial.csv']);});

EDIT2: I've added a new test with a controller. Route :

Route::get('test', 'test@test');

Controller test :

public function test()
{
  return Storage::disk('public')->download('import.csv', 'import.csv', ['Content-Type: text/csv"','Content-disposition: attachment;filename=MyVerySpecial.csv']);
}

Exactly the same result

EDIT3: Tested with headers:

['Content-Type: application/octet-stream"','Content-disposition: attachment;filename="MyVerySpecial.csv"']

Same result

EDIT4: Looks to be a server configuration problem as I have this issue with Firefox (last developer edition) and not with IE

Thank you for your help.

EDIT5: I think there is something wrong with Laravel because if I'm creating a php file with:

<?php
$file = "../storage/app/public/import.csv";
header("Content-Description: File Transfer");
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=" . basename($file));
readfile ($file);
exit();    

This is working perfectly with Firefox. But if I use a route like

return Storage::disk('public')->download('import.csv', 'import.csv', ['Content-Description: File Transfer','Content-Type: application/octet-stream','Content-Disposition: attachment; filename=/home/webadmin/fresh/storage/app/public/import.csv']);

Well it does not work.

Question: has somebody else tried to reproduce same issue?

Upvotes: 1

Views: 3786

Answers (2)

J. Grunder
J. Grunder

Reputation: 143

The answer of this problem is format used for headers :

Route::get('/', function () {
    return Storage::disk('public')->download('import.csv', 'import.csv', ['Content-Description' =>  'File Transfer','Content-Type' => 'application/octet-stream','Content-Disposition' => 'attachment; filename=import.csv']);
});

This is a good way how to send headers to download files, tested on Firefox and IE and Chrome

Upvotes: 1

priMo-ex3m
priMo-ex3m

Reputation: 1092

You have to add all these headers :

header('Content-type: application/octet-stream');
header('Content-Length: ' . filesize($data));
header('Content-Disposition: attachment; filename="export.csv"');

Upvotes: 0

Related Questions