Send all requests to subfolder using Apache - apache

I'm trying to get all requests to my website passed on to a subfolder in my webroot.
Here's my folder structure:
/webroot
current
releases
release1
index.html
en
index.html
release2
index.html
en
index.html
...
.htaccess
The current folder is a symlink pointing to a folder in the releases folder. The idea is that when I make a new release, a new folder is created in the releases folder and the current symlink is then pointing to this new folder.
In my .htaccess I'm then trying to pass on all requests to the current symlink. So if a user requests, for example, /en the requests should be routed through the symlink and while the browser URL will look like https://example.com/en the actual request will end up at https://example.com/current/en
Now, this works perfectly as long as the request ends with a trailing slash, for example https://example.com/en/ but if I remove the trailing slash the routing works BUT the URL in the browser will be https://example.com/current/en
Here's the rewrites I'm doing in my .htaccess:
Options +FollowSymlinks -MultiViews -Indexes
DirectorySlash On
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_URI} !^/current/
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^(.*)$ current/$1 [L]
And here's the logfile
[perdir /path/to/webroot/] applying pattern '^(.*)$' to uri 'en'
[perdir /path/to/webroot/] RewriteCond: input='/en' pattern='!^/current/' => matched
[perdir /path/to/webroot/] RewriteCond: input='' pattern='^$' => matched
[perdir /path/to/webroot/] rewrite 'en' -> 'current/en'
[perdir /path/to/webroot/] add per-dir prefix: current/en -> /path/to/webroot/current/en
[perdir /path/to/webroot/] trying to replace prefix /path/to/webroot/ with /
strip matching prefix: /path/to/webroot/current/en -> current/en
add subst prefix: current/en -> /current/en
[perdir /path/to/webroot/] internal redirect with /current/en [INTERNAL REDIRECT]
[perdir /path/to/webroot/] strip per-dir prefix: /path/to/webroot/current/en -> current/en
[perdir /path/to/webroot/] applying pattern '^(.*)$' to uri 'current/en'
[perdir /path/to/webroot/] RewriteCond: input='/current/en' pattern='!^/current/' => not-matched
[perdir /path/to/webroot/] pass through /path/to/webroot/current/en
[perdir /path/to/webroot/] strip per-dir prefix: /path/to/webroot/current/en/ -> current/en/
[perdir /path/to/webroot/] applying pattern '^(.*)$' to uri 'current/en/'
[perdir /path/to/webroot/] RewriteCond: input='/current/en/' pattern='!^/current/' => not-matched
[perdir /path/to/webroot/] pass through /path/to/webroot/current/en/
[perdir /path/to/webroot/] strip per-dir prefix: /path/to/webroot/current/en/index.php -> current/en/index.php
[perdir /path/to/webroot/] applying pattern '^(.*)$' to uri 'current/en/index.php'
[perdir /path/to/webroot/] RewriteCond: input='/current/en/index.php' pattern='!^/current/' => not-matched
[perdir /path/to/webroot/] pass through /path/to/webroot/current/en/index.php
[perdir /path/to/webroot/] strip per-dir prefix: /path/to/webroot/current/en/index.html -> current/en/index.html
[perdir /path/to/webroot/] applying pattern '^(.*)$' to uri 'current/en/index.html'
[perdir /path/to/webroot/] RewriteCond: input='/current/en/index.html' pattern='!^/current/' => not-matched
[perdir /path/to/webroot/] pass through /path/to/webroot/current/en/index.html

