Re: Don't process requests containing folders

2016-09-12 Thread Grant
>> location ~ (^/[^/]*|.html)$ {}
>
> Yes, that should do what you describe.


I realize now that I didn't define the requirement properly.  I said:
"match requests with a single / or ending in .html" but what I need
is: "match requests with a single / *and* ending in .html, also match
/".  Will this do it:

location ~ ^(/[^/]*\.html|/)$ {}


> Note that the . is a metacharacter for "any one"; if you really want
> the five-character string ".html" at the end of the request, you should
> escape the . to \.


Fixed.  Do I ever need to escape / in location blocks?


>> And let everything else match the following, most of which will 404 
>> (cheaply):
>>
>> location / { internal; }
>
> Testing and measuring might show that "return 404;" is even cheaper than
> "internal;" in the cases where they have the same output. But if there
> are cases where the difference in output matters, or if the difference
> is not measurable, then leaving it as-is is fine.


I'm sure you're right.  I'll switch to:

location / { return 404; }

- Grant

___
nginx mailing list
nginx@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx


Re: Don't process requests containing folders

2016-09-12 Thread Francis Daly
On Mon, Sep 12, 2016 at 01:55:35PM -0700, Grant wrote:

Hi there,

> > If you want to match "requests with a second slash", do just that:
> >
> >   location ~ ^/.*/ {}
> >
> > (the "^" is not necessary there, but I guess-without-testing that
> > it helps.)
> 
> When you say it helps, you mean for performance?

Yes - I guess that anchoring this regex at a point where it will always
match anyway, will do no harm.

> > If you want to match "requests without a second slash", you could do
> >
> >   location ~ ^/[^/]*$ {}
> >
> > but I suspect you'll be better off with the positive match, plus a
> > "location /" for "all the rest".
> 
> 
> I want to keep my location blocks to a minimum so I think I should use
> the following as my last location block which will send all remaining
> good requests to my backend:
> 
> location ~ (^/[^/]*|.html)$ {}

Yes, that should do what you describe.

Note that the . is a metacharacter for "any one"; if you really want
the five-character string ".html" at the end of the request, you should
escape the . to \.

> And let everything else match the following, most of which will 404 (cheaply):
> 
> location / { internal; }

Testing and measuring might show that "return 404;" is even cheaper than
"internal;" in the cases where they have the same output. But if there
are cases where the difference in output matters, or if the difference
is not measurable, then leaving it as-is is fine.

Cheers,

f
-- 
Francis Dalyfran...@daoine.org

___
nginx mailing list
nginx@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx


Re: Don't process requests containing folders

2016-09-12 Thread Grant
>> My site doesn't have any folders in its URL structure so I'd like to
>> have nginx process any request which includes a folder (cheap 404)
>> instead of sending the request to my backend (expensive 404).
>
>> Currently I'm using a series of location blocks to check for a valid
>> request.  Here's the last one before nginx internal takes over:
>>
>> location ~ (^/|.html)$ {
>> }
>
> I think that says "is exactly /, or ends in html".


Yes that is my intention.


> I'm actually not sure whether this is intended to be the "good"
> request, or the "bad" request. If it is the "bad" one, then "return
> 404;" can easily be copied in to each. If it is the "good" one, with a
> complicated config, then you may need to have many duplicate lines in
> the two locations; or just "include" a file with the good" configuration.


That's the good request.  I do need it in multiple locations but an
include is working well for that.


>> Can I expand that to only match requests with a single / or ending in
>> .html like this:
>>
>> location ~ (^[^/]+/?[^/]+$|.html$) {
>
> Since every real request starts with a /, I think that that pattern
> effectively says "ends in html", which matches fewer requests than the
> earlier one.


That is not what I intended.


> If you want to match "requests with a second slash", do just that:
>
>   location ~ ^/.*/ {}
>
> (the "^" is not necessary there, but I guess-without-testing that
> it helps.)


When you say it helps, you mean for performance?


> If you want to match "requests without a second slash", you could do
>
>   location ~ ^/[^/]*$ {}
>
> but I suspect you'll be better off with the positive match, plus a
> "location /" for "all the rest".


I want to keep my location blocks to a minimum so I think I should use
the following as my last location block which will send all remaining
good requests to my backend:

location ~ (^/[^/]*|.html)$ {}

And let everything else match the following, most of which will 404 (cheaply):

location / { internal; }

- Grant

___
nginx mailing list
nginx@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx


Re: Don't process requests containing folders

2016-09-12 Thread Francis Daly
On Mon, Sep 12, 2016 at 10:17:06AM -0700, Grant wrote:

Hi there,

> My site doesn't have any folders in its URL structure so I'd like to
> have nginx process any request which includes a folder (cheap 404)
> instead of sending the request to my backend (expensive 404).

The location-matching rules are at http://nginx.org/r/location

At the point of location-matching, nginx does not know anything about
folders; it only knows about the incoming request and the defined
"location" patterns.

That probably sounds like it is being pedantic; but once you know what the
rules are, it may be clearer how to configure nginx to do what you want.

"doesn't have any folders" might mean "no valid url has a second
slash". (Unless you are using something like a fastcgi service which
makes use of PATH_INFO.)

> Currently I'm using a series of location blocks to check for a valid
> request.  Here's the last one before nginx internal takes over:
> 
> location ~ (^/|.html)$ {
> }

I think that says "is exactly /, or ends in html".

It might be simpler to understand if you write it as two locations:

  location = / {}
  location ~ html$ {}

partly because if that is *not* what you want, that should be obvious
from the simpler expression.

I'm actually not sure whether this is intended to be the "good"
request, or the "bad" request. If it is the "bad" one, then "return
404;" can easily be copied in to each. If it is the "good" one, with a
complicated config, then you may need to have many duplicate lines in
the two locations; or just "include" a file with the good" configuration.

> Can I expand that to only match requests with a single / or ending in
> .html like this:
> 
> location ~ (^[^/]+/?[^/]+$|.html$) {

Since every real request starts with a /, I think that that pattern
effectively says "ends in html", which matches fewer requests than the
earlier one.

> Should that work as expected?

Only if you expect it to be the same as "location ~ html$ {}". So:
probably "no".


If you want to match "requests with a second slash", do just that:

  location ~ ^/.*/ {}

(the "^" is not necessary there, but I guess-without-testing that
it helps.)

If you want to match "requests without a second slash", you could do

  location ~ ^/[^/]*$ {}

but I suspect you'll be better off with the positive match, plus a
"location /" for "all the rest".

Good luck with it,

f
-- 
Francis Dalyfran...@daoine.org

___
nginx mailing list
nginx@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx