301 Redirects and RewriteCond - non-www to www

Topics: Developer Forum, User Forum
Dec 11, 2009 at 5:02 PM

First of all thanks for such a great component. I recently started working for a company where just about everything is Windows and I'm more used to Linux. I've had to implement some things in order take advantage of such things as rewrite rules and conditions and this component has made this possible, in most cases. 

Before I get started let me say that I think I've tried out every example in the documentation and the thing I'm trying to get to work does not.

Initially the request was to have a redirect go from one sub domain to another, passing all query strings with it. This was accomplished by the following rule:

RedirectRule ^/(.*)$ http://www.subdomain.domain.com$1

Now however I need to account for non-www and www requests and this doesn't seem to work no matter what I try. I added this rewrite condition which also didn't work:

RewriteCond %{HTTP_HOST} ^(www\.subdomain\.domain\.com).*$ [I]

I've also tried working rewritecond rules from .htaccess files I'm using on a unix box, and those don't work either. I'm rather certain it's a syntax problem, because I've seen various examples in the documentation and other sites I've come across that shows similar working examples.

So, to sum it up this is what I'm trying to accomplish:

Orginal URL: http://www.subdomain.domain.com >> http://www.subdomain2.domain.com

Currently this is working:

Original URL: http://subdomain.domain.com >> http://www.subdomain2.domain.com

I've tried changing the RewriteCond to include any domain variation, the exact domain, etc but everytime it results in www just going back to www.

I also tried out the code examples in this thread, but I'm not sure whether the subdomains are somehow keeping things from working on my end.

Any help here would be greatly appreciated, I've been chompin' at the bit for quite a while on this now ;)

Thanks,

Alex

 

 

 

<input id="gwProxy" type="hidden" /><input id="jsProxy" onclick="jsCall();" type="hidden" />

Coordinator
Dec 11, 2009 at 9:23 PM

What you want to do seems pretty straightforward.

This is what I would try:  

RewriteCond %{HTTP_HOST} ^(www\.)?subdomain\.domain\.com$ [I]
RedirectRule ^/(.*)$   http://www.subdomain2.domain.com/$1

English translation: The RedirectRule is pretty simple. Redirect anything to subdomain2. But the redirect is conditional, it depends on a single RewriteCond. The RewriteCond compares the HTTP_HOST server variable to the given pattern. The pattern matches a string that maybe starts with www., and then follows with subdomain.domain.com . [The maybe is the question mark following the (www\.).  In regex, a question mark is a "zero or one" quantifier.]   Both www.subdomain2.domain.com and subdomain2.domain.com will match that pattern.

Dec 11, 2009 at 9:55 PM

Cheeso! HUGE thanks for this quick reply - I don't have to tell you how frustrating it can be sometimes when you're struggling with something like this and nothing motivates more than having someone like you so willing to help. 

I tried your code just as you posted it, however when I type in: www.subdomain.domain.com it just stays there - so it successfully 'rewrites', but nothing gets redirected after that (if I understand this correctly)

Here's my ini in its entirety, maybe I'm missing something obvious: 

 

# IsapiRewrite4.ini
# ini file for the ISAPI rewriter. 

# log level
RewriteLogLevel 4

# log location
RewriteLogFile c:\temp-iirf\iirf

RewriteEngine ON

RewriteCond %{HTTP_HOST} ^(www\.)?subdomain\.domain\.com$ [I]
RedirectRule ^/(.*)$ http://www.subdomain2.domain.com$1

Results: 

www.subdomain.domain.com > no redirect

subdomain.domain.com > successful redirect to http://www.subdomain2.domain.com

Is there any way that I have some global setting which is keeping this from working? 

Thanks again for time and efforts on all this. 

 

 

Dec 11, 2009 at 10:30 PM

Can you copy and past the relevant part of you log file?

 

Coordinator
Dec 12, 2009 at 2:46 AM
Edited Dec 12, 2009 at 10:39 PM

yep, good idea Ryan,  the log file might show what is happening.

Also if you like you can try a Fiddler trace - it can be helpful in visualizing the HTTP transaction flow back-and-forth.  Fiddler is a free tool, a plugin to IE.  It lets you look at the messages that get sent from the browser, and received by the browser. In the case of a Redirect, you should see an HTTP 301 response code. In your case (no redirect), I don't know what it is doing but Fiddler might give you a hint. If you run firefox, there's a different plugin you can use, but I don't know what it is. (actually Fiddler will trace firefox traffic just as it traces IE traffic, but Fiddler is easily launchable from IE.  I'm not sure it is similarly launchable from FF).

Is it possible that www.subdomain.domain.com is not pointing to the same server as subdomain.domain.com?   If that were true then, the request sent to www.subdomain.domain.com would never arrive an the IIS, or the IIRF.

Dec 12, 2009 at 10:17 PM

ryandohara & Cheeso - thanks for your help on this.

1. Cheeso - that's a very valid question. I'm setting up all these redirects for a client and usually I just get told which domain to redirect from and it definitely can't be ruled out that the client doesn't have the domain setup properly - if they for example don't have the A records setup correctly, www and non-www might be handled differently.

2. Here are the logs - I entered subdomain.domain.com and www.subdomain.domain.com and this should be the direct output:

Sat Dec 12 17:05:38 -  1672 - -------------------------------------------------------
Sat Dec 12 17:05:38 -  1672 - Ionic ISAPI Rewriting Filter (IIRF) 2.0.1.1010 RELEASE
Sat Dec 12 17:05:38 -  1672 - IIRF was built on: Nov  9 2009 16:47:48
Sat Dec 12 17:05:38 -  1672 - Cached: DLL_PROCESS_ATTACH
Sat Dec 12 17:05:38 -  1672 - Cached: Process ID: 4608
Sat Dec 12 17:05:38 -  1672 - Cached: ReadServerConfig: Could not open ini file 'C:\Windows\System32\inetsrv\IIRF\IirfGlobal.ini' (error: 2)
Sat Dec 12 17:05:38 -  1672 - Cached: DLL_PROCESS_ATTACH - complete
Sat Dec 12 17:05:38 -  1672 - Cached: GetFilterVersion
Sat Dec 12 17:05:38 -  1672 - GetLogFile: app:'/LM/W3SVC/51/ROOT'  new log:'c:\temp-iirf\iirf.4608.log'
Sat Dec 12 17:05:38 -  1672 - ReadSiteConfig: actual log file 'c:\temp-iirf\iirf.4608.log'
Sat Dec 12 17:05:38 -  1672 - ReadSiteConfig: ini file: 'C:\websites\subdomain.domain.com\Iirf.ini'
Sat Dec 12 17:05:38 -  1672 - ReadSiteConfig: ini file timestamp: 2009/12/11 16:50:39 Eastern Standard Time
Sat Dec 12 17:05:38 -  1672 - ReadSiteConfig: pass 1
Sat Dec 12 17:05:38 -  1672 - ReadSiteConfig: line  12: RewriteCond   %{HTTP_HOST}  ^(www\.)?subdomain\.domain\.com$
Sat Dec 12 17:05:38 -  1672 - ParseCondModifierFlags: '[I]'
Sat Dec 12 17:05:38 -  1672 - ReadSiteConfig: line  14: RedirectRule (rule 1)  '^/(.*)$'  'http://www.subdomain2.domain.com$1'   (null)
Sat Dec 12 17:05:38 -  1672 - ReadSiteConfig: Done reading, found 1 rules (0 errors, 0 warnings) on 16 lines
Sat Dec 12 17:05:38 -  1672 - GetSiteConfig: Obtain  site '/LM/W3SVC/51/ROOT' (era=0) (rc=1) (Expired=0) (ptr=0x01E72E40)...
Sat Dec 12 17:05:38 -  1672 - HttpFilterProc: SF_NOTIFY_URL_MAP
Sat Dec 12 17:05:38 -  1672 - HttpFilterProc: cfg= 0x01E72E40
Sat Dec 12 17:05:38 -  1672 - HttpFilterProc: SF_NOTIFY_AUTH_COMPLETE
Sat Dec 12 17:05:38 -  1672 - DoRewrites
Sat Dec 12 17:05:38 -  1672 - GetHeader_AutoFree: 'url' = '/'
Sat Dec 12 17:05:38 -  1672 - GetHeader_AutoFree: 'method' = 'GET'
Sat Dec 12 17:05:38 -  1672 - DoRewrites: New Url, before decoding: '/' 
Sat Dec 12 17:05:38 -  1672 - DoRewrites: Url (no decoding): '/'
Sat Dec 12 17:05:38 -  1672 - EvaluateRules: depth=0
Sat Dec 12 17:05:38 -  1672 - EvaluateRules: Rule 1 : 2 matches
Sat Dec 12 17:05:38 -  1672 - ReplaceServerVariables: in='%{HTTP_HOST}' out='subdomain.domain.com'
Sat Dec 12 17:05:38 -  1672 - GenerateReplacementString: result 'subdomain.domain.com'
Sat Dec 12 17:05:38 -  1672 - EvalCondition: Cond %{HTTP_HOST} ^(www\.)?subdomain\.domain\.com$ => TRUE
Sat Dec 12 17:05:38 -  1672 - EvalConditionList: rule 1, TRUE, Rule will apply
Sat Dec 12 17:05:38 -  1672 - ReplaceServerVariables: in='http://www.subdomain2.domain.com$1' out='http://www.subdomain2.domain.com$1'
Sat Dec 12 17:05:38 -  1672 - GenerateReplacementString: result 'http://www.subdomain2.domain.com$1'
Sat Dec 12 17:05:38 -  1672 - EvaluateRules: Result (length 67): http://www.subdomain2.domain.com$1
Sat Dec 12 17:05:38 -  1672 - EvaluateRules: returning 1302
Sat Dec 12 17:05:38 -  1672 - DoRewrites: Redirect (code=302) Url to: 'http://www.subdomain2.domain.com$1'
Sat Dec 12 17:05:38 -  1672 - HttpFilterProc: SF_NOTIFY_LOG
Sat Dec 12 17:05:38 -  1672 - ReleaseOrExpireSiteConfig: site '/LM/W3SVC/51/ROOT' (era=0) (rc=0) (Expired=0) (ptr=0x01E72E40)...

Thanks again for your help guys.

 

<input id="gwProxy" type="hidden" /><input id="jsProxy" onclick="jsCall();" type="hidden" />

Coordinator
Dec 12, 2009 at 10:52 PM

Ryan, I see only one request being handled by IIRF.

I don't see the request for www.subdomain.domain.com.  That means IIRF is never receiving it, which means the IIS for which IIRF is configured is never receiving it. 
Check the A records?

You can also check  - in a Windows Server the www.subdomain.domain.com name might be mapped to its own distinct website, and :

  • IIRF may not be configured for that site, in which case you will get no rewrites.
  • or, IIRF may be configured, but IIS is running as a separate worker process, in which case, there will be a separate IIRF log file.  (There will be one IIRF log file generated per IIS worker process).

[ IIRF, like all ISAPI filters, can be configured at the server level, or at the site level. ]

 

Dec 12, 2009 at 11:09 PM

I installed/ran fiddler and it confirms that no redirect occurs. I'll have to check with the client and get access to their zone file to see what's going on here.

Not sure what you mean with your second bullet point

IIRF may be configured, but IIS is running as a separate worker process, in which case, there will be a separate IIRF log file.  (There will be one IIRF log file generated per IIS worker process).

As I stated initially, I'm very much a unix guy trying to make my way around this windows world - can you elaborate on that point above? I have tons of log files here and new segments (sep. files) seem to be created all the time - not sure if that proves whether we're dealing with separate log files per IIS worker process or not.

Oh, and I'm pretty sure that IIRF is installed on a server level - or at least at some kind of 'parent' level - when I create a new site in IIS and I check in the filter section, IIRF shows up without me having to add it...

 

 

 

<input id="gwProxy" type="hidden" /><input id="jsProxy" onclick="jsCall();" type="hidden" />

Coordinator
Dec 12, 2009 at 11:57 PM

There's a concept in IIS called "website" , which gets a port assigned to it.  Most servers use a single website listening on port 80, but some use multiple websites listening on multiple distinct ports.  IIS allows that.  And within IIS, you can install an ISAPI filter (like an apache module) once for the server ( == all websites), or you can install a filter independently on one or more websites. 

if one of the websites is listening at a different port, normally external users would have to specify the port in the UrL.  Unless, of course, there's some front-end networking gear that intercepts the request for www.subdomain.domain.com and forwards it to port 88 on your server, for example.   The implication is, www.subdomain.domain.com could be using IIS on your server, with a different port than is evident from the external requestors. 

But based on  your description, it seems like you have IIRF on at the server level, so this is all probably moot. 

The number of logfiles doesn't prove you're working with separate websites.  IIS in v6 and later uses multiple worker processes for each site, so ... even with the same site, you could get multiple worker processes with consecutive requests submitted within 10 seconds of each other.

You can look at the timestamp of the IIRF logfiles to see which ones are "current".  you can also use Task Manager to see how many instances of w3wp.exe are running. Each one is a worker process (w3wp = www worker process).  And each one will generate a distinct IIRF logfile, if IIRF is configured for the website that the w3wp is running on behalf of.

So I would check those two things

Dec 14, 2009 at 3:22 PM

Cheeso - we need more of you :)

I just posted ONE log file's output that pertained to the domain in question. I see various "w3wp.exe's" running in task manager.

I ran nslookup on the primary domain, and the subdomain I'm working with, and their IP addresses differ:

# nslookup -all subdomain.domain.com

Set options:
  novc                  nodebug         nod2
  search                recurse
  timeout = 0           retry = 3       port = 53
  querytype = A         class = IN
  srchlist =
Server:         192.168.1.1
Address:        192.168.1.1#53

Non-authoritative answer:
Name:   holidays.kaplan.edu
Address: xx.xxx.xx.229
# nslookup -all domain.com

Set options:
  novc                  nodebug         nod2
  search                recurse
  timeout = 0           retry = 3       port = 53
  querytype = A         class = IN
  srchlist =
Server:         192.168.1.1
Address:        192.168.1.1#53

Non-authoritative answer:
Name:   domain.com
Address: xx.xxx.xx.37

In theory I would just ask for the client's zone records, but I need to make 1000000% sure I don't make a rear end of myself, so I'm trying to test everything I can. I'll see if I can run some more conclusive tests...