Make the download of large files with PHP (and lighty) very easy

Avatar von Björn Schotte

As you may know, our friend Jan Kneschke is the creator of lighttpd (called „lighty“), a superb OpenSource webserver (designed for speed and easyness) where we provide exclusively consulting and implementation services for.

Some days ago I stumbled upon an old entry of Jan in lighty’s life, called „X-Sendfile“. There he explains how to speed up the delivery of (large) files with lighttpd instead of PHP (YES, lighttpd is very fast – for one customer we created an ImageServer with pure lighty that replaced a 4-server-cluster with Apache and now has 1 server with lighttpd (which is boring around at low load). The box makes 180 Mio. requests per month).

It makes use of the X-Sendfile: (upon lighttpd V1.5) or X-LIGHTTPD-send-file: (prior to V1.5) header lines. In fact, your PHP script does only the following things – for example in a Media Asset Management System:

  • check ACL for the particular user if he has the right to download the file
  • search for the original filename in the database it had when the file was uploaded
  • set the appropriate headers (the file may have a crypting filename on the disk, i.e. not the original filename as it was uploaded for)
  • output file via readfile() and the like
  • set the X-LIGHTTPD-send-file: or X-Sendfile: header
  • exit your script – let lighttpd take care about delivering the file to the client and save your PHP FCGI Binary for the next real application request

As you see, lighty will handle the delivery of the file itself. In order to support the hand-over to lighttpd you need to activate support for X-sendfile in the configuration:

fastcgi.server = {
   ".php" => {
      "192.168.0.1" => {
          # ....
          "allow-x-send-file" => "enable"
      }
   }
}

Here’s a short example of a PHP script that lets lighttpd deliver the file:

<?php
/**
 * lighttpd's feature of X-Sendfile explained.
 * 
 * @author Björn Schotte <schotte@mayflower.de>
 */

// as this is an example, here's the static file. Usually, you may
// have something like /download.php?file_id=500 etc. This file here is 126 MB big
$file_on_harddisk = "/data/vhosts/bjoern/htdocs/acbd18db4cc2f85cedef654fccc4a4d8download.tar.gz";
$file_to_download = "download.tar.gz";

// try to fake a "ACL authentication". This is rather simple, so
// replace it with your own ACL routine
if ( !empty($_GET['authenticated']) && $_GET['authenticated'] == 1) {
        header( "Content-Disposition: attachment; filename=\"" . $file_to_download . '"' );
        Header( "X-LIGHTTPD-send-file: " . $file_on_harddisk);
} else {
    print "Sorry, you don't have permissions to download this file!<br />\n";
}

Happy lightning!

Avatar von Björn Schotte

Kommentare

11 Antworten zu „Make the download of large files with PHP (and lighty) very easy“

  1. wow, that’s a great feature! I’m working on a large-file-download project right now and I wish Apache had one like this, because we can’t just jump over to lighy at the moment …

  2. We just use Akamai for the really big downloads (more of a diskspace issue), as well as Zend Download Server for our regular binary downloads. Then again, I don’t see us running away from Apache any time soon unless there is really something seriously wrong with Apache any time soon, due to the legacy of the business setup.

  3. According to the latest Netcraft survey statistics from 1st of February, 2007, Jan Kneschke’s little baby lighttpd is showing a steady growth, with currently serving 702712 servers which is a tremendous growth compared to January 2007 (only 172819 serve

  4. We are operating heavy traffic website with huge media downloads processed by PHP (because of ACL on each file), which in turn uses our system resources at maximum and even happened that our webserver hangs up few times. If your solution will make our server capable of at least 2x times more requests without any additional costs at all, big THANK YOU!

  5. I wish I could get this to work consistantly. Sometimes I get the files at blazing speed, the next time I get a 500 internal error and an error log entry.
    (mod_fastcgi.c.2462) unexpected end-of-file (perhaps the fastcgi process died).
    I’ve been using Apache & php for years but I’m new to lighttpd. Any suggestions would be appreciated.

  6. It is worth mentioning that Apache also has mod_xsendfile module and nginx has X-Accel-Redirect.

    Personally, I am a fan of lighty and nginx :)

  7. Avatar von Ashwani Tiwari
    Ashwani Tiwari

    Hye….

    I just saw your code.
    can u explain it more for me.
    Thank you.

  8. Avatar von Fernando
    Fernando

    Hello,

    I’m using X-LIGHTTPD-send-file on my PHP Script. But before it, i’m changing a $_SESSION variable.

    Unfortunately, it is not working.

    Do you any idea of why it isn’t working?

  9. Very interesting information. Especially about „one customer with cluster of 4 servers“…

  10. hi, is possible to serve files hosted on other websites? (like readfile() does)

    for eg.

    header( „Content-Disposition: attachment; filename=\““ . $file_to_download . ‚“‚ );
    Header( „X-LIGHTTPD-send-file: http://otherwebsite.com/videos/funny.flv„);

    ? if not.. how i can do that?! (can i use mod_flv_streaming? how?)

    thank u guys

  11. What if we the file on a different server and we are using CURL to fetch the content of that file ?

    then the resume download option would become an issue, right ?

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert


Für das Handling unseres Newsletters nutzen wir den Dienst HubSpot. Mehr Informationen, insbesondere auch zu Deinem Widerrufsrecht, kannst Du jederzeit unserer Datenschutzerklärung entnehmen.