Hi I want user to be able to download PDF file from my server (Windows) configured with nginx PHP. This is my nginx.conf (server block)
http {
include
Ok - there's a couple of issues here:
1) Puting root inside of a location is a BAD IDEA according to the nginx developers.
2) The internal URL used for telling Nginx that this is an internal redirect shouldn't be exposed to users.
3) I can't see where your download.php file is being served from, so I changed your root location block to use try_files so a request to /download.php would be served by that file rather than index.php.
Your project should be laid out as:
project\
html - this is the root of your website
protected - this directory is not accessible directly
And your Nginx conf should look like:
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
root /path/to/project/html;
location / {
try_files $uri /index.php?$args;
}
location /protected_files {
internal;
alias /path/to/project/protected;
}
}
}
It's a good idea not to re-use the same names to mean different things as it's quite confusing. I've changed them so that now protected
just refers to the actual physical directory that holds the files you want to serve. protected_files
is just a string that allows Nginx to match the request from the x-accel header.
The only thing that needs changing in your PHP code is to use the correct string to allow Nginx to pickup the internal location:
$aliasedFile = '/download/real-pdf-file.pdf'; //this is the nginx alias of the file path
$realFile = '/path/to/project/protected/real-pdf-file.pdf'; //this is the physical file path
$filename = 'user-pdf-file.pdf'; //this is the file name user will get
header('Cache-Control: public, must-revalidate');
header('Pragma: no-cache');
header('Content-Type: application\pdf');
header('Content-Length: ' .(string)(filesize($realFile)) );
header('Content-Disposition: attachment; filename='.$filename.'');
header('Content-Transfer-Encoding: binary');
header('X-Accel-Redirect: '. $aliasedFile);
exit(0);
Based from recommendation and solution from Danack and some clarification from Carsten, I found that in Windows Serve, we need to set the full path in the alias like this:
location /protected_files {
internal;
alias C:/absolute/path/to/project/protected/;
}
Please note that the extra forward slash is needed (in my case, Windows 7 Pro on development, Windows Server 2008 for deployment). The only issue is now I need to test concurrent downloads to see if server resources is hogging.
I'm new with nginx, since it seem really faster that I switch from Apache. Thanks guy for the enlightenment! I'am glad to be part of Stackoverflow community :)