The addition before sub

Maxim Dounin mdounin at mdounin.ru
Thu Jun 6 17:56:52 UTC 2013


Hello!

On Thu, Jun 06, 2013 at 05:43:14PM +0200,  Witold Filipczyk wrote:

> W dniu 06.06.2013 o 15:57 Maxim Dounin <mdounin at mdounin.ru> pisze:
> 
> >Hello!
> >
> >On Thu, Jun 06, 2013 at 03:41:53PM +0200,  Witold Filipczyk wrote:
> >
> >>Hello,
> >>I want to inject something before </body> and before </head>, but
> >>even if there is no </body>.
> >>So used add_after_body /after_body;
> >>/after_body returns the text </body>, so there is at least one
> >></body> in the page.
> >>I wanted sub_filter to replace </body> to SOMETHING</body>, but the
> >>sub_filter is run before the addition_filter.
> >>Changing the order in modules doesn't help, because the sub_filter
> >>doesn't replace the text from subrequests.
> >
> >Works fine here:
> >
> >    location / {
> >        add_after_body /after.html;
> >        sub_filter 'foo' 'bar';
> >    }
> >
> >$ cat main.html
> >this is main.html: foo
> >$ cat after.html
> >this is in after.html: foo
> >$ fetch -qo - 'http://localhost:8080/main.html'
> >this is main.html: bar
> >this is in after.html: bar
> >
> >The explanation is simple: addition filter uses _subrequests_ to
> >add text, and these subrequests are in turn processed by the whole
> >filter chain, including the sub filter.  Hence order of sub and
> >addition filters doesn't matter.
> >
> >Most likely it doesn't work for you because /after_body have some
> >default mime type not matched by sub_filter_types, see
> >http://nginx.org/r/sub_filter_types.
> 
> OK. It works, but:
> 
> server {
>    listen 8000;
>    sub_filter 'foo' 'bar';
>    sub_filter_once on;
> 
>    location / {
>       root /;
>       add_after_body /after.html;
>    }
> 
>    location = /after.html {
>       root /;
>    }
> }
> 
> /after.html contains "lalala foo"
> /body.html contains "foo"
> 
> http://localhost:8000/body.html:
> bar lalala bar
> 
> I expected:
> bar lalala foo

Any reasons for the expectation?

> How to switch off sub_filter for location = /after.html to get
> expected result?

As in most cases sub_filter isn't switched on if it's not needed, 
there are no special way to turn it off.  Using an empty search
string does the trick though, at least in recent enough versions:

    location = /after.html {
        sub_filter "" "";
    }

Better solution would be to don't switch it on where it's not 
needed, i.e.:

    location / {
        add_after_body /after.html;
        sub_filter "foo" "bar";
    }

    location = /after.html {
        # no sub_filter here
    }

-- 
Maxim Dounin
http://nginx.org/en/donation.html



More information about the nginx-devel mailing list