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

J. Lewis Muir jlmuir at
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


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

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


but not


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!


More information about the nginx mailing list