As you might remember from the “fastcgi php migration” thread back in
March, the list helped solve a problem migrating our apache setup where
php ran through files with extensions (.php, .shtml) and extensionless
files (e.g. /galleries/123/72 where galleries is a php script NOT a
directory and /123/72 were the arguments or /some-event/day1/photos/12
where photos was a php script that could be located in any depth of
subdirs)
The solutions suggested by Igor and the list have worked perfectly.
Thanks again!
I’ve been looking at various .conf’s and have seen how they handle Rails
static caching and I’m wondering how to apply that in my non-Rails
setup.
Sometimes after a big event we can get hammered (once even getting
listed on a Yahoo! news page) and I’ve thought about creating static
versions of my script pages using php and curl or something.
I’d have two situations. One where an extensioned but argument-less php
script had a cached .html version and second where an extensionless
script and its pathinfo had a cached version
- In the first case, say I had a database hungry file at:
/tribeca-fest/winners.shtml and I created a cached version as
/tribeca-fest/winners.shtml.html am I correct in assuming that:
if (-f $request_filename.html) {
break;
}
would serve it properly?
- The 2nd case would be a little more crazy and I’m not sure if it’s
doable.
Let’s say I have the extensionless file “galleries” in the root and it’s
pathinfo can be:
/galleries/123/ <- an overview listing
/galleries/123/5 <- a more detailed listing
/galleries/123/5/72 <- an individual photo
I could create three cache files:
/galleries_123.html
/galleries_123_5.html
/galleries_123_5_72.html
Is there anyway for nginx to translate a request for /galleries/123/5/72
or the other two examples into their underscore seperated .html
equivalent?
I’m thinking that handling #1 is dead easy but the problem in #2 might
be a little nuts?
Thanks for any advice.
Ian M. Evans a écrit :
- In the first case, say I had a database hungry file at:
/tribeca-fest/winners.shtml and I created a cached version as
/tribeca-fest/winners.shtml.html am I correct in assuming that:
if (-f $request_filename.html) {
break;
}
would serve it properly?
You have to rewrite your request for nginx to understand that it should
serve
the cached version. Common rails recipes use :
if (-f $request_filename/index.html)
{
rewrite ^(.*)$ $1/index.html break;
}
if (-f $request_filename.html)
{
rewrite ^(.*)$ $1.html break;
}
(So it can be used for directories and files, you may want to skip the
first part.)
I could create three cache files:
/galleries_123.html
/galleries_123_5.html
/galleries_123_5_72.html
Is there anyway for nginx to translate a request for /galleries/123/5/72
or the other two examples into their underscore seperated .html equivalent?
Seems tricky if you want to test the cache existence and not simply
rewrite to
the underscored version (which could be done with a simple rewrite).
Maybe an if block like this :
if ($request_filename ~ (foo)/(bar)/(baz)) {
set $foo $1;
set $bar $2;
set $baz $3;
}
Could be used before another if block to check the local file.
Jean-Philippe wrote:
if (-f $request_filename.html)
{
rewrite ^(.*)$ $1.html break;
}
Okay, thanks.
Seems tricky if you want to test the cache existence and not simply
rewrite to the underscored version (which could be done with a simple
rewrite).
Maybe an if block like this :
if ($request_filename ~ (foo)/(bar)/(baz)) {
Yeh, I figured the second part of the wish list would be the nutty one.
It’s too bad there’s not a way (unless there is and I have to read
deeper!) to string replace the pathinfo so you could just test something
like:
location /galleries {
if ($request_filename.underscoredpathinfo.html) {…etc…
I guess I may have to consider something like Varnish, though I’ve read
that nginx’s ability to serve up static files can sometimes even be
faster than memory caches due to filesystem caching.
}
Jean-Philippe wrote:
Seems tricky if you want to test the cache existence and not simply
rewrite to the underscored version (which could be done with a simple
rewrite).
Right…is it correct to say that nginx can’t regex replace BEFORE a
file test? That is, the logic can say:
if the request is in location /galleries rewrite and serve up
/galleries[path slashes converted to underscores].html
but it can’t say:
if the request is in location /galleries rewrite the URI to
/galleries[path slashes converted to underscores].html, check to see if
that exists and if so, serve it up?
Ian M. Evans a écrit :
but it can’t say:
if the request is in location /galleries rewrite the URI to
/galleries[path slashes converted to underscores].html, check to see if
that exists and if so, serve it up?
I don’t think the location directive sets $n ($1, $2 etc…) variables
like the
“if” directive, so the only way to do this may be using the perl module.
Otherwise you could still create your cache files using the same layout
as your
URLs (by creating multiples directories and subdirectories).
Jean-Philippe M. wrote:
Otherwise you could still create your cache files using the same layout
as your URLs (by creating multiples directories and subdirectories).
Ah, I had an brief inkling of that thought last night.
So I’d have my PHP cache code create different dirs and index files so
you’d have
/galleries/1 => /galleries/1/index.html
/galleries/1/27 => /galleries/1/27/index.html
/galleries/1/27/8 => /galleries/1/27/8/index.html
Since /galleries is actually a FILE in the root, not a directory, could
I create a cache dir with a galleries dir elsewhere and say something
like this:
if (-f /cache/$request_filename/index.html)
{
rewrite ^(.*)$ /cache/$1/index.html break;
}
[No idea if that’s the right way to do the syntax]
Also…is there any magic I’d need to do if someone added a trailing
slash so the “if” wouldn’t be looking for:
/galleries/1/27/ => /galleries/1/27//index.html
^^
Thanks for helping me think this through!
Ian M. Evans a écrit :
/galleries/1 => /galleries/1/index.html
}
[No idea if that’s the right way to do the syntax]
This should be possible, even without adding a /index.html in the
expression
(nginx should handle this automatically thanks to the index directive).
Note that /cache here refers to a directory directly under the
filesystem root.
Also…is there any magic I’d need to do if someone added a trailing
slash so the “if” wouldn’t be looking for:
/galleries/1/27/ => /galleries/1/27//index.html
^^
Here again nginx should handle this automatically. At least it does it
when
doing URL processing.
Jean-Philippe M. wrote:
Here again nginx should handle this automatically. At least it does it
when doing URL processing.
Yep, it did. Tossed the file test into my galleries location and it did
pull up an html copy I manually stuck in the right location.
Now off to look at my PHP code and write the output and then a cron to
clean up the cache every once in a while.
But first, a coffee!