.htaccess rewrite not working if subdirectory also contains .htaccess file

Although I have been developing web pages for a few years (HTML, PHP, MYSQL), I am a novice using mod_rewrite. I have read several tutorials and many seem contradictory. I may be going about this all wrong so I am seeking guidance from someone with experience in this area.

I am having trouble with a redirect in my top level domain if a subdirectory also contains a .htaccess file.

To help explain, here is my directory structure.

www.domain1.com” points to directory /public_html

www.domain2.com” points to directory /public_html/domain2

My goal is to keep people from directly accessing directory domain2 using “http://www.domain1.com/domain2/” I want them to access it only by “http://www.domain2.com/

Here is the .htaccess file that I have placed in directory /public_html

RewriteEngine on
RewriteCond %{HTTP_HOST} ^domain1\\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\\.domain1\\.com$
RewriteRule ^domain2\\/?(.*)$  - [F]

If I do not have a .htaccess file in directory /public_html/domain2, then this works fine and properly displays the Forbidden error.

In directory /public_html/domain2 I also have the following .htaccess file:

RewriteEngine on
RewriteCond %{HTTP_HOST} ^domain2\\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\\.domain2\\.com$
RewriteRule ^forums\\/?(.*)$ http://forums.domain2.com/$1 [R=301,L]

I want users to be sent to “http://forums.domain2.com” when they enter “http://www.domain2.com/forums/” (this redirection works fine)

The problem I am encountering is when directory /public_html/domain2 contains a .htaccess file, then the rewrite rule in the .htaccess file in directory /public_html for domain “www.domain1.com” does not work (the page on the /domain2 directory is displayed when the desired result is to display the forbidden error).

I am running Apache 2.2.14.

Any assistance will be appreciated.

Steve

SS51,

The root of your problem is in understanding .htaccess and domains.

An .htaccess file is read (and parsed) ONLY if it is in the path to the requested file, thus, domain1’s .htaccess will NOT be read if domain2 is requested directly; it will be read if the request is domain1/domain2.

As for your forum.domain2, I don’t believe I’ve ever seen that setup on a host although it should be possible. May I assume that it’s DocumentRoot is domain1/domain2/forum?

Excellent: A statement of your goal!

My goal is to keep people from directly accessing directory domain2 using “http://www.domain1.com/domain2/” I want them to access it only by “http://www.domain2.com/

However, your code,

# .htaccess file that I have placed in directory /public_html
RewriteEngine on
RewriteCond %{HTTP_HOST} ^domain1\\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\\.domain1\\.com$
RewriteRule ^domain2\\/?(.*)$  - [F]

… is designed to KILL any request made via domain1, not redirect it via domain2 which

RewriteEngine on
RewriteRule ^domain2/(.*)$ http://domain2/$1 [R=301,L]

… would do.

Your stated goal is now met.

However, dealing with forum.domain2 may also require some treatment in domain2’s .htaccess. Please note that some hosts will make this impossible as they’ll parse the subdomain out and redirect to the subdirectory - ATTACK your host if they do this to you!

To ensure that the forum subdomain is used rather than the domain2/forum,

# .htaccess in domain2
RewriteEngine on
RewriteRule ^forum/(.*)$ http://forum.domain2/$1 [R=301,L]
# This assumes that you have a good/cooperative host

Finally, two comments on optimizing your coding

RewriteEngine on
RewriteCond %{HTTP_HOST} ^domain2\\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\\.domain2\\.com$
RewriteRule ^forums\\/?(.*)$ http://forums.domain2.com/$1 [R=301,L]
  1. Because I’ve already shown code (above) which does not use either of the RewriteCond statements, you should know that they’re not necessary (i.e., should be removed) and

  2. If you did need the two RewriteCond’s, combine them by making the www. optional, i.e.,

RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www\\.)?domain2\\.com$
RewriteRule ^forums\\/?(.*)$ http://forums.domain2.com/$1 [R=301,L]

Regards,

DK

dklynn,

Thank you very much for your detailed reply. I actually have two goals but I did not do a very good job of explaining them. I would be glad to provide real domain names pointing to real web pages, but I am unsure if that is acceptable on this board. I apologize if I attempt to provide too many details.

Some information:

If a user navigates to “http://www.domain1.com/” the files in folder “/home/myaccount/public_html/” will be viewed (This is the top level folder for html. All other domains are sub-folders of this directory).

If a user navigates to “http://www.domain2.com/” the files in folder “/home/myaccount/public_html/domain2/” will be viewed.

If a user navigates to “http://www.domain1.com/domain2/” the files in folder “/home/myaccount/public_html/domain2/” will also be viewed.

If a user navigates to “http://forums.domain2.com/” the files in folder “/home/myaccount/public_html/domain2/forums/” will be viewed.

If a user navigates to “http://www.domain2.com/forums/” the files in folder “/home/myaccount/public_html/domain2/forums/” will also be viewed.


Goal 1:

If a users navigates to “http://www.domain2.com/forums/”, I want them redirected to “http://forums.domain2.com/”. In folder “/home/myaccount/public_html/domain2/” I have placed the following .htaccess file and it works as desired (although at your suggestion, I will remove the unnecessary lines).


RewriteEngine on
RewriteCond %{HTTP_HOST} ^domain2\\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\\.domain2\\.com$
RewriteRule ^forums\\/?(.*)$ http://forums.domain2.com/$1 [R=301,L]


