Hey Grace, Albert & Robert
It looks like your support for nginx_accel_redirect won't quite work as expected. There are two issues I've found so far.
#1) Your nginx_octopus_include.conf includes the following for private files
###
### deny direct access to private downloads
###
location ~* ^/sites/.*/private/ {
access_log off;
deny all;
}
This won't work with the X-Accel-Redirect header because you have not specified it as internal. I have forked your files on github and I think you need this.
###
### deny direct access to private downloads
###
location ~* ^/sites/.*/private/ {
log_not_found off;
internal;
}
However, BEFORE YOU DO THAT.... We have issue...
#2) Your choice of a location won't work well with Drupal.
Using the location of ^/sites/.*/private/ puts the /private folder directly within the example.com (site folder). This means you would need to set your /admin/settings/file-system to sites/example.com and then the path on something like filefield to /private/whatever (mine is /private/videos).
So the full path ends up being sites
/sites/example.com/private/videos
Your included module of nginx_accel_redirect hijacks the /system/files menu path in order to inject the X-Accel-Redirect header.
This means if a user opts to use this module, they MUST set Drupal to use Private files.
The problem is, that the module uses Drupal's file_create_path() function, which in turn calls file_directory_path(). If you look at that function it looks like this.
function file_directory_path() {
return variable_get('file_directory_path', conf_path() .'/files');
}
Which means that /files is implied and the call to file_create_path() within nginx_accel_redirect will always fail and the X-Accel-Redirect header will never get sent.
My suggestion would be to modify your nginx location config to the following.
###
### deny direct access to private downloads
### with support for x-accel-redirect headers
### http://drupal.org/project/nginx_accel_redirect
###
location ~* /files/private/ {
log_not_found off;
internal;
}
It would be optional to use perusio's config setting for
https://github.com/perusio/drupal-with-nginx/blob/master/sites-available...
location ~* /system/files/ {
try_files $uri /index.php?q=$uri&$args;
log_not_found off;
}
As I would personally prefer that you simply block /files/private and allow me to still use Drupal's public files setting - knowing that /files/private is blocked off. This will allow me to write my own modules and inject the x-accel-redirect when I see fit. Of course this also factors into my own file_access module which I will be using and would work with nginx_accel_redirect.
I've not been able to test this yet on my local machine as I just got nginx running today, but this is what I've found to be the case so far. Of course, with only 2 reported sites using nginx_accel_redirect they may not be on the servers Omega8 is running. ;)
Am I right on this one? Or do you have people on omega servers who are successfully using nginx_accel_redirect?
Comments
Comment #1
omega8cc commentedHey Matt!
The location with
~* ^/sites/.*/private/ {is still required, as it is used also for the built-in in Aegir support forsites/domain/privatedirectory, by default created. And it *does work* also forsites/domain/files/privatedirectory, thanks to the wildcard in the path.Also, we don't use
internalthere, because some modules expect error 403 and not 404 - which is default wheninternalis used. At least this is how I remember why we did it that way there.Note also that it is not *our* choice of the location - it is default in the standard Drupal multisite, which is the directory structure used in Aegir, and there are good reasons why the standard path to files is hardcoded in Aegir, so you can't change it and there will be always the
/sites/domainin the (direct) URI.We also have already location for
system, which is always sent to drupal for processing.So what can be wrong if we already have all required locations? I think we have them in the wrong order, as location for
privateis above/before location withsystem, so it never has a chance to hit thesystemlocation and is stopped completely earlier, atprivatelocation.I'm not sure if changing
deny alltointernalwould help here, probably not, so we probably only need to re-order those locations a bit.I just did that and it is now in HEAD, could you test and let us know if that helped?
The fix: http://drupalcode.org/project/octopus.git/commit/f7bb289
Thanks.
Comment #2
mattman commentedOk, I'll pull it down and give it a go. I am trying on my local dev enviroment so I'm just including the nginx_octopus_include.conf file into my server - I'm not running a virtual of a linux box (on OS X).
I was testing with persuio's configs just to see if I could get things going and so far I'm still having issues with replicating the setup. It may be a nginx issue or something else. I installed nginx via macports.
If I can't get much farther, then I'll have to shoot a video and get it to you guys.
Once I can get this going then I'll be an nginx/omega8 convert for life. ;)
Matt
Comment #3
mattman commentedHere's a screencast of my setup and the issue.
http://screencast.com/t/UxQpliAiC
Ok, I've symlinked the nginx_octopus_include.conf into my server and I'm getting the same issues I had with perusio's config.
The issue may either be me, my setup - or the universe. :) The issue I'm hitting is that the file_create_path() function is not returning a valid path. This means the nginx_accel_redirect_file_transfer() function is never getting to the point where it can send
header('X-Accel-Redirect: ' . base_path() . file_create_path($filepath));Even when I modify the code to make sure a valid path gets into the function. The header may be added but nginx does not pass the file through. It still hits
return drupal_not_found();or it's never even getting redirected to nginx.You'll have to excuse any lack of knowledge. I've only just setup nginx for the first time yesterday. I've been beating on this for the past two days however. Maybe you can see something in my setup.
One interesting thing is that when I watch the headers using Live HTTP headers in Firefox, I only send the request to GET /system/files/private/files/KarateAppPart11.zip and the immediate response is a 404 from nginx. So it would seem that nginx isn't even pushing the request to drupal - yet the returned page is a drupal 'Page not found'. Very confusing right now.
Comment #4
mattman commentedHere's some additional info.
With everything in place here's some additional testing I've done. Here are the headers when the private files is turned on.
According to...
The try_files is pushing to @drupal, which is where the
return drupal_not_found();is being hit.However, notice that if I disable the
#try_files $uri @drupal;the return headers I get are of a nginx 404.Should I not be seeing the
add_header X-Header "IC Generator 1.0";or is this because nginx moves on to the 404 and does not add the header due to the error?I'm still coming up to speed on how you guys have this conf laid out.
Comment #5
mattman commentedOk, making some progress. I think I found one issue. The file_create_path() was not working in Drupal because the path to my files was via a symlink.
I don't think php-fpm was able to stat the file so php's realpath() was likely failing within file_check_location().
It's odd because php-fpm is running as my login username and has permissions all the way down. Are there issues with nginx/php-fpm and symlinks?
At least I'm moving forward. It may not be your config at all - It will likely turn out to be me and my lack of knowledge about nginx/php-fpm (coming from an Apache guy :)
Matt
Comment #6
mattman commentedI'm at least now passing through the
nginx_accel_redirect_file_transfer()function.Adding a
dd(headers_list());is giving me this.So at least the header is being added. However, the response I'm now getting is a 403 from nginx.
Here's the result of the error.log debug
It looks like it's not matching anything and getting all the way back up to
Comment #7
omega8cc commentedSo maybe we should really change
deny alltointernalat http://drupalcode.org/project/octopus.git/blob/HEAD:/aegir/conf/nginx_oc... ?Could you try to change this there?
Comment #8
mattman commentedYep, that's an affirmative. As soon as you go
internalthe file comes down. So there's definitely a relationship between x-accel and internal.http://wiki.nginx.org/X-accel
With a 403 deny all it's likely saying "hey this is explicitly denied no matter what!" :)
If other modules expect 403s then you may need to create another location and work within /files and tell people they have to store things in /files/private
Now I have to figure out what the issue is with symlinks.
You guys are using symlinks right? The future issue I'm wondering about is in this particular site the /files/private would have around 13G of files. What would the impact be on a aegir clone on that one! If the files are copied when you make a clone that would suck. So it would be important for me to keep the files outside of the root but yet still support x-accel
On my local box here I can't get symlinks working. Of course, I'm going across two drives - but should that be an issue?
Comment #9
omega8cc commentedThanks, you are right, as it is still using the same URI, just with special header and not like it is for other modules where requests always goes via some Drupal controlled gate like /admin. We just sent this also upstream to Provision.
As for symlinks - yes, we use them and with that big files directory you must move it away from the site's directory anyway, however on the server you will not cross filesystems/disks, so maybe it is some Mac specific issue?
Comment #10
mattman commentedYeah, been toying with php realpath() not being able to stat the file. Something is going on and I'll just have to move the site and files onto the same drive to test.
It's one of those issues that drives you bonkers until you break down and just change how you're doing things. You want to find the answer but you know that many hours wasted = many hours wasted. :)
I'm just glad to know that it will all work out. I'm looking forward to moving my sites to omega boxes. I wish I wasn't so busy right now so I could make some instructional videos about using your setup. At least I'm gaining a ton of knowledge about how things are working behind the scenes!
Closing the issue.
Comment #11
perusio commentedHello,
There's no hardcoding of anything in the module. You can place the private files dir wherever you want. Of course the nginx config must be adjusted. Namely the protection of the direct access.
I haven't checked the code, but in the wiki it's explicit that the location where the special pipelline is active must be set internal. This returns a 404 when trying to access it directly. If you need the 403 then you can use
error_page.in the
internallocation. Now the 403 status code will be returned. The 404.html can be created by just doing:in the site root.
Comment #12
mattman commentedThanks António!
You're knowledge, insight and contributions are muito apreciado. I was able to get my nginx setup going quite quickly with the help of your configs!
Comment #13
omega8cc commentedThank you.
Now Octopus supports X-Accel-Redirect correctly. As I'm not sure if we need 403 there for other modules really, I will leave this with
internalfor now and will use perusio's tip from #11 if needed.Thanks for all your help in debugging this!