Php: How to protect images for downloading [duplicate] - php

This question already has answers here:
Protect image download
(17 answers)
Closed 6 years ago.
In my site we are doing image protecting section. Can I protect images in my site from others without download.That is i want to protect my image from downloading by others.Is it possible using php code

you can do this by using force download in php.
$file_url = 'base path to file / file name';
header('Content-Type: application/octet-stream');
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"" . basename($file_url) . "\"");
readfile($file_url);
this code will download the file and block files folder using htaccess
<IfModule authz_core_module>
Require all denied
</IfModule>
<IfModule !authz_core_module>
Deny from all
</IfModule>

Related

Output 3gp audio/video in php

I have a problem that I can not solve.
I use RewriteEngine in my .htaccess to access some videos. I need to export them for use in android.
My .htaccess:
RewriteRule ([^/]*)\.amr$ api.php?cmd=getmp3&hash=$1 [L]
In api.php
$__GB->getSafemp3($_GET['hash']);
And feature code:
header('Content-Type: video/3gpp');
header('Content-Disposition: inline; filename=' . $fetch['new_name']);
header('Content-length: '.filesize($path));
header("Content-Transfer-Encoding: binary");
readfile($path);
With the URL directly works perfectly, but not RewriteRule
Edit:
I've fixed the problem, i changed the feature code for this:
header('Location: ' . $path.$fetch['new_name']); //$path.$fetch['new_name'] is the file directory, ex: /music/audio.3gp

Disguising .pdf extension using .htaccess avoiding cycling

