Use nginx x-sendfile mechanism to improve PHP file download performance
Many times users need to download files from the site, if the file can be obtained through a fixed link publicly, then we just need to store the file in the directory under Webroot. But in most cases, we need to do permission control, such as downloading a PDF bill, or downloading files from a Web disk. At this point, we usually use scripting code to implement, and this will undoubtedly increase the burden on the server.
For example, the following code:
User authentication, if authentication fails to jump
Authenticate ();
Get the file that needs to be downloaded, if the file does not exist jump
$file = Determine_file ();
Read File contents
$content =file_get_contents ($file);
Send the 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);
?>, what's the problem with doing this?
This means that our program needs to loop the contents of the file from disk through a fixed buffer to the memory, then send it to the front-end Web server before it arrives at the user. This method consumes a lot of memory when the files that need to be downloaded are large, and even causes the PHP process to time out or crash. The Cache is also a headache, not to mention interrupting the re-connect situation.
An ideal solution should be, by the PHP program to check the logic of the permissions, and so on, after all, let the foreground Web server directly send the file to the user-like Nginx, such as the front desk is more adept at handling static files. This way the PHP script will not be blocked by I/O.
Second, what is X-sendfile?
X-sendfile is a mechanism for transferring file download requests from back-end applications to the front-end Web server, which eliminates the ability of the backend program to read both the file and the sending pressure, thereby significantly improving server efficiency, especially in cases where large file downloads are handled.
X-sendfile is implemented via a specific HTTP header: Specify the address of a file in the X-sendfile header to advertise the front-end Web server. When the Web server detects the header sent by the backend, it ignores the other output from the backend and sends the file to the user using its own components, including optimizations such as cache headers and breakpoint re-connection.
However, before using x-sendfile, we must understand that this is not a standard feature, and by default it is disabled by most Web servers. The implementation of different Web servers is not the same, including the provision of a different X-sendfile header format. If the configuration is inappropriate, the user may download to a 0-byte file.
Using X-sendfile will allow you to download files from non-web directories (such as/root/), even if the file is forbidden under. htaccess protection and is downloaded.
Different Web servers implement different HTTP headers Sendfile headers used by the Web server
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 do something after the file is downloaded, such as allowing the user to download the file only once, this x-sendfile is not possible because the PHP script in the background does not know whether the download was successful or not.
Third, how to use?
Please refer to the Mod_xsendfile module for Apache. Below I introduce the use of Nginx.
Nginx supports this feature by default and does not require additional modules to be loaded. Just to implement some differences, the HTTP headers that need to be sent are x-accel-redirect. In addition, the following settings need to be made in the configuration file
location/protected/{
Internal
Root/some/path;
}internal indicates that this path can only be accessed within Nginx, and cannot be accessed directly from the browser to prevent unauthorized downloads.
So PHP sends X-accel-redirect to Nginx:
$filePath = '/protected/iso.img ';
Header (' Content-type:application/octet-stream ');
Header (' content-disposition:attachment; Filename= '. basename ($file). '"');
Let xsendfile send files
Header (' X-accel-redirect: '. $filePath);
?> so that users will be downloaded to the/some/path/protected/iso.img file under this path.
If you want to send a/some/path/iso.img file, then the Nginx configuration should be
location/protected/{
Internal
alias/some/path/; # Note the last slash
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.