Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>You have a few options here, depending on your use-case.</p> <ol> <li><p>Use PHP to serve the file. Basically, either intercept all attempts to read the file by PHP (using a mod_rewrite rule), or link directly to PHP and put the file(s) below the document root. Then use something like <a href="http://us.php.net/manual/en/function.fpassthru.php"><code>fpassthru</code></a> to send the file to the browser. Note that you <strong>must</strong> properly set the content-type headers. Also note that this will eat up a lot of server resources since the server needs to read the entire file in PHP and send it, so it's easy, but not light.</p> <pre><code>$f = fopen('file.doc', 'r'); if (!$f) { //Tell User Can't Open File! } header('Content-Type: ...'); header('Content-Length: '.filesize('file.doc')); fpassthru($f); die(); </code></pre> <p>The main benefit to doing it this way is that it's easy and portable (will work on all servers). But you're trading off valuable server resources (since while PHP is serving the file, it can't be serving another page) for that benefit...</p></li> <li><p>Use the web-server to send the file using something like <a href="http://blog.lighttpd.net/articles/2006/07/02/x-sendfile"><code>X-SendFile</code></a> (Lighttpd), <a href="https://tn123.org/mod_xsendfile/"><code>X-SendFile</code></a> (Apache2/2.2) or <a href="http://wiki.nginx.org/XSendfile"><code>X-Accel-Redirect</code></a> (NginX). So you'd redirect all requests to the file to PHP (either manually or rewrite). In PHP you'd do your authentication. You'd send the Content-Type headers, and then send a header like <code>X-SendFile: /foo/file.doc</code>. The server will actually send the file, so you don't have to (it's <strong>far</strong> more efficient than sending from PHP natively).</p> <pre><code>header('Content-Type: ...'); header('X-SendFile: /foo/file.doc'); die(); </code></pre> <p>The main benefit here is that you don't need to serve the file from PHP. You can still do all of your authentication and logging that you'd like, but free up PHP as soon as you start transferring the file.</p></li> <li><p>Use something like <a href="http://redmine.lighttpd.net/wiki/1/Docs%3aModSecDownload"><code>mod_secdownload</code></a> (lighttpd) or <a href="http://code.google.com/p/mod-auth-token/"><code>mod_auth_token</code></a> (Apache). Basically, you create a token in PHP when you generate the link to the file. This token is a combination of a MD5 of a secret password combined with the current timestamp. The benefit here, is the URL is only valid for how long you specify in the configuration (60 seconds by default). So that means that the link you give out will only be active for 60 seconds, and then any further attempts to see the content will generate a 400 series error (I'm not positive which off the top of my head).</p> <pre><code>$filename = '/file.doc'; $secret = 'your-configured-secret-string'; $time = dechex(time()); $token = md5($secret . $filename . $time); $url = "/downloads/$token/$time$filename"; echo "&lt;a href="$url"&gt;Click Here To Download&lt;/a&gt;"; </code></pre> <p>The main benefit to doing it this way is that there is very little overhead associated with the implementation. But you have to be comfortable with having URLs being valid for a set time only (60 seconds by default)...</p></li> <li><p>Push it off onto a CDN to handle. This is like option #3 (the one above), but uses a CDN to handle the file serving instead of your local server. Some CDNs such as <a href="http://www.edgecast.com/">EdgeCast</a> provide a similar functionality where you set a token which expires after a set amount of time. This case will work nicely if you have a <strong>lot</strong> of traffic and can justify the expense of a CDN. (Note: no affiliation with the linked CDN, only linked because I know they offer the functionality).</p></li> </ol> <p>As far as how I'd personally do it, I've done all of the above. It really matters what your use-case is. If you're building a system that's going to be installed on shared hosts or multiple different servers which you don't control, stick to the first option. If you have full control and need to save server resources, do one of the other two.</p> <p><em>Note:</em> there are other options than these three. These are just the easiest to implement, and most of the other options are similar enough to these to fit into the category...</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload