1

Inside the VirtualHost I got this redirect:

RewriteBase /
RewriteCond %{REQUEST_URI} wp-content/uploads/([^.]+\.(jpe?g|gif|bmp|png))$
RewriteRule (.*) http://example.org/$1 [R=301,L,NC]

So the full VirtualHost config is:

<VirtualHost *:80>
        ServerName localhost.foo

        ServerAdmin webmaster@localhost
        DocumentRoot /home/me/public_html/foo

        LogLevel info

        ErrorLog /home/me/public_html/foo/error.log
        CustomLog /home/me/public_html/foo/access.log combined

    <Directory "/home/me/public_html/foo">
        Options FollowSymLinks Indexes
        AllowOverride All

        RewriteBase /
        RewriteCond %{REQUEST_URI} wp-content/uploads/([^.]+\.(jpe?g|gif|bmp|png))$
        RewriteRule (.*) http://example.org/$1 [R=301,L,NC]
    </Directory>
</VirtualHost>

But in a subfolder I got a .htaccess changing the RewriteBase:

RewriteBase /thisIsMe

Now when I access an image

  • http://localhost.foo/thisIsMe/wp-content/uploads/someImage.jpg
  • Should redirect to: http://example.org/thisIsMe/wp-content/uploads/someImage.jpg
  • but redirects to http://example.org/wp-content/uploads/someImage.jpg

So the RewriteBase /thisIsMe in the URL got lost.

How can I achieve the correct URL as above?

MrWhite
  • 12,647
  • 4
  • 29
  • 41
LeMike
  • 179
  • 1
  • 8

2 Answers2

1

RewriteBase is used for per-directory rewrites, i.e. rewrites with a relative path to/from the directory. Your rewrite contains an absolute path since it points to an entirely different hostname. (It may be on the same host, but mod_rewrite doesn't know that...).

Instead of using RewriteBase, you should add the actual path that you want to have inserted - e.g.:

    RewriteRule (.*) http://example.org/ThisIsMe/$1 [R=301,L,NC]
Jenny D
  • 27,780
  • 21
  • 75
  • 114
  • Thanks. I can do that and it's my current workaround. But I like to have the rule for all sub-directories so placing the name there would mean that the sub-folder "thatIsAnother" would point to "http://example.org/ThisIsMe" instead of "http://example.org/thatIsAnother". – LeMike May 23 '14 at 17:19
  • From the information in the question, the captured URL-path (`$1` backreference) should already contain the full URL-path starting `thisIsMe/...`, so there would seem to be something else going on here. It is quite likely the OP is using mod_rewrite inheritance to inherit the parent directives into `/thisIsMe/.htaccess` - this would account for the missing `thisIsMe/` directory in the captured URL-path. In which case they would need to use the `REQUEST_URI` server variable instead. I've added an answer with more explantion... https://serverfault.com/a/1032180/49157 – MrWhite Aug 31 '20 at 16:02
0

As @JennyD already stated in her answer, the RewriteBase directive does not apply when using absolute URL substitution strings in the RewriteRule directive.

However, the directives as posted should already work as intended (RewriteBase is not requried). The captured backreference ($1) should already contain the full URL-path. ie. thisIsMe/wp-content/uploads/someImage.jpg.

Unless... in your /thisIsMe/.htaccess file you are using mod_rewrite inheritance to inherit the <Directory> mod_rewrite directives in-place in the .htaccess file. This would seem quite likely, given you are trying to set RewriteBase here. Since the mod_rewrite directives are effectively copied in-place (inherited) in the subdirectory's .htaccess file, you will lose the subdirectory from the captured backreference.

To resolve this you could either:

  • Remove the mod_rewrite directives entirely from the /thisIsMe/.htaccess file - not necessarily practical if you have other/specific mod_rewrite directives here (although these can always be moved to the server config). The mod_rewrite directives in the <Directory> container are then simply processed as-is, they are not "inherited" into a child config.

OR,

  • Use the REQUEST_URI server variable instead in the inherited directives in the <Directory> container. REQUEST_URI always contains the full URL-path (starting with a slash). So, will naturally contain the /thisIsMe prefix. For example:

    RewriteEngine On
    RewriteRule wp-content/uploads/[^.]+\.(jpe?g|gif|bmp|png)$ http://example.org%{REQUEST_URI} [R=301,L]
    

    The preceding RewriteCond (and RewriteBase) directive(s) are not required. The RewriteEngine On directive is required - unless this is already enabled earlier in the config.

MrWhite
  • 12,647
  • 4
  • 29
  • 41