Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

download files with spaces in their name - restriction through htaccess

I stumbled upon strange way to protect files.

Basicly there is empty download.php file in protected folder and two files that cause file to be downloaded (from the same folder): .htpwd where password is stored and .htaccess:

RewriteEngine On
##RewriteBase /
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?example.com [NC]
RewriteRule \.(.*)$ - [NC,F,L]

RewriteCond %{QUERY_STRING} ^filename=(.*)$
RewriteRule ^download\.php$ %1
RewriteRule (.*) - [E=file:$1]
Header set Content-type "octet-stream"
Header set Content-disposition "attachment; filename=%{file}e" env=file

##AuthName "Restricted Access" 
##AuthType Basic
##AuthUserFile /local/home/example/example.com/downloads/.htpwd
##AuthGroupFile /dev/null 
##require valid-user

Example of download link:
http://www.example.com/downloads/download.php?filename=dog%20cat%20cow.zip

If filename is dog-cat-cow.zip - all works. Problem starts when filename is: "dog cat cow.zip" then file will be downloaded but its file name after download will be "dog" instead of "dog cat cow.zip". So problem is people get file without even extension and have no idea what to do with it.

How this can be solved considering i simply cannot rename those files and remove spaces? I'm not expert on how to read .htaccess and no phrase that I could think of to search gives any similar problem resolution. Any ideas?

like image 698
Greg Viv Avatar asked Aug 05 '15 14:08

Greg Viv


1 Answers

As mentioned in comments, maybe try:

RewriteEngine On
##RewriteBase /
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?example.com [NC]
RewriteRule \.(.*)$ - [NC,F,L]

RewriteCond %{QUERY_STRING} ^filename=(.*)$
RewriteRule ^download\.php$ %1
RewriteRule (.*) - [E=file:$1]
Header set Content-type "octet-stream"
Header set Content-disposition "attachment; filename='%{file}'" env=file

##AuthName "Restricted Access" 
##AuthType Basic
##AuthUserFile /local/home/example/example.com/downloads/.htpwd
##AuthGroupFile /dev/null 
##require valid-user

Alternately, why not set the Content Type and Disposition within your download.php file itself?

$fileStorageDirectory = '/the/folder/the/downloadable/files/are/in/';

// Check for Parameter
if( !isset( $_GET['filename'] ) || $_GET['filename']=='' ){
  header($_SERVER['SERVER_PROTOCOL'].' 404 Not Found', true, 404);
  die('No File Specified');
}

$fileName = trim( $_GET['filename'] );
$fileRequested = $fileStorageDirectory.$fileName;
// Check File Exists
if( !file_exists( $fileRequested ) ){
  header($_SERVER['SERVER_PROTOCOL'].' 404 Not Found', true, 404);
  die('File Not Found');
}
// Check File is Readable
if( !is_readable( $fileRequested ) ){
  header($_SERVER['SERVER_PROTOCOL'].' 404 Not Found', true, 404);
  die('File Not Accessible');
}
// Send the File
header( 'Content-Type: application/octet-stream' );
header( 'Content-Disposition: attachment; filename="'.fileName.'"' );
readfile( $fileRequested );
exit;
like image 174
Luke Stevenson Avatar answered Sep 30 '22 16:09

Luke Stevenson