0

I have seen this method being used on about three sites now, including Facebook, Dropbox and Microsoft's Skydrive. It works like this. Let's say you want to look at the image without downloading, then you'd just do this.

https://fbcdn-sphotos-a.akamaihd.net/hphotos-ak-xxxx/xxx_xxxxxxxxxxxxxxx_xxxxxxxxx_o.jpg

But if I want to download it, I'd add ?dl=1

https://fbcdn-sphotos-a.akamaihd.net/hphotos-ak-xxxx/xxx_xxxxxxxxxxxxxxx_xxxxxxxxx_o.jpg?dl=1

Easy peasy right? Well, it's probably not easy on the server side, and this is where my problem is. I would know how to do this if that .jpg-file was a PHP script and the $_GET parameter pointed to the image and another parameter would specify whether the image were to be downloaded or not. But that's not the case.

So, what methods did I try? None. Because I honestly have no idea how this works, it's like magic to me. Maybe it's something that you do in .htaccess? That sounds reasonable to me, but after a while of googling I didn't find anything even close to what I'm asking for.

  • Found a working facebook URL, there is not much magic, see http://stackoverflow.com/a/12640682/367456 – hakre Sep 28 '12 at 13:12

3 Answers3

1

You have some options.

One option would be to use a PHP script instead of the .jpg file. So your URL would point to a PHP file and in the PHP file you would do something like this:

header('Content-Type: image/jpeg');

if ($_GET['dl'] == 1)
    header('Content-Disposition: attachment; filename="downloaded.jpg"');

$file = $_GET["file"];
// do some checking to make sure the user is allowed to get the file specified.
echo file_get_contents($file);

Another option would be to use mod_rewrite in your .htaccess file to check for ?dl=1 and if found, redirect to the PHP script that will download the file (the same way as above).

I'm sure there are more options, but those two are the only ones popping into my head right now.

Travesty3
  • 14,351
  • 6
  • 61
  • 98
  • By the way, you can also rename the script something like IMG_126.jpg.php and use .htaccess to remove the .php extension. –  Oct 01 '12 at 17:13
0

I would have redirected all of the images to a single PHP file that will handle them based on their URI parameters.

in the .htaccess I would put:

Options +FollowSymLinks +ExecCGI

<IfModule mod_rewrite.c>

RewriteEngine On
RewriteCond %{REQUEST_URI} \.(jpg|png|gif)$
RewriteRule (.*)  images.php [QSA]

</IfModule>

that will make all of the requests to files with the extensions of jpg, png and gif redirect to you images.php file.

in the images.php file I would search for the existence of ?dl=1 and by that decide how to serve the image:

$requestedImage = $_SERVER['REQUEST_URI']
if (strpos($requestedImage,'?dl=1') !== false) {
    // serve the image as attachment
}else{
    // just print it as usual
}
  • This is a fantastic answer, however, after being in touch with my ISP I found out that **Options +FollowSymLinks** isn't supported. Bummer, really. I have another server, so I'll try and see how it works there and get back to y'all peeps here. –  Sep 28 '12 at 20:58
  • Hmm... Although I didn't get an Internal Server Error, this is what I got when visiting the script: **Parse error: syntax error, unexpected T_IF in /home/a2901076/public_html/images.php on line 4** Which also means that nothing happens when I add ?dl=1 to an image either. –  Sep 28 '12 at 21:03
  • add the all mighty ; after $requestedImage = $_SERVER['REQUEST_URI'] (: I seemed to forgot to add it – Daniel Tsyganok Sep 28 '12 at 22:45
  • There's no PHP error now, but instead there's a blank page. Hmm, what am I missing? Thanks a bunch for the help though! –  Oct 01 '12 at 17:05
0

The display response headers on such a facebook URL:

HTTP/1.1 200 OK
Content-Type: image/jpeg
Content-Length: 5684
Last-Modified: Fri, 01 Jan 2010 00:00:00 GMT
X-Backend: hs675.ash3
X-BlockId: 157119
X-Object-Type: PHOTO_PROFILE
Access-Control-Allow-Origin: *
Cache-Control: max-age=1209600
Expires: Fri, 12 Oct 2012 13:07:08 GMT
Date: Fri, 28 Sep 2012 13:07:08 GMT
Connection: keep-alive

And the download response headers:

HTTP/1.1 200 OK
Content-Type: image/jpeg
Content-Length: 5684
Last-Modified: Fri, 01 Jan 2010 00:00:00 GMT
X-Backend: hs675.ash3
X-BlockId: 157119
X-Object-Type: PHOTO_PROFILE
Content-Disposition: attachment
Access-Control-Allow-Origin: *
Cache-Control: max-age=1209600
Expires: Fri, 12 Oct 2012 13:07:17 GMT
Date: Fri, 28 Sep 2012 13:07:17 GMT
Connection: keep-alive

See the Content-Disposition: attachment line which is a difference.

So as you're already serving the images from a PHP script, in case the download parameter is set, add:

header('Content-Disposition: attachment');

and you should be fine.

hakre
  • 193,403
  • 52
  • 435
  • 836
  • I'm not using a PHP script, that was exactly what I wanted to avoid. –  Sep 28 '12 at 16:12
  • you can do something similar with your webserver configuration, too. it's just one additional header-line, so easy to add. you find that documented inside your webservers manual. – hakre Sep 28 '12 at 16:14