but if I remove the trailing slash the routing works BUT the URL in the browser will be https://example.com/current/en
I assume you mean https://example.com/current/en/ (with a trailing slash).
This happens because mod_dir tries to "fix" (with a 301 redirect) the URL by appending a trailing slash to physical directories when omitted (this is necessary for directory indexes to work correctly). This "fix" occurs after the URL has been rewritten to the subdirectory (since the URL-path /en does not initially map to a subdirectory).
You can disable this behaviour of mod_dir, so that trailing slashes are not appended; but that gets messy (you then need to manually append the trailing slash as required) and could potentially raise security issues.
Instead, you need to make sure you are always linking to the URL with a trailing slash and manually correcting any URL that omits the trailing slash in .htaccess before mod_dir does so.
Your existing rewrite that rewrites to the /current subdirectory looks OK, although you don't necessarily need to check that the request is not already for /current/ (the first condition). (By checking that the request does not already start /current/ then you are allowing direct requests to the actual symlink'd filesystem location - although maybe that's a requirement?)
So, before your existing rewrite, add the following redirect:
# Fix any requests for directories that omit the trailing slash
RewriteCond %{DOCUMENT_ROOT}/current/$1 -d
RewriteRule ^(.+[^/])$ /$1/ [R=301,L]
Given a request for /example, the above first checks whether /current/example exists as a directory (albeit a symlink'd directory). If if does then it issues a 301 redirect to append the trailing slash to the original URL, not the rewritten URL. eg. /example is redirected to /example/, which is then later rewritten to /current/example/.
Test first with 302 (temporary) redirects to avoid potential caching issues.
You will need to clear your browser cache, since the erroneous 301 (permanent) redirect by mod_dir will have been cached by the browser.
UPDATE:
it should not be possible to directly access any files or folders in the "current" folder. Currently, that's possible...
As hinted at above, you could simply remove the first condition that checks whether the REQUEST_URI does not already start with /current/. So all direct requests are unconditionally rewritten to /current/. A request for /current/en/ would therefore be rewritten to /current/current/en, resulting in a 404.
However, a user could still potentially request the filesystem location directly, bypassing the symlink entirely. eg. /releases/release1/en/.
To block both these locations from direct access you could add the following as the first rule:
# Block direct access to "/current/" and "/releases/"
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^(current|releases)($|/) - [F]
Requesting /current/... or /releases/... directly would result in a "403 Forbidden". Or change the F to R=404 to serve a "404 Not Found" instead (no redirect occurs, despite the use of the R flag).
The check against the REDIRECT_STATUS environment variable (as in your original rule) ensures that the request can still be internally rewritten to these locations. (The REDIRECT_STATUS env var is empty on the initial request from the client, but set to the HTTP response status (eg. "200") after the first rewrite.)

Related

RewriteRule causing 403

I restored a website from webarchive so it has files with file names like:
blog.html
blog.html%3fstart%3d10
blog.html%3fstart%3d20
blog.html%3fstart%3d30
And the pagination was working with links like blog.html?start=10 etc.
So I need simple redirect. My .htaccess looks like the following, but getting 403 error.
RewriteEngine On
RewriteCond %{QUERY_STRING} ^start=([0-9]+)$
RewriteRule ^(.*)$ /blog.html\%253fstart\%253d%1 [L]
But I am getting 500 error (looked in apache log that it was infinite internal redirect), here's full apache log:
strip per-dir prefix: F:/OSPanel/domains/test3/blog.html -> blog.html
applying pattern '^(.*)$' to uri 'blog.html'
rewrite 'blog.html' -> '/blog.html%253fstart%253d10'
trying to replace context docroot F:/OSPanel/domains/test3 with context prefix
internal redirect with /blog.html%253fstart%253d10 [INTERNAL REDIRECT]
strip per-dir prefix: F:/OSPanel/domains/test3/blog.html%3fstart%3d10 -> blog.html%3fstart%3d10
applying pattern '^(.*)$' to uri 'blog.html%3fstart%3d10'
rewrite 'blog.html%3fstart%3d10' -> '/blog.html%253fstart%253d10'
trying to replace context docroot F:/OSPanel/domains/test3 with context prefix
internal redirect with /blog.html%253fstart%253d10 [INTERNAL REDIRECT]
strip per-dir prefix: F:/OSPanel/domains/test3/blog.html%3fstart%3d10 -> blog.html%3fstart%3d10
applying pattern '^(.*)$' to uri 'blog.html%3fstart%3d10'
rewrite 'blog.html%3fstart%3d10' -> '/blog.html%253fstart%253d10'
trying to replace context docroot F:/OSPanel/domains/test3 with context prefix
internal redirect with /blog.html%253fstart%253d10 [INTERNAL REDIRECT]
And the last block repeats 10 times
What am I doing wrong?

How to redirect URL with htaccess (RewriteRule) and prevent direct access

using .htaccess I'd like to transparently redirect requests for folder "old" to folder "new", and in the same time prevent direct access to folder "new":
desired result:
http://example.com/old/... -> will display what's in "new" (no URL change in browser!)
http://example.com/new/... -> no access
this is my code in .htaccess (the 1st line is here because several domains share the same root folder):
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^old(.*)$ new$1 [L]
RewriteRule ^new(.*)$ - [F]
Well, what happens is that the 3d line triggers because of the substitution in the 2nd. I was convinced that the flag "L" would prevent this from happening (end of processing), but it seems that's not the case.
Do you have any suggestions what needs to be done (I tried to debug with rewrite log, but without success)?
I did some logging and found the following:
[rid#d0ac98/initial] (3) [per-dir C:/www/example/] add path info postfix: C:/www/example/new -> C:/www/example/new/
[rid#d0ac98/initial] (3) [per-dir C:/www/example/] strip per-dir prefix: C:/www/example/new/ -> new/
[rid#d0ac98/initial] (3) [per-dir C:/www/example/] applying pattern '^new(.*)$' to uri 'new/'
[rid#d0ac98/initial] (4) RewriteCond: input='localhost' pattern='^example\.com$' => not-matched
[rid#d0ac98/initial] (4) RewriteCond: input='localhost' pattern='^localhost$' => matched
[rid#d0ac98/initial] (2) [per-dir C:/www/example/] rewrite new/ -> old/
[rid#d0ac98/initial] (3) [per-dir C:/www/example/] add per-dir prefix: old/ -> C:/www/example/old/
[rid#d0ac98/initial] (2) [per-dir C:/www/example/] strip document_root prefix: C:/www/example/old/ -> /example/old/
[rid#d0ac98/initial] (1) [per-dir C:/www/example/] internal redirect with /example/old/ [INTERNAL REDIRECT]
[rid#d217a8/initial/redir#1] (3) [per-dir C:/www/example/] strip per-dir prefix: C:/www/example/old/ -> old/
[rid#d217a8/initial/redir#1] (3) [per-dir C:/www/example/] applying pattern '^new(.*)$' to uri 'old/'
[rid#d217a8/initial/redir#1] (3) [per-dir C:/www/example/] strip per-dir prefix: C:/www/example/old/ -> old/
[rid#d217a8/initial/redir#1] (3) [per-dir C:/www/example/] applying pattern '^old(.*)$' to uri 'old/'
[rid#d217a8/initial/redir#1] (2) forcing 'C:/www/example/old/' to be forbidden
This seems an internal redirect, which causes the "forbidden" result. Indeed, the documentation mentions it:
It is therefore important, if you are using RewriteRule directives in one of these contexts, that you take explicit steps to avoid rules looping, and not count solely on the [L] flag to terminate execution of a series of rules, as shown below. An alternative flag, [END], can be used to terminate not only the current round of rewrite processing but prevent any subsequent rewrite processing from occurring in per-directory (htaccess) context. This does not apply to new requests resulting from external redirects...
So I suppose that in my example the error was due to the fact that I used "L" flag instead the "END" flag?
I found an alternative solution (3rd line is inserted here):
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^old(.*)$ new$1 [L]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^new(.*)$ - [F]
The 4th line will be executed only if there's no internal redirect.
You can use:
RewriteEngine On
# if directly requesting /new then block it
RewriteCond %{THE_REQUEST} \s/+new(/\S*)?\s [NC]
RewriteRule ^ - [F]
# forward /old/abc to /new/abc
RewriteCond %{HTTP_HOST} ^(www\.)?example\.com$ [NC]
RewriteRule ^old(/.*)?$ new$1 [L,NC]
We used THE_REQUEST in first rule. THE_REQUEST variable represents original request received by Apache from your browser and it doesn't get overwritten after execution of some rewrite rules. REQUEST_URI on the other hand changes its value after other rewrite rules.
For the same reason your rule RewriteRule ^new(.*)$ - [F] will even block your request from /old/ since first rule changes URI to /new/.

Unable to ignore mod_rewrite internal redirects with NS flag

I have defined a couple mod_rewrite rules in an .htaccess file, one to rewrite the URL path from /rwtest/source.html to /rwtest/target.html, and another to prohibit direct access to /rwtest/target.html. That is, all users wishing to see the content of /rwtest/target.html must enter /rwtest/source.html in their URL bar.
I was trying to use the NS flag in the forbid rule to prevent rewritten URLs from being denied as well, but it appears this flag does not distinguish between the first request and the internal redirect. It would seem that NS should do the job, but I'm sure I'm misunderstanding something.
Can someone please clarify this behavior? What exactly makes this internal redirect not an internal subrequest that the NS flag can ignore?
Details:
Here's my full .htaccess file:
Options +FollowSymLinks -Multiviews
RewriteEngine on
RewriteBase /rwtest
# Forbid rule. Prohibit direct access to target.html. Note the NS flag.
RewriteRule ^target.html$ - [F,NS]
# Rewrite rule. Rewrite source.html to target.html.
RewriteRule ^source.html$ target.html
I'm running Apache 2.4.9 on Windows 7 x64, but I've observed similar behavior on Apache 2.4.3 on Linux. Here's Log output for a request to /rwtest/source.html.
[rewrite:trace3] [rid#20b6200/initial] [perdir C:/Apache24/htdocs/rwtest/] strip per-dir prefix: C:/Apache24/htdocs/rwtest/source.html -> source.html
[rewrite:trace3] [rid#20b6200/initial] [perdir C:/Apache24/htdocs/rwtest/] applying pattern '^target.html$' to uri 'source.html'
[rewrite:trace3] [rid#20b6200/initial] [perdir C:/Apache24/htdocs/rwtest/] strip per-dir prefix: C:/Apache24/htdocs/rwtest/source.html -> source.html
[rewrite:trace3] [rid#20b6200/initial] [perdir C:/Apache24/htdocs/rwtest/] applying pattern '^source.html$' to uri 'source.html'
[rewrite:trace2] [rid#20b6200/initial] [perdir C:/Apache24/htdocs/rwtest/] rewrite 'source.html' -> 'target.html'
[rewrite:trace3] [rid#20b6200/initial] [perdir C:/Apache24/htdocs/rwtest/] add per-dir prefix: target.html -> C:/Apache24/htdocs/rwtest/target.html
[rewrite:trace2] [rid#20b6200/initial] [perdir C:/Apache24/htdocs/rwtest/] trying to replace prefix C:/Apache24/htdocs/rwtest/ with /rwtest
[rewrite:trace5] [rid#20b6200/initial] strip matching prefix: C:/Apache24/htdocs/rwtest/target.html -> target.html
[rewrite:trace4] [rid#20b6200/initial] add subst prefix: target.html -> /rwtest/target.html
[rewrite:trace1] [rid#20b6200/initial] [perdir C:/Apache24/htdocs/rwtest/] internal redirect with /rwtest/target.html [INTERNAL REDIRECT]
[rewrite:trace3] [rid#20ba360/initial/redir#1] [perdir C:/Apache24/htdocs/rwtest/] strip per-dir prefix: C:/Apache24/htdocs/rwtest/target.html -> target.html
[rewrite:trace3] [rid#20ba360/initial/redir#1] [perdir C:/Apache24/htdocs/rwtest/] applying pattern '^target.html$' to uri 'target.html'
[rewrite:trace2] [rid#20ba360/initial/redir#1] [perdir C:/Apache24/htdocs/rwtest/] forcing responsecode 403 for C:/Apache24/htdocs/rwtest/target.html
Workarounds
I've posted a few workarounds below.
There are several workarounds for this, each with their pros and cons. As a disclaimer, I've only tested them in an .htaccess context.
Workaround 1. Check for empty REDIRECT_STATUS
Add a RewriteCond checking to see if %{ENV:REDIRECT_STATUS} is empty. If it is empty, then the current request is not an internal redirect.
Pros
Most direct way to determine internal redirect.
Cons
Lack of documentation. The page on Custom Error Responses mentions this variable briefly:
REDIRECT_ environment variables are created from the environment variables which existed prior to the redirect. They are renamed with a REDIRECT_ prefix, i.e., HTTP_USER_AGENT becomes REDIRECT_HTTP_USER_AGENT. REDIRECT_URL, REDIRECT_STATUS, and REDIRECT_QUERY_STRING are guaranteed to be set, and the other headers will be set only if they existed prior to the error condition.
I've tried every other REDIRECT_ variable in RewriteCond, yet all of them except REDIRECT_STATUS were empty for internal redirects. Why REDIRECT_STATUS is the special one in mod_rewrite remains a mystery.
Example
# Forbid rule. Prohibit direct access to target.html.
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^target.html$ - [F]
# Rewrite rule. Rewrite source.html to target.html.
RewriteRule ^source.html$ target.html
Credits for this approach go to URL rewrite : internal server error.
Workaround 2. Halt rewrite rule processing with END
Unlike the L flag, END halts rewrite rules even for internal redirects.
Pros
Simple. Just an extra flag.
Cons
Does not give you enough control over which rules to process and which to skip.
Example
# Forbid rule. Prohibit direct access to target.html.
RewriteRule ^target.html$ - [F]
# Rewrite rule. Rewrite source.html to target.html.
RewriteRule ^source.html$ target.html [END]
For more information see END flag.
Workaround 3. Match against original URL in THE_REQUEST
%{THE_REQUEST}
The full HTTP request line sent by the browser to the server (e.g., "GET /index.html HTTP/1.1").
THE_REQUEST does not change with internal redirects, so you can match against it.
Pros
Can be used to match against the original URL even in the second round of URL processing.
Cons
Significantly more complicated than the other approaches. Forces the use of RewriteCond where just one RewriteRule would have been sufficient.
Matches against the full URL which has not been unescaped (decoded), unlike most other variables.
Inconvenient to use in multiple RewriteRules. RewriteConds can be copied above every RewriteRule or the value can be exported to an environment variable (see example). Both hacky alternatives.
Example
# Forbid rule. Prohibit direct access to target.html.
RewriteCond %{THE_REQUEST} "^[^ ]+ ([^ ?]*)" # extract path from request line
RewriteCond %1 ^/rwtest/target.html$
RewriteRule ^ - [F]
# Rewrite rule. Rewrite source.html to target.html.
RewriteRule ^source.html$ target.html
Or, export the path to an environment variable and use it in multiple RewriteRules.
# Extract the original URL and save it to ORIG_URL.
RewriteCond %{THE_REQUEST} "^[^ ]+ ([^ ?]*)" # extract path from request line
RewriteRule ^ - [E=ORIG_URL:%1]
# Forbid rule. Prohibit direct access to target.html.
RewriteCond %{ENV:ORIG_URL} ^/rwtest/target.html$
RewriteRule ^ - [F]
# Rewrite rule. Rewrite source.html to target.html.
RewriteCond %{ENV:ORIG_URL} ^/rwtest/source.html$
RewriteRule ^ target.html

Why doesn't the RewriteCond prevent the RewriteRule from processing?

I've got the following in my .conf file used for cache busting js:
<Directory "/www/virtual/site/html/js/">
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^\d+\/(.+)$ $1 [L]
</Directory>
The idea here is to rewrite site.com/js/123456/script.js to site.com/js/script.js
(The rewriting works just fine)
If I look at the rewrite log the part I'm not understanding is that it is applying the RewriteRule to the script after the interal redirect... Shouldn't the %{REQUEST_FILENAME} !-f prevent it from processing the RewriteRule since the file exists?
Rewrite Log
[rid#2b607f8f2dc8/initial] (3) [perdir /www/virtual/site2/html/js/] add path info postfix: /www/virtual/site2/html/js/1234 -> /www/virtual/site2/html/js/1234/script.js
[rid#2b607f8f2dc8/initial] (3) [perdir /www/virtual/site2/html/js/] strip per-dir prefix: /www/virtual/site2/html/js/1234/script.js -> 1234/script.js
[rid#2b607f8f2dc8/initial] (3) [perdir /www/virtual/site2/html/js/] applying pattern '^\d+\/(.+)$' to uri '1234/script.js'
[rid#2b607f8f2dc8/initial] (2) [perdir /www/virtual/site2/html/js/] rewrite '1234/script.js' -> 'script.js'
[rid#2b607f8f2dc8/initial] (3) [perdir /www/virtual/site2/html/js/] add per-dir prefix: script.js -> /www/virtual/site2/html/js/script.js
[rid#2b607f8f2dc8/initial] (2) [perdir /www/virtual/site2/html/js/] strip document_root prefix: /www/virtual/site2/html/js/script.js -> /js/script.js
[rid#2b607f8f2dc8/initial] (1) [perdir /www/virtual/site2/html/js/] internal redirect with /js/script.js [INTERNAL REDIRECT]
[rid#2b6073eb14a8/initial/redir#1] (3) [perdir /www/virtual/site2/html/js/] strip per-dir prefix: /www/virtual/site2/html/js/script.js -> script.js
[rid#2b6073eb14a8/initial/redir#1] (3) [perdir /www/virtual/site2/html/js/] applying pattern '^\d+\/(.+)$' to uri 'script.js'
[rid#2b6073eb14a8/initial/redir#1] (1) [perdir /www/virtual/site2/html/js/] pass through /www/virtual/site2/html/js/script.js
mod_rewrite (by design) keeps on applying rewrite-rules, till the url no longer changes.
So the first time it rewrite 1234/script.js to script.js the second time it tries to apply the rule, the pattern regular expression doesn't match and script.js is 'passed through'.
This is the way it is supposed to work. It can sometimes be a pain, but it makes mod_rewrite a lot more powerful/useful.
edit
mod_rewite first tests the RewriteRule pattern, before trying to apply the RewriteCond's. This is so you can use backreferences $0, $1 etc. in your RewriteCond. After all the RewriteCond's it will create the substitution string, so it can also use backrefereces %0, %1. etc. See also the diagram below.
So this is why it tried to apply the pattern before testing if the file exists.

Help understanding rewrite log (want to internally rewrite a page when requested from specific HTTP_HOST)

I have a Drupal site, site.com, and our client has a campaign that they're promoting for which they've bought a new domain name, campaign.com. I'd like it so that a request for campaign.com internally rewrites to a particular page of the Drupal site. Note Drupal uses an .htaccess file in the document root.
The normal Drupal rewrite is
# Rewrite URLs of the form 'x' to the form 'index.php?q=x'.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
I added the following before the normal rewrite.
# Custom URLS (eg. microsites) go here
RewriteCond %{HTTP_HOST} =campaign.com
RewriteCond %{REQUEST_URI} =/
RewriteRule ^ index.php?q=node/22 [L]
Unfortunately it doesn't work, it just shows the homepage. Turning on the rewrite log I get this.
1. [rid#2da8ea8/initial] (3) [perdir D:/wamp/www/] strip per-dir prefix: D:/wamp/www/ ->
2. [rid#2da8ea8/initial] (3) [perdir D:/wamp/www/] applying pattern '^' to uri ''
3. [rid#2da8ea8/initial] (2) [perdir D:/wamp/www/] rewrite '' -> 'index.php?q=node/22'
4. [rid#2da8ea8/initial] (3) split uri=index.php?q=node/22 -> uri=index.php, args=q=node/22
5. [rid#2da8ea8/initial] (3) [perdir D:/wamp/www/] add per-dir prefix: index.php -> D:/wamp/www/index.php
6. [rid#2da8ea8/initial] (2) [perdir D:/wamp/www/] strip document_root prefix: D:/wamp/www/index.php -> /index.php
7. [rid#2da8ea8/initial] (1) [perdir D:/wamp/www/] internal redirect with /index.php [INTERNAL REDIRECT]
8. [rid#2da7770/initial/redir#1] (3) [perdir D:/wamp/www/] strip per-dir prefix: D:/wamp/www/index.php -> index.php
9. [rid#2da7770/initial/redir#1] (3) [perdir D:/wamp/www/] applying pattern '^' to uri 'index.php'
10.[rid#2da7770/initial/redir#1] (3) [perdir D:/wamp/www/] strip per-dir prefix: D:/wamp/www/index.php -> index.php
11.[rid#2da7770/initial/redir#1] (3) [perdir D:/wamp/www/] applying pattern '^(.*)$' to uri 'index.php'
12.[rid#2da7770/initial/redir#1] (1) [perdir D:/wamp/www/] pass through D:/wamp/www/index.php
I'm not used to mod_rewrite, so I might be missing something, but comparing the logs from a call to http://site.com/node/3 and from http://campaign.com/ I can't see any meaningful difference. Specifically uri and args on line 4 seem correct, the internal redirect on line 7 seems right, and the pass through on line 12 seems right (because the file index.php exists). But for some reason it seems the query string's been discarded/ignored around the time of the internal redirect. I'm completely stumped.
Also, if anyone could provide a reference on understanding the rewrite log, that might help. It'd be great if there's a way to track the query string through the internal redirect.
FWIW I'm using WampServer 2.1 with Apache 2.2.17.
Thanks for asking this question, it's something that I need to do too. I don't know the way to do this by means of the .htaccess, and hope that someone here can answer that.
But I do the same thing by using Drupal's menu system with this code in a custom module:
function mymodule_menu() {
$items = array();
$items['domain_redirect'] = array(
'page callback' => 'domain_redirect',
'type' => MENU_NORMAL_ITEM,
'access arguments' => array('access content'),
);
return $items;
}
function domain_redirect() {
switch ($_SERVER['SERVER_NAME'])
{
case "campaign.com":
$goto = "node/22";
break;
default:
$goto = "/";
}
drupal_goto($goto);
}
Then set the frontpage to domain_redirect.