You need to change the links inside your application to point to the CDN for static includes.
When you rewrite to an http location there's nothing nginx can do but redirect the browser (since the CDN is outside of nginx, and the browser needs to get the files from the CDN). You would have the same issue with Apache or any other URL rewriter, as the CDN is not an "internal" location to the web server.
One option might be the nginx subsitution module, which can replace content as it is delivered. But that doesn't handle regular expressions, and would slow down every request. It is better just to change your application's HTML to reference the CDN URLs directly.
I suspect that you might be able to avoid the infinite loop in your second ruleset by putting the rewriting directives in the main virtual host configuration, not in an .htaccess
file. That's generally good practice anyway, since rewriting runs a lot faster when you put it in the virtual host, and you can get further speed benefits if you can tell Apache to ignore .htaccess
files altogether.
The logic behind this is explained in the mod_rewrite technical documentation. Here's the gist: as you know, rewrite rules can change which filename a given request corresponds to, and even which directory the resulting file is in. In fact, your
RewriteRule ^$ /blog/
is a perfect example, which changes the document root to the blog
directory. But Apache needs to know the directory in order to figure out which .htaccess
files to check for the request. Maybe you can see the problem here: by the time Apache reaches your .htaccess
file, it has already determined the name of the file it should be accessing, which means it's too late for your rewriting rules to apply.
Apache internally solves this problem by creating a new subrequest, which starts processing over from the beginning, and injecting the rules from your .htaccess
file into the processing stream so they will apply to the request. As a side effect of this, all applicable rewrite rules are applied again, and this means that the [L]
flag is kind of a lie when you use it in a .htaccess
file. So even though you put [L]
on your rule to try to force it to be the last rule applied, it really isn't; all the rules are applied again when Apache processes its internal subrequest.
If you don't have access to the main server configuration, you might be able to do this:
RewriteRule ^/blog/?$ / [R,L,NS]
The NS
flag prevents the rule from being applied to subrequests.
Best Answer
By the sounds of it, your
sub
subdomain maps to the same directory as the main domain and all other subdomains (www
andother
, etc.)However, if all requests to the
sub
subdomain are internally rewritten to the/sub
subdirectory then you can presumably just create another.htaccess
at/sub/.htaccess
in which you setDirectorySlash Off
- this then applies to all requests to thesub
subdomain. (Assuming you don't also access the same subdirectory via a different hostname. You can prevent this if you wish.)The
/sub/.htaccess
file is also where you would be implementing #3 in your requirements.The root
.htaccess
file simply rewrites all requests to thesub
subdomain to the/sub
subdirectory.Aside: Since you are asking this question on ServerFault it is generally assumed that you have full control of the server. In which case it would be preferable to configure this
sub
subdomain in its own vHost container that points directly to the/sub
subdirectory (or somewhere outside of the main domains directory tree ideally). In this case, you would not need to implement #2 of your requirements and you just setDirectorySlash Off
for the entire subdomain.