Allow internal redirect to URI x, but deny external request for x?

J. Lewis Muir jlmuir at imca-cat.org
Sat Aug 31 15:04:23 UTC 2019


On 08/31, Francis Daly wrote:
> On Sat, Aug 31, 2019 at 12:21:40AM +0100, Francis Daly wrote:
> 
> Hi there,
> 
> A few further thoughts here...
> 
> > It sounds like your desires are for requests:
> > 
> >  * starts with /my-app/current/ -> reject
> >  * starts with /my-app/releases/ -> reject
> >  * matches /my-app/something.php, or /myapp/something.php/anything ->
> 
> Typo there -- should be "/my-app/".

Yeah, no problem; I knew what you meant.

> But note that the "/my-app/" in the request and the "/my-app/" on the
> filesystem do not need to the same. (And also: the filesystem /my-app/
> for the php files and the filesystem /my-app/ for other files do not
> need to be the same; if you want to keep your "static" and "processed"
> content separate.)

Got it.

> > fastcgi-process the file /srv/www/my-app/current/something.php
> >  * matches /my-app/something -> just send the file
> > /srv/www/my-app/current/something
> > 
> > Is that correct? If so -- do exactly that.
> > 
> > For example (but mostly untested):
> > 
> > ==
> >   location ^~ /my-app/current/ { return 200 "nothing to see at /current/\n"; }
> >   location ^~ /my-app/releases/ { return 200 "nothing to see at /releases/\n"; }
> >   location ^~ /my-app/ {
> >     location ~ \.php($|/) {
> >       fastcgi_split_path_info ^/my-app(/.*php)(.*);
> 
> If there might be more than one "php" in the request, that will split on
> "the last one". Perhaps you want to split on "the first one followed by
> slash". In that case, adjust the regex:
> 
>       fastcgi_split_path_info ^/my-app(/.*?php)($|/.*);

Yes, I ended up doing something like that:

  fastcgi_split_path_info ^/synchweb(/.+?\.php)(/.*)?$;

I think you'd want the "\." in yours before the "php", and then I think
the only meaningful difference between ours would be that yours would
match

  /my-app/.php

while mine would not because I used ".+?" to match one or more
reluctantly where you used ".*?" to match zero or more reluctantly.

I was aware of

  https://www.nginx.com/resources/wiki/start/topics/examples/phpfcgi/

which has a location of

  location ~ [^/]\.php(/|$) {

and a fastcgi_split_path_info of

  fastcgi_split_path_info ^(.+?\.php)(/.*)$;

I've always wondered exactly what the idea was with starting that
location regex with "[^/]", though.  Why require the ".php" to be
preceded by a character other than "/"? That means it would match a
request of

  /foo.php

but not

  /.php

Is it because that's considered an invalid PHP file name?  Is it because
some PHP web apps uses a directory named ".php" as a private directory
that should not be served?  I don't know.

> >       root /srv/www/my-app/current/;
> 
> You did also show a "if (!-f" config, which is "404 if the matching php
> file is not present". That can be:
> 
>       try_files $fastcgi_script_name =404;
> 
> because we have root and the variable set correctly here.

Ah, I see!  Thank you for pointing that out!  I like that better.

> >       include fastcgi.conf;
> 
> Possibly the only bits of that file that you care about are:
> 
>       fastcgi_param PATH_INFO $fastcgi_path_info;
>       fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
> 
> so you could just use those lines directly.

Yes, I could, but I was trying to make my php-fpm-realpath.conf reusable
for other apps which is why I was keeping those lines in it.  And, I
think I mentioned this earlier, but I changed them to use $realpath_root
instead of $document_root because of the symlinks and my desire to
support an atomic app deploy with no downtime and no nginx reload.

Thanks again!

Lewis


More information about the nginx mailing list