I have a little bit stupid necessity to disguise links to PDF files as PHP files with the PDF filename as a parameter.
Something like:
Client requests xxxx.pdf file.
Server receives request but instead of returning xxxx.pdf goes to yyyy.php or whatever extension.
yyyy.php has an iframe in which the PDF file is loaded.
The thing is that I managed to do point 2. but when I try to do point 3. it either cycles or doesn't locate the file.
I was thinking of having a custom extension to "simulate" another file in order to not cycle but it's still cycling.
I have the following .htaccess:
AddType application/pdf .view
RewriteRule ^(.*)\.pdf$ yyyy.php?filename=$1 [L]
RewriteRule ^(.*)\.view$ $1.pdf [L]
The thing is that it cycles and I get nowhere.
I am not really good with .htaccess, so where am I doing this wrong?
You probably need to add something to prevent the referer for yyyy.php from getting rewritten back to the php file. Add this before your yyyy.php rule:
RewriteCond %{HTTP_REFERER} !yyyy\.php
Note that referers can be forged, so this is one way people will be able to bypass the yyyy.php file.
I found it easier to just redirect when I detect a .pdf extension.
So I basically did this:
.htaccess detects a PDF extension and redirects to a php file passing the filename without extension as a parameter.
The php file uses the filename and renders the PDF using header and readfile to avoid conflicts with .htaccess.
Something like that:
.htaccess
RewriteRule ^(.*)\.pdf$ /pdfreader/$1 [L,R=302,NC]
RewriteRule ^pdfreader/(.*)?$ pdfreader.php?file=$1 [L,NC]
pdfreader.php
$file = $_GET["file"].".pdf";
header('Content-type: application/pdf');
header('Content-Disposition: inline; filename="' . $file . '"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($file));
header('Accept-Ranges: bytes');
#readfile($file);

How to calculate time with a php force download script?

I have a rather simple force download script:
$thefile = $_GET['id'];
$file = 'http://www.mywebsite.com/test/'.$thefile;
header('Content-Disposition: attachment; filename='.$thefile);
header("Content-Type: application/force-download");
#readfile($file);
And it works nicely, except it does not show how much time is remaining ("could not calculate time").
I found someone with a similar problem here, by using this code:
# for URL paths that begin with "/foo/bar/"
SetEnvIf Request_URI ^/foo/bar/ no-gzip=1
# for files that end with ".py"
<FilesMatch \.py$>
SetEnv no-gzip 1
</FilesMatch>
But alas, I can not get that to work. My files are media files (avi, wmv, mp4 and so forth), so I assumed I would have to modify the code along these lines:
SetEnvIf Request_URI ^/test/ no-gzip=1
<FilesMatch "\.(avi|wmv|mp4|mpg|mpeg|m4v)$">
SetEnv no-gzip 1
</FilesMatch>
I have also changed the path to a simple test folder, but time is still not being displayed.
How to?
You should add content-length header, for your browser to know total file size.
header("Content-Length: " . filesize($file));
Take a look at this example.

PHP force browser downloading image, Facebook like

I am looking for a way to force the browser to download an image instead of just display it.
I already looked a lot (and deeply) and there seems to be no standard way to do it properly.
The way Facebook do it, it's with some PHP I guess they put a parameter at the end :
?dl=1
So it's certainly a PHP page behind with an url rewritting i guess
<a class="itemAnchor" role="menuitem" tabindex="-1" href="http://a5.sphotos.ak.fbcdn.net/hphotos-ak-ash4/327910_2733459209258_1040639162_2895571_6924037615_o.jpg?dl=1" rel="ignore"><span class="itemLabel fsm">Download</span></a>
So if you have any clue how they do it... My clue is that they probably do something in the headers of the PHP page
They simply force downloading using HTTP headers just like you do with any other file:
<?php
$file = 'C:\\test.jpg';
header('Cache-Control: public');
header('Content-Description: File Transfer');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Type: '.mime_content_type($file));
header('Content-Transfer-Encoding: binary');
header('Content-Length: '.filesize($file));
readfile($file);
?>
X-SendFile
For larger files or busy webservers, I would suggest the use of X-SendFile header instead of using readfile() function (note that you need mod_xsendfile installed in Apache).
header('X-Sendfile: '.$file);
//readfile($file);
.htccess
As you noticed, the Facebook URL points at a jpg file, rather than a PHP one.
You will need to have URL rewriting in a .htaccess file to do this trick.
Something like the following should work (note you will need to use the real URL, checking the contents of $_SERVER to do so).
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
You'll have to define the Content-Disposition variable in your header:
<?php
header("Content-Disposition: attachment; filename='downloaded.png'");
?>
You can achieve this by setting the appropriate headers before sending the file. Specifically you can set the Content-Type to whatever your content type is and Content-Disposition: attachment; filename=<yourfilename>.
There are some gotchas with IE; check this answer for more info.

X-SendFile on Apache2 (PHP) serving 0B file, no errors though

I installed mod_xsendfile and it seems to have been successful; xsendfile.load appears in /etc/apache2/mods-enabled, and I've found no errors when running my test script. However, every time I run it, I get served a 0B file.
Here's my test script:
$file = 'sample.mp4';
$path = '/var/storage/media/'.$file;
header('Content-Disposition: attachment; filename="' . basename($file) . '"');
header("Content-type: application/octet-stream");
header("X-Sendfile: $path");
Obviously I have a file stored in /var/storage/media/sample.mp4, it's only 25MB, and is served perfectly fine if I do it this way:
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($path));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($path));
ob_clean();
flush();
readfile($path);
exit;
I also have this in the .htaccess file of both /var/storage and /var/www (the files that has all this is stored in /var/www/files/index.php):
XSendFile on
XSendFileAllowAbove on
Like I said, I get no errors, and the PHP can certianly access the file, but I must be missing something with the x-sendfile configuration... that reminds me, I notice in mods-enabled just about every mod has a .load and .conf, but xsendfile only has .load, but so do a few others, so would that have anything to do with it?
Thanks.
I had the same problem and this solution worked for me:
After installing the module, you need to enable it and give an access path into the Apache configuration (httpd.conf for global configuration, or specific site vhosts for specific configuration) like these:
# enable xsendfile
XSendFile On
# enable sending files from parent dirs
XSendFilePath /var/www/
Of course you must replace /var/www/ by whatever folder you want xsendfile to have access to
Make sure you also turn on XSendFile in your Apache configuration if using Apache. If you don't do this, it will look like it works, but empty files will be served.
For example:
<Directory /var/www/>
Options Indexes FollowSymLinks MultiViews
XSendFile on
AllowOverride All
Order allow,deny
allow from all
</Directory>
I'm using it on Ubuntu 14.04 and Apache/2.4.7.
It's important to:
Setup on each host configuration:
<Directory /var/www/path/to/files>
XSendFile On
XSendFilePath /var/www/path/to/files
</Directory>
Add to .htaccess:
XSendFile on
While I was using only 1; it kept me downloading empty files.
After adding 2, worked nicely.
On Windows I had to use the following in order be able to serve files outside of doc roo.
Everything else was giving me 404
XSendFilePath C:/
Try making header("X-Sendfile: $path"); the first header() call in the file.
Also take a look at this. Seems like a similar issue and it may give you some ideas:
X-Sendfile Error

Categories