Forum Moderators: phranque

Message Too Old, No Replies

Return of bidirectional URL rewriting problem

.htaccess file at a lower level kills it for some reason

         

MichaelBluejay

11:12 pm on Aug 25, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



A while back I posted abouting needing a solution to this problem:

<http://domain.com/topic> should load the content stored at </domain.com/subdir/topic.html>, but still show <http://domain.com/topic> in the address bar.

And at the same time:

<http://domain.com/subdir/topic.html> should change to <http://domain.com/topic> in the address bar.

The problem is that each directs to the other so there would be a loop. jdMorgan proposed the following solution which worked initially. This is what I have in my </.htaccess> file:

# REWRITE REQUESTS FOR THE SUBDIR
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /subdir/topic\.html
RewriteRule subdir/topic\.html [domain.com...] [R=301,L]

# REWRITE REQUESTS FOR THE SHORTCUT
RewriteRule ^topic$http://domain.com/subdir/topic.html [L]

But now when I go to <http://domain.com/subdir/topic.html>, the page loads but the address bar doesn't change.

After a lot of troubleshooting I found that I could get it to work if I removed the secondary htaccess file at </subdir/.htaccess>. Exploring further I discovered that what killed it was having even a single RewriteRule command in that secondary .htaccess file, *even if that command had nothing to do with the request*. For example, this line in the secondary .htaccess file kills the whole deal:

RewriteRule apx [domain.com...] [R=301,L]

Incidentally, the reason I have a second .htaccess file is that I'm trying to improve performance. When I want to run certain rewriting code only for requests to a specific folder, I like to put the .htaccess file in that folder so the rewriting code doesn't have to get evaluated for requests to other directories.

So, the burning question is: Is there any way to get my URL rewriting to work when I have a secondary .htaccess file that contains RewriteRule commands? Thanks for your help.

jdMorgan

1:56 am on Aug 26, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



See the RewriteOptions inherit directive -- I suspect that's what you need.

Jim

MichaelBluejay

2:54 am on Aug 26, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I'm not sure why RewriteOptions inherit would be necessary, because I don't really need the /subdir/to inherit anything, since by the time the /subdir/ sees the request all the rewriting has already been done. But of course I tried adding RewriteOptions inherit[/] before the RewriteCond in that secondary .htaccess file, but it didn't solve the problem.

Also, not sure if this is expected behavior, but if I put [i]RewriteEngine on before RewriteOptions inherit then I get an Internal Server Error. If I leave RewriteEngine on out completely then the RewriteRule in that secondary .htaccess file executes fine, but I still have the original problem with the url not being rewritten to remove /subdir/ from the address bar.

I hope I haven't stumped jdMorgan, because otherwise I don't know who else would be able to figure this one out....

jdMorgan

3:12 am on Aug 26, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Maybe because the following line (which is missing a space, BTW) creates a 302 redirect by default:

# REWRITE REQUESTS FOR THE SHORTCUT
RewriteRule ^topic$http://domain.com/subdir/topic.html [L]

This "undoes" the first rule, and 302's can cause problems in the SERPs. See the RewriteRule documentation for more info.

The proper form for an internal (silent) rewrite is:


# REWRITE REQUESTS FOR THE SHORTCUT
RewriteRule ^topic$ /subdir/topic.html [L]

(No protocol or domain should be used for internal rewrites.)

Jim

MichaelBluejay

1:29 am on Aug 27, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



The missing space was a typo, sort of. I use tabs in my .htaccess file. When I pasted my code into my forum post it didn't come acress. There's definitely whitespace in the original.

I also took out the protocol and domain from my RewriteRules. Same problem: </subdir/topic> does not rewrite to </topic> if </subdir/.htaccess> contains even a single, unrelated Rewrite command.

This is sure crazy.

jd01

2:06 am on Aug 27, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Did you try RewriteOptions inherit *after* you corrected your rule?

Primary .hatccess:
# REWRITE REQUESTS FOR THE SUBDIR
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /subdir/topic\.html
RewriteRule subdir/topic\.html http://domain.com/topic [R=301,L]

# REWRITE REQUESTS FOR THE SHORTCUT
RewriteRule ^topic$ /subdir/topic.html [L]

Secondary .htaccess:

RewriteEngine on
RewriteOptions inherit
RewriteRule apx http://domain.com/topic2/appendix.html [R=301,L]

You correctly received a 500 error when this was added before, because the rewrite from the original *was* inherited, and the inherited rule caused an external (original request) redirect (matching THE_REQUEST), which was then rewritten in the main .htaccess to the new URL, which was then redirected externally (original request) in the secondary (inherited) rewrite, over and over and over...

