Trouble with a complex rewrite

Igor Sysoev is at rambler-co.ru
Tue Apr 3 01:26:39 MSD 2007


On Mon, Apr 02, 2007 at 05:11:21PM -0400, Wilson Bilkovich wrote:

> On 4/2/07, Igor Sysoev <is at rambler-co.ru> wrote:
> >On Mon, Apr 02, 2007 at 03:55:20PM -0400, Wilson Bilkovich wrote:
> >
> >> I have two more questions about this:
> >> 1. I can use any regular expression supported by PCRE, anywhere in my
> >> nginx config, correct?
> >
> >The regexp engine is PCRE.
> >
> >The regexp are supported in some directives only:
> >"if", "rewrite", and "location".
> >
> >> 2. When I have nested locations, such as:
> >> location / {
> >>  location /api/receive {
> >>    break;
> >>  }
> >>  some_config_option on;
> >> }
> >>
> >> Configuration options in the outer scope (location /, in this case)
> >> are always evaluated, despite the break command?
> >> In other words, break only 'breaks' from the location / rewrite loop,
> >> not from the rest of the configuration?
> >
> >If the "rewrite" directive has rewritten URI, then nginx search the new
> >location configuration. The "break" stops this rewrite cycle.
> >
> >The nested locations are not fully supported, you should use
> >
> >   location / {
> >       ...
> >   }
> >
> >   location /api/receive {
> >       ...
> >   }
> >
> >
> 
> Sorry to belabor the point, but this is really helping me understand.
> 
> location / {
>  set $once = "once";
>  if ($once) {
>    set $once = "";
>    rewrite ^ /once break;
>  }
>  set $once = "twice";
>  rewrite /once /twice break;
> }
> 
> Given that code (assuming it is valid.. if not, let's pretend I wrote
> it correctly).
> 
> I would expect that a request for example.com/ would be rewritten to
> example.com/once, and that the value of $once would be 'twice'.

This configuration will run as following:
1) $once is "once" so "set $once = "", then URI became "/once" and rewrite
stops ("break").

> Am I correct about that? My understanding is that break cancels any
> further rewrites, but has no effect on the other configuration
> statements that come after it.

nginx has three type of configuration directives:

1) static: the most directives,
2) partially dynamic: the directives with $variable paramters,
3) and dynamic: if/rewrite/set/break/return.
    
The static directives are compiled into binary structures for each
server and locations and they are usually availabe via three and
so memory accesses.

The partially dynamic directives are also compiled into binary structures
and besides the dynamic parts are compiled into some code that run at
request processing stage.

The dynamic directives are compiled into some code that run at
request processing stage. They can not be used to choose configuration
parts.

The order of directive is mostly important for dynamic directives.
So the following configuration are the same:

--------------------

   location / {
       set   ...;
       rewrite ...;
       if (...) {
           rewrite ...;
           break;
       }

       root  ...;
   }

--------------------

   location / {
       root  ...;

       set   ...;
       rewrite ...;
       if (...) {
           rewrite ...;
           break;
       }
   }

--------------------

   location / {

       set   ...;
       rewrite ...;
       if (...) {
           rewrite ...;
           break;
       }
   }

   root  ...;

--------------------

   root  ...;

   location / {

       set   ...;
       rewrite ...;
       if (...) {
           rewrite ...;
           break;
       }
   }

--------------------

The place of the "root" directive is not important (in two last
configuration it's inherited inside "location /".


-- 
Igor Sysoev
http://sysoev.ru/en/





More information about the nginx mailing list