Use Nginx's X-Sendfile mechanism to improve PHP File Download Performance

Source: Internet
Author: User
Tags sendfile

Most users need to download files from the website. If the files can be publicly obtained through a fixed link, we only need to store the files in the webroot directory. However, in most cases, permission control is required, such as downloading PDF bills, and downloading files on an online storage. At this time, we usually implement it through script code, which will undoubtedly increase the burden on the server.


For example, the following code:

<? Php
// User identity authentication, jump if verification fails
Authenticate ();
// Obtain the object to be downloaded. If the object does not exist
$ File = determine_file ();
// Read the file content
$ Content = file_get_contents ($ file );
// Send an appropriate HTTP Header
Header ("Content-type: application/octet-stream ");
Header ('content-Disposition: attachment; filename = "'. basename ($ file ).'"');
Header ("Content-Length:". filesize ($ file ));
Echo $ content; // or readfile ($ file );
?> 1. What are the problems with this?
This means that our program needs to cyclically read the file content from the disk through a fixed buffer to the memory, and then send it to the front-end web server before reaching the user. When the files to be downloaded are large, this method will consume a lot of memory, and even cause the php process to time out or crash. The Cache is also a headache, not to mention the reconnection interruption.

An ideal solution is to perform permission check and other logic judgment by the php program. After everything passes, enable the front-end web server to directly send files to users-a front-end such as Nginx is better at processing static files. In this way, the php script will not be blocked by I/O.

2. What is X-Sendfile?
X-Sendfile is a mechanism that transfers a File Download request from a backend application to a front-end web server for processing. It can eliminate the pressure on backend programs to read files and process and send files, this significantly improves server efficiency, especially when large file downloads are processed.

X-Sendfile is implemented through a specific HTTP header: specify a file address in the X-Sendfile header to notify the front-end web server. When the web server detects the header sent by the backend, it ignores other backend outputs and uses its own components (including cache headers and breakpoint reconnection optimization) sends the file to the user.

However, before using X-Sendfile, we must understand that this is not a standard feature and is disabled by most web servers by default. Different web servers have different implementations, including specifying different X-Sendfile header formats. If the configuration is incorrect, the user may download a 0-byte file.

Using X-Sendfile will allow downloading files in non-web directories (for example,/root/), even if the files are not accessible under. htaccess protection, they will be downloaded.

Different web servers implement different HTTP header sendfile headers.
X-Sendfile Apache, Lighttpd v1.5, Cherokee
X-LIGHTTPD-send-file Lighttpd v1.4
X-Accel-Redirect Nginx, Cherokee

The disadvantage of using X-SendFile is that you lose control of the file transfer mechanism. For example, if you want to perform some operations after the file is downloaded, for example, you can only download the file once, this X-Sendfile cannot be done, because the php script in the background does not know whether the download is successful.

3. How to use it?
For Apache, see the mod_xsendfile module. The following describes how to use Nginx.

Nginx supports this feature by default and does not need to load additional modules. The only difference is that the HTTP header to be sent is X-Accel-Redirect. In addition, make the following settings in the configuration file:

Location/protected /{
Internal;
Root/some/path;
} Internal indicates that this path can only be accessed within Nginx, but cannot be accessed directly using a browser to prevent unauthorized downloads.

So PHP sends X-Accel-Redirect to Nginx:

<? Php
$ FilePath = '/protected/iso. img ';
Header ('content-type: application/octet-stream ');
Header ('content-Disposition: attachment; filename = "'. basename ($ file ).'"');
// Send an Xsendfile File
Header ('x-Accel-Redirect: '. $ filePath );
?> In this way, the user downloads the file under the path/some/path/protected/iso. img.

If you want to send the/some/path/iso. img file, the Nginx configuration should be

Location/protected /{
Internal;
Alias/some/path/; # note the last slash


Author: lovelucy

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.