Reputation: 2743
I have one URL (domain), for multiple directories (project). And I have a very odd behaviour when putting a .htaccess in it.
sub.mywebsite.com/
=> /foo/bar/things
sub/mywesite.com/pro
=> /srv/www/new
VirtualHost:
<VirtualHost *:80>
DocumentRoot /foo/bar/things
ServerName sub.mywebsite.com
Alias /pro /srv/www/new
</VirtualHost>
And it works perfectly. When I go on sub.mywebsite.com/
it hit the /foo/bar/things
dir and the other way around.
Now, let's add a simple .htaccess
in /srv/www/new
:
RewriteEngine on
RewriteRule ^(.*)/$ php/file.php?text=$1 [L,QSA]
So when I go on sub.mywebsite.com/pro/hello/
the file called is supposed to be /srv/www/new/php/file.php
with a GET arg. I double-checked, the rule is good.
Here is the end of the RewriteLogLevel 4:
192.168.123.123 - - [25/Apr/2018:19:28:11 +0200] [sub.mywebsite.com/sid#7f317dd08b8][rid#7f37eca9f78/initial] (1)
[perdir /srv/www/new/] internal redirect with /srv/www/new/php/file.php [INTERNAL REDIRECT]
And an online htaccess checker confirm it: The new url is http://sub.mywebsite.com/php/file.php%3Ftext=testing
But I've got an apache 404 not found:
Not Found
The requested URL /srv/www/new/php/file.php was not found on this server.
And yes, ls -l /srv/www/new/php/file.php
the file exists.
The VERY ODD part is this: in the apache error log, I've got:
[Wed Apr 25 19:45:30 2018] [error] [client 192.168.123.123] File does not exist: /foo/bar/things/srv
Questions:
/srv/www/new/php/file.php
as the .htaccess ask it?Feel free to ask me more data if needed. I want to understand!
NB: there is no .htaccess in /foo/bar/things
; I've tried a lot of things in my vhost, like adding a <directory>
, etc.
Upvotes: 1
Views: 1346
Reputation: 415
Update for Apache > 2.4.16
Since version 2.4.16 RewriteBase
directive is not required when the request is mapped via Alias
:
This directive is required when you use a relative path in a substitution in per-directory (htaccess) context unless any of the following conditions are true:
- The original request, and the substitution, are underneath the
[DocumentRoot](https://httpd.apache.org/docs/current/mod/core.html#documentroot)
(as opposed to reachable by other means, such as[Alias](https://httpd.apache.org/docs/current/mod/mod_alias.html#alias)
).- The filesystem path to the directory containing the
[RewriteRule](https://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewriterule)
, suffixed by the relative substitution is also valid as a URL path on the server (this is rare).- In Apache HTTP Server 2.4.16 and later, this directive may be omitted when the request is mapped via
[Alias](https://httpd.apache.org/docs/current/mod/mod_alias.html#alias)
or[mod_userdir](https://httpd.apache.org/docs/current/mod/mod_userdir.html)
.
So basically you don't get any AH00128: File does not exist:
errors anymore.
Worth noting that CentOS 7.x comes with Apache 2.4.6 with security patches: as for 2022/01/07 you get 2.4.6-97.2 that fixes CVE-2021-40438. So if you want to manage multiple alias you need to upgrade with a different package, but this is another story...
Upvotes: 1
Reputation: 10889
The answer to both of your questions is already shown on your screen and in your logs:
The requested URL /srv/www/new/php/file.php was not found on this server.
The requested URL.
AH00128: File does not exist: /foo/bar/things/srv/www/new/php/file.php
File does not exist.
So, apache is not trying to fetch the file file.php
which is located in /srv/www/new/php/
folder on your filesystem. It is trying to open URL http://sub.mywebsite.com/srv/www/new/php/file.php
, which explains both the browser error and the line in your error log, since for that URL it really should look into /foo/bar/things/srv/www/new/php/file.php
.
From http://httpd.apache.org/docs/current/mod/mod_rewrite.html:
The rewrite engine may be used in .htaccess files and in sections, with some additional complexity.
(...)
See the RewriteBase directive for more information regarding what prefix will be added back to relative substitutions.
(...)
The RewriteBase directive specifies the URL prefix to be used for per-directory (htaccess) RewriteRule directives that substitute a relative path. This directive is required when you use a relative path in a substitution in per-directory (htaccess) context.
(...)
This misconfiguration would normally cause the server to look for an directory under the document root.
Solution: add RewriteBase "/pro"
to your .htaccess
You can see the difference in Rewrite Log:
Without RewriteBase:
[perdir /srv/www/new/] rewrite 'hello/' -> 'php/file.php?text=hello'
[perdir /srv/www/new/] add per-dir prefix: php/file.php -> /srv/www/new/php/file.php
[perdir /srv/www/new/] internal redirect with /srv/www/new/php/file.php [INTERNAL REDIRECT]
With RewriteBase "/pro"
:
[perdir /srv/www/new/] rewrite 'hello/' -> 'php/file.php?text=hello'
[perdir /srv/www/new/] add per-dir prefix: php/file.php -> /srv/www/new/php/file.php
[perdir /srv/www/new/] trying to replace prefix /srv/www/new/ with /pro
strip matching prefix: /srv/www/new/php/file.php -> php/file.php
add subst prefix: php/file.php -> /pro/php/file.php
[perdir /srv/www/new/] internal redirect with /pro/php/file.php [INTERNAL REDIRECT]
Upvotes: 2