Goal 2:

If a user navigates to “http://www.domain1.com/domain2/” I want them to receive the forbidden error. The good guys (members of the club) know the proper URL. The bad guys use “http://www.domain1.com/domain2/”. The only acceptable way to get to directory “/home/myaccount/public_html/domain2/” is to navigate to “http://www.domain2.com/”. I want this so I can keep my statistics accurate. If they navigate to “http://www.domain1.com/domain2/” then this access is listed in the domain1 log instead of the domain2 log. In folder “/home/myaccount/public_html/” I have placed the following .htaccess file


RewriteEngine on
RewriteCond %{HTTP_HOST} ^domain1\\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\\.domain1\\.com$
RewriteRule ^domain2\\/?(.*)$  - [F]

This part works properly if the .htaccess file associated with Goal 1 is not present in folder “/home/myaccount/public_html/domain2/”. As soon as the Goal 1 .htaccess file is added, the user no longer receives the forbidden error.


There must be some interaction between the two .htaccess files that is causing the problem or else I am violating some apache rule.

Again - Thanks for the assistance.

Steve

SS51,

No problem.

The real domain names are not necessary.

Regards,

DK

dklynn,

Again - Thanks for your reply. At this point, I’m ready to give up on this. For goal #2 (from domain 1) I attempted to forward to another site instead of using F (forbidden) and it still will not work if there is anything in the .htaccess file for domain2. In domain2 I changed the .htaccess file to just

RewriteEngine on

(literally one line in the file and no Rewrite Rules) and it (goal #2) still did not work. When I changed the .htaccess file in domain2 to

##RewriteEngine on

(everything commented out) then goal #2 worked properly and redirected to another site.

I don’t expect any more assistance on this, but if anyone gets really bored some afternoon, they may want to simulate this scenario just to see what happens.

All of my testing has been on my local computer running Apache. I never send anything to the live server until it is proven out on my local server. Possibly there is some setting on my local server that is causing this.

Hopefully, in the future I’ll be able to answer some questions on this forum instead of just asking them.

Steve

SS51,

If I have to guess, your host is trying to do you a favor (with Apache’s settings - nothing personal) by attempting to connect to the subdomain (probably via mod_alias) before allowing mod_rewrite to do its work. If this is the case, I’d modify domain2’s .htaccess to include a look at Apache’s {THE_REQUEST} variable (which includes HTTP Protocol, the ORIGINAL {REQUEST_URI} and the GET/POST) and, if domain2 is in %{THE_REQUEST}, fail it right then and there with … aw:

# .htaccess in domain2 addition (right after RewriteEngine on)
RewriteCond %{THE_REQUEST} domain2
RewriteRule .? - [F]

There may be a better way to do it but the power of mod_rewrite can shine through whatever nonsense is going on with your server.

Regards,

DK

Success - That worked great on my local server. Now to test it on the production server.

Looking on the bright side of these difficulties, I now have a much better understanding of mod_rewrite.

Thanks again,
Steve

:tup:

Regards,

DK



Options -Indexes +FollowSymLinks

<IfModule mod_rewrite.c>

RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^www\\.domain1\\.com
RewriteCond %{REQUEST_URI} ^/domain2 [NC]
RewriteRule . / [R=301,L]

</IfModule>



Edward,

OMG, NO!

# Those are core directives where -Indexes prohibits directory listings and
# +FollowSymLinks helps to enable mod_rewrite (and is something which should be in the httpd.conf, not in .htaccess

[COLOR="#FF0000"]<IfModule mod_rewrite.c>[/COLOR]
# A MAJOR abuse of the server! So bad, in fact, that I had to create a standard rant for it:
# [rant #4][indent]The definition of an idiot is someone who repeatedly does the same thing expecting a different result.  Asking Apache to confirm the existence of ANY module with an <IfModule> ... </IfModule> wrapper is the same thing in the webmaster world.  DON'T BE AN IDIOT!  If you don't know whether a module is enabled, run the test ONCE then REMOVE the wrapper as it is EXTREMELY wasteful of Apache's resources (and should NEVER be allowed on a shared server).[/indent][/rant 4]

RewriteEngine On

[COLOR="#FF0000"]RewriteBase /[/COLOR]
# Another no-no as this is designed to undo a mod_alias redirection before handoff to mod_rewrite
# Where is your Redirect statement?

RewriteCond %{HTTP_HOST} ^www\\.domain1\\.com [COLOR="#0000FF"][NC][/COLOR]
# No Case flag is required else DoMaIn.CoM will not be matched (and it IS legal; the host is not case sensitive)
RewriteCond %{REQUEST_URI} ^[COLOR="#FF0000"]/[/COLOR]domain2 [COLOR="#FF0000"][NC][/COLOR]
# leading / is only matched by Apache 1.x servers
# {REQUEST_URI} variables are case sensitive so you got these backward
[COLOR="#FFA07A"]RewriteRule . / [R=301,L][/COLOR]
# redirect EVERYTHING to the DirectoryIndex of the root?

[COLOR="#FF0000"]</IfModule>[/COLOR]

Sorry to “go off” on you like that but I do get pedantic when I see errors in code. It’s not personal (I don’t know you), it’s to help you as well as prevent other members from making the same errors (or using your code).

Regards,

DK