Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rewriting paths in CSS & JS via nginx's sub_filter

Tags:

nginx

I'm having a problem with nginx's sub_filter rewrite rules not working with CSS files. I'm serving content on a path (/site) and need all URLs in JS & CSS to be prefixed correctly.

I've specified the mime type when linking in the CSS. From the template:

<link href="/static/css/site.css" type="text/css" rel="stylesheet" />

nginx has sub filters enabled and I've explicitly specified to include text/css:

location /site {
    access_log /opt/logs/test/nginx-access-site.log combined if=$loggable;
    error_log  /opt/logs/test/nginx-errors-site.log error;

    rewrite ^(/site)$ $1/;
    rewrite ^/site(.+) $1 break;

    sub_filter "test.domain.tld" "test.domain.tld/site";
    sub_filter "'/" "'/site/";
    sub_filter '"/' '"/site/';
    sub_filter "http:" "https:";
    sub_filter_types text/html text/css text/javascript;
    sub_filter_once off;

    include proxy_params;
    proxy_pass http://site_test$1$is_args$args;
    proxy_redirect http://test.domain.tld/ https://test.domain.tld/site/;
}

The reference to the CSS file is rewritten correctly. From the HTML output:

<link href="/site/static/css/site.css" type="text/css" rel="stylesheet" />

The issue is it's not rewriting within the CSS file, so image paths are incorrect:

.sortable th .asc {
  background-image: url("/static/img/up_arrow.gif");
}

I've tried being overly permissive without any difference:

    sub_filter_types *;

Have I misunderstood the use of sub_filter? I assumed that because the CSS was being served directly by nginx it would also be rewritten.

like image 663
Matthew Trevor Avatar asked Nov 16 '16 05:11

Matthew Trevor


1 Answers

I found the solution after some searching and wasted some time trying some that didn't work so hopefully this helps someone else searching and found this post.

Apparently, by default sub_filter works only for text/html. I tried various other options to enable for text/javascript text/css like this, but which didn't work:

sub_filter_types text/xml text/css text/javascript;

Finally got it working by filtering all types like this:

sub_filter_once off;
sub_filter_types *;

Remember to restart nginx and remember to clear cache on your browser.

like image 188
85noob Avatar answered Sep 20 '22 11:09

85noob