The reason your rewrite does not work without inherit, is even though the .htaccess does not specifically mention the location you are redirecting, the secondary .htaccess overrides all previous .htaccess files *unless* the options are set to inherit somewhere, either in a per directory location or at the server root...

Added: So, unless you were to explicitly rewrite the location in the secondary .htaccess, no rewrite will be processed, because the first .htaccess file effectively does not exist, eliminating the original rule.

Hope this helps.

Justin

MichaelBluejay

2:44 am on Aug 27, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Justin, I'm afraid I don't understand what you're saying.

What do you mean "after you corrected your rule"? Corrected how? What was there to correct? Adding the space? (Like I said, there's always been a space there, it just didn't show up in the post.) Removing the method and domain from the RewriteRule? Your own code includes the method and domain. In any event I removed the method and domain and tried it with RewriteOptions Inherit but I still have the same problem.

About your "Added:" comment, are you saying that it's impossible to get this to work unless I duplicate the Rewrite command in the secondary .htaccess file? Meaning that it works fine as long as the secondary htaccess file contains no Rewrite commands, but as soon as it includes *any* Rewrite command, then I have to duplicate the Rewrite commands from the primary htaccess file?

jd01

2:56 am on Aug 27, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



RewriteRule ^topic$ /subdir/topic.html [L]

The above rule is the one I was referring to... In the main .htaccess.

I have to duplicate the Rewrite commands from the primary htaccess file?

You either have to have the options inherit, or duplicate the rules, no other way around it. If the rewrite does not work when there is any information in the secondary .htaccess the option is set to off, IOW will not inherit - If you cannot get the inherit to work, yes, you will have to duplicate (or move) the rule.

Justin

jdMorgan

3:29 am on Aug 27, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Instead of duplicating them, I'd vote to move all the rules which can interact with each other to the Web root .htaccess file, where you can make them play nice with each other, while leaving the inherit option enabled in any subdirectories where you use .htaccess and also need the rules in the root .htaccess to apply.

Jim

MichaelBluejay

3:58 am on Aug 27, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Now I'm *really* confused.

jdMorgan, I thought that what you're advising is exactly what I'm trying to do, which doesn't work. What is different about what you're suggesting?

After some more tinkering, this seems to work:

In the root .htaccess file
RewriteEngine On
RewriteRule topic$ /subdir/topic.html [L]

In the subdir's .htaccess file
RewriteEngine on
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /subdir/topic\.html
RewriteRule topic\.html /topic [R=301,L]

Is there any reason I shouldn't proceed with this?

jdMorgan

4:43 am on Aug 27, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



You can't argue with successful test results.

The only change I'd make is to use a canonical substitution URL in redirects (not rewrites), and to anchor the patterns where possible:

In the subdir's .htaccess file


RewriteEngine on
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /subdir/topic\.html
RewriteRule ^topic\.html$ http://%{HTTP_HOST}/topic [R=301,L]

You could also use "http://www.example.com/topic [R=301,L]" in the rule substitution -- hard-coding your domain name instead.

Jim

MichaelBluejay

9:58 am on Aug 27, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Okay, I'll anchor the patterns.

What does "canonical" mean?

I'm not sure I understand why it's necessary to specify the method and host if it works okay without specifying it?

jdMorgan

3:47 pm on Aug 27, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



> if it works okay without specifying it?

Because it's documented that way...

Canonical [google.com]; here meaning "the generally-accepted, standard form" for a complete URL.

Jim

jd01

6:55 pm on Aug 27, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Here is the webopedia - computer use definition:

When referring to programming, canonical means conforming to well-established patterns or rules. The term is typically used to describe whether or not a programming interface follows the already established standard.

SOURCE: webopedia.com

jdMorgan gave you the plain english answer to his statement - here is another version of what he said: 'to use a [well-established pattern, which follows the already established standard] of substitution URL in redirects (not rewrites), and to anchor the patterns where possible:'

Hope you get everything working.

Justin

MichaelBluejay

9:43 pm on Aug 27, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Okay, thanks. Everything has already been working since a post or two ago, so I think I'm all set. And I'm even happier since I was able to offload much of the code to the subdir's .htacess file from the root .htaccess file, which I hope will slightly increase performance on requests for files not in the subdir. It certainly makes the code a lot easier to maintain, because there's not just one "topic", there are dozens of them.

Thanks again for your help, both of you.