Thursday, February 8, 2024

[SOLVED] RewriteRule working on .htaccess but not httpd.conf

Issue

I'm trying to redirect all urls that have /__/ to /public/assets/ and got it working in .htaccess but not globally in httpd.conf What it should do is re-write:

http://example.com/__/test.css

to

http://example.com/public/assets/test.css

So far I have this working for .htaccess:

RewriteRule ^(.*)/?__/(.*)$ $1/public/assets/$2 [L]

(Which might not be written properly but it's the only way I managed to make it work). If I put it in httpd.conf however, it doesn't work at all. I tried tweaking it, tried putting it inside <VirtualHost 127.0.0.1> and inside <Directory "c:/DEV/wamp/www/"> but it still won't work. Been losing 3 hours of time on this now and found plenty of examples on Stackoverflow/forums, but oddly none of them work for me..

EDIT: Here are two examples of blocks I tried. [R] is to verify if the rule was working and redirecting:

<VirtualHost 127.0.0.1>
    DocumentRoot "c:/DEV/wamp/www/"
    <Directory "c:/DEV/wamp/www/">
        Allow From All
        RewriteEngine On
        RewriteRule ^/(.*)?__/(.*)$ /$1public/assets/$2 [R]
    </Directory>
</VirtualHost>

And this one:

<Directory "c:/DEV/wamp/www/">
    Allow From All
    RewriteEngine On
    RewriteRule ^/(.*)?__/(.*)$ /$1public/assets/$2 [R]
</Directory>

EDIT2: Tried selected edit from proposed answer, still cannot find the css files on the server.

<Directory "c:/DEV/wamp/www/">
    Allow From All
    RewriteEngine On
    RewriteRule ^__/(.*)$ public/assets/$1 [L]
</Directory>

Solution

RewriteRule ^/(.*)?__/(.*)$

You've included a slash prefix on your RewriteRule pattern in the <Directory> container. This should be the same as in your .htaccess file, ie. no directory-prefix.

.htaccess files and <Directory> containers behave the same in this respect. Only when the directive is directly in the server config / VirtualHost container should the directory-prefix be included (but then it matches the URL-path, not the filesystem path, as it does in a .htaccess / Directory context).

If you put it in a <Directory> container then there should be no need to "tweak it".

I'm trying to redirect

Strictly speaking, this is an internal rewrite (as you have in your .htaccess file), rather than an external redirect.


/__/<file> to /public/assets/<file>
RewriteRule ^(.*)/?__/(.*)$ $1/public/assets/$2 [L]

This rewrite can be simplified, providing /__/ always occurs at the start of the URL-path. Try the following in either a .htaccess file or <Directory> container:

RewriteRule ^__/(.*)$ public/assets/$1 [L]

[EDIT] WARNING: mod_rewrite inheritance

If you are switching between testing .htaccess and <Directory> containers in your server config and wondering why the directives in the <Directory> container aren't doing anything then it's possible that the mod_rewrite directives in .htaccess are completely overriding the directives in the <Directory> container. This is the default behaviour. .htaccess directives will take priority and parent directives are not inherited by default.

Generally, if you are using <Directory> containers in the server config then you don't need .htaccess, so the easiest option is to simply disable them in your <Directory> container with AllowOverride None. So, the <Directory> container looks like:

<Directory "c:/DEV/wamp/www/">
Allow From All
AllowOverride None
RewriteEngine On
RewriteRule ^__/(.*)$ public/assets/$1 [L]
</Directory>

If you needed to have mod_rewrite directives in both .htaccess and a parent <Directory> container then you would need to explicitly enable mod_rewrite inheritance by placing the following directive in .htaccess:

RewriteOptions Inherit

If you are on Apache 2.4 then you have more options.

You can't simply disable the rewrite engine in .htaccess (ie. RewriteEngine Off) since that will also prevent the parent directives from being processed. If you simply remove the RewriteEngine directive from .htaccess then the RewriteEngine On directive in the <Directory> container will enable the rewrite engine but will result in the .htaccess directives overriding the parent again, so you are back to requiring the RewriteOptions Inherit directive.



Answered By - MrWhite
Answer Checked By - Timothy Miller (WPSolving Admin)