H3XED

How to use X-Sendfile with PHP and Apache

Apr 10, 2015   Programming   Nick Vogt   Comments
Please note that this post is over a year old and may contain outdated information.
X-Sendfile allows you to use PHP to instruct the server to send a file to a user, without having to load that file into PHP. It solves the problem of securely managing file access, without the excessive memory requirement of loading the file and reading it from PHP.

With X-Sendfile, you can now store files outside of the document root (inaccessible to visitors), and only deliver them to users after being properly validated in PHP. The server (Apache, Nginx) handles the file as it normally would, so there is no extra memory usage.


Setting Up X-Sendfile


This is an example of setting up X-Sendfile in Apache. Nginx has similar functionality but it won't be covered in this post.

You must have the mod_xsendfile Apache module, which you can get here. Download the one appropriate for your operating system and Apache version, and put it into your Apache modules folder.

In your httpd.conf file, add an X-Sendfile section that looks like this:

#
# X-Sendfile
#
LoadModule xsendfile_module modules/mod_xsendfile.so
XSendFile On
XSendFilePath "C:/Development/Web Root/"

You'll want to change the XSendFilePath to your DocumentRoot.


Using X-Sendfile


Using X-Sendfile from within PHP is very easy. Just set an X-Sendfile header with the absolute file path:

header('X-Sendfile: ' . $absoluteFilePath);
Using PHP realpath and the Magic Constant __DIR__ can help you get the full absolute path if you need help.

It's also a good idea to add some additional headers that describe the type of file being delivered and how the user's browser should handle it.

// The Content-Disposition header allows you to tell the browser if
// it should download the file or display it. Use "inline" instead of
// "attachment" if you want it to display in the browser. You can
// also set the filename the browser should use.
header('Content-Disposition: attachment; filename="somefile.jpg"');

// The Content-Type header tells the browser what type of file it is.
header('Content-Type: image/jpeg');
Share This Post
Twitter

Comments (0)

Share This Post
Twitter
H3XED © Nick Vogt   RSS   Policies   Twitter