mod_rewrite Question

"Please leave a message at the beep, we will get back to you when your support contract expires."

Moderators: phlip, Moderators General, Prelates

fagricipni
Posts: 34
Joined: Thu Nov 04, 2010 7:32 pm UTC

mod_rewrite Question

Postby fagricipni » Mon Aug 01, 2016 5:59 pm UTC

I have the following in my .htaccess file:

RewriteEngine On
RewriteBase /

# www to bare
RewriteCond %{HTTP_HOST} ^www.fagricipni.com [NC]
RewriteRule ^(.*)$ http://fagricipni.com/$1 [R=301]

# redirect to new lojban location
RewriteRule ^lojban/about(.*)/?$ /library/reference/lojban/$1 [R=301]

# renamed files
RewriteRule ^library/reference/radioactive_eqns.html$ http://fagricipni.com/library/reference/radioactive-equations.html [R=301,L]
RewriteRule ^library/reference/lojban/lojban1_draft1.html$ http://fagricipni.com/library/reference/lojban/grammar-draft-unfinished.html [R=301,L]

The question that I have is that from what I saw when I tested retrieving http://www.fagricipni.com/lojban/about/lojban1_draft1.html , there appeared to be three 301 redirects: first to http://fagricipni.com/lojban/about/lojban1_draft1.html , then to http://fagricipni.com/library/reference/lojban/lojban1_draft1.html, then finally to http://fagricipni.com/library/reference/lojban/grammar-draft-unfinished.html . Now, while this does redirect the first address (http://www.fagricipni.com/lojban/about/lojban1_draft1.html ) to the intended last address (http://fagricipni.com/library/reference/lojban/grammar-draft-unfinished.html ); my readings on mod_rewrite led me to believe that the rules were applied one after another server-side, until a rule ending with an L flag was triggered, but if that were true, then it seems to me that only one 301 redirect would occur in this case: When asked for http://www.fagricipni.com/lojban/about/lojban1_draft1.html : the server would test the first rule, find that it matched and apply it yielding a new address, to which the second rule would be tested against found to match and be applied yielding a new address, to which the third rule would be tested against found to fail and thus be skipped, and then finally the fourth rule would be tested against the address found to match and be applied, and since the server applied a rewrite rule with an [L] flag, no more rewriting would take place. This whole process should lead to one 301 redirect being given to the client: http://www.fagricipni.com/lojban/about/lojban1_draft1.html to http://fagricipni.com/library/reference/lojban/grammar-draft-unfinished.html directly.

From where I am browsing any extra delay from two more communications with the server causes no perceptible effect, but it seems to me that one shouldn't assume this to be true for all users. And if one should, I still want to know what I have done wrong, or understood wrong.

User avatar
Flumble
Yes Man
Posts: 1938
Joined: Sun Aug 05, 2012 9:35 pm UTC

Re: mod_rewrite Question

Postby Flumble » Mon Aug 01, 2016 6:48 pm UTC

Weird, even the documentation specifically says R does not imply L, so use it in conjunction with L unless you know what you're doing.
What happens if you add the N flag to those rules?

fagricipni
Posts: 34
Joined: Thu Nov 04, 2010 7:32 pm UTC

Re: mod_rewrite Question

Postby fagricipni » Mon Aug 01, 2016 10:29 pm UTC

I must have changed this rule after testing

# redirect to new lojban location
RewriteRule ^lojban/about(.*)/?$ /library/reference/lojban/$1 [R=301]

because I don't get exactly the behavior I described unless the rule is changed to read

# redirect to new lojban location
RewriteRule ^lojban/about/?(.*)$ /library/reference/lojban/$1 [R=301]

Note the move of "/?" in the rewrite condition.

However, using [R=301,N] doesn't seem to help: indeed it makes things worse. This

RewriteEngine On
RewriteBase /

# www to bare
RewriteCond %{HTTP_HOST} ^www.fagricipni.com [NC]
RewriteRule ^(.*)$ http://fagricipni.com/$1 [R=301,N]

# redirect to new lojban location
RewriteRule ^lojban/about/?(.*)$ /library/reference/lojban/$1 [R=301,N]

# renamed files
RewriteRule ^library/reference/radioactive_eqns.html$ http://fagricipni.com/library/reference/radioactive-equations.html [R=301,L]
RewriteRule ^library/reference/lojban/lojban1_draft1.html$ http://fagricipni.com/library/reference/lojban/grammar-draft-unfinished.html [R=301,L]

causes an apparent infinite loop when fed http://www.fagricipni.com/lojban/about/lojban1_draft1.html , at least curl -i http://www.fagricipni.com/lojban/about/lojban1_draft1.html seems to hang for a while then finally gives a message: curl: (52) Empty reply from server .

And http://fagricipni.com/lojban/about/lojban1_draft1.html continues to 301 redirect to http://fagricipni.com/library/reference/lojban/lojban1_draft1.html .

ETA: I also checked the version of apache; it is 1.3.42 .

User avatar
chridd
Has a vermicelli title
Posts: 753
Joined: Tue Aug 19, 2008 10:07 am UTC
Location: ...Earth, I guess?
Contact:

Re: mod_rewrite Question

Postby chridd » Tue Aug 02, 2016 6:42 am UTC

After an [R] rule, the location it's matching against is the absolute URL rather than just the path. So...

Code: Select all

# Request: http://www.fagricipni.com/lojban/about/lojban1_draft1.html
# Current path: lojban/about/lojban1_draft1.html
RewriteEngine On
RewriteBase /

# www to bare
RewriteCond %{HTTP_HOST} ^www.fagricipni.com [NC]
RewriteRule ^(.*)$ http://fagricipni.com/$1 [R=301]
# new path: http://fagricipni.com/lojban/about/lojban1_draft1.html

# redirect to new lojban location
RewriteRule ^lojban/about(.*)/?$ /library/reference/lojban/$1 [R=301]
# this rule doesn't match since http://fagricipni.com/lojban/about/lojban1_draft1.html doesn't start with lojban/about

# renamed files
RewriteRule ^library/reference/radioactive_eqns.html$ http://fagricipni.com/library/reference/radioactive-equations.html [R=301,L]
RewriteRule ^library/reference/lojban/lojban1_draft1.html$ http://fagricipni.com/library/reference/lojban/grammar-draft-unfinished.html [R=301,L]
# neither do these rules

So you'd need to change the rules to also match absolute URL's.
(This is, assuming I'm understanding this correctly, and it seems like it should work with what you have. There seems to be weird stuff I don't understand, like if I just do RewriteRule ^something something-else [R] (where something-else isn't absolute and doesn't start with /), then the rewritten URL seems to include the full path to the file? But then it's like there's another automatic rewrite rule at the end to correct for that or something? That shouldn't affect what you have, but still... it's weird and I don't understand why it does that, so maybe I don't understand this as well as I thought...)
~ chri d. d. /tʃɹɪ.di.di/ (Phonotactics, schmphonotactics) · they (for now, at least) · Forum game scores
mittfh wrote:I wish this post was very quotable...
flicky1991 wrote:In both cases the quote is "I'm being quoted too much!"

fagricipni
Posts: 34
Joined: Thu Nov 04, 2010 7:32 pm UTC

Re: mod_rewrite Question

Postby fagricipni » Tue Aug 02, 2016 8:26 am UTC

chridd wrote:(This is, assuming I'm understanding this correctly, and it seems like it should work with what you have. There seems to be weird stuff I don't understand, like if I just do RewriteRule ^something something-else [R] (where something-else isn't absolute and doesn't start with /), then the rewritten URL seems to include the full path to the file? But then it's like there's another automatic rewrite rule at the end to correct for that or something? That shouldn't affect what you have, but still... it's weird and I don't understand why it does that, so maybe I don't understand this as well as I thought...)


I changed my .htaccess to contain:

RewriteEngine On
RewriteBase /

# www to bare
RewriteCond %{HTTP_HOST} ^www.fagricipni.com [NC]
RewriteRule ^(.*)$ http://fagricipni.com/$1 [R=301]

# redirect to new lojban location
RewriteRule ^(http://fagricipni.com/)?lojban/about/(.*)$ http://fagricipni.com/library/reference/lojban/$2 [R=301]

# renamed files
RewriteRule ^(http://fagricipni.com/)?library/reference/radioactive_eqns.html$ http://fagricipni.com/library/reference/radioactive-equations.html [R=301,L]
RewriteRule ^(http://fagricipni.com/)?library/reference/lojban/lojban1_draft1.html$ http://fagricipni.com/library/reference/lojban/grammar-draft-unfinished.html [R=301,L]

But while it now correctly changes http://fagricipni.com/lojban/about/lojban1_draft1.html to http://fagricipni.com/library/reference/lojban/lojban1_draft1.html and http://fagricipni.com/lojban/about/feeling.html to http://fagricipni.com/library/reference/lojban/feeling.html in one pass, it also incorrectly converts http://www.fagricipni.com/lojban/about/lojban1_draft1.html to http://fagricipni.com/library/reference/lojban/lojban1_draft1.html/about/lojban1_draft1.html not http://fagricipni.com/library/reference/lojban/lojban1_draft1.html , and http://www.fagricipni.com/lojban/about/feeling.html to http://fagricipni.com/library/reference/lojban/feeling.html/about/feeling.html not http://fagricipni.com/library/reference/lojban/feeling.html .

I seem to be hitting whatever causes the rewritten URL to contain the full path the the file. I've changed my current .htaccess to the old one because it does actually reach the files I want; it just takes more than one redirect to get there.

User avatar
chridd
Has a vermicelli title
Posts: 753
Joined: Tue Aug 19, 2008 10:07 am UTC
Location: ...Earth, I guess?
Contact:

Re: mod_rewrite Question

Postby chridd » Tue Aug 02, 2016 1:24 pm UTC

fagricipni wrote:I seem to be hitting whatever causes the rewritten URL to contain the full path the the file. I've changed my current .htaccess to the old one because it does actually reach the files I want; it just takes more than one redirect to get there.
That doesn't sound like the problem I was running into. The problem I was running into involved ending up with redirects to things starting with http://127.0.0.1/Users/chri/site/public/, where /Users/chri/site/public is the directory that my website is stored in. Although this falls into the same "huh?" category...
(I can get the same problem to occur on my computer; it's not just you.)

Edit to add: Simplified test case:

Code: Select all

RewriteRule ^(.*)$ / [R]
RewriteRule ^(.*)$ /--$1-- [R]

# Input: http://127.0.0.1/a/b
# Expected output: http://127.0.0.1/--http://127.0.0.1/--
# Actual output: http://127.0.0.1/--http://127.0.0.1//b--
Anything after the first slash besides the one separating the domain from the path seems to be duplicated for no apparent reason.

Edit to add: Try adding the [DPI] flag
~ chri d. d. /tʃɹɪ.di.di/ (Phonotactics, schmphonotactics) · they (for now, at least) · Forum game scores
mittfh wrote:I wish this post was very quotable...
flicky1991 wrote:In both cases the quote is "I'm being quoted too much!"

fagricipni
Posts: 34
Joined: Thu Nov 04, 2010 7:32 pm UTC

Re: mod_rewrite Question

Postby fagricipni » Tue Aug 02, 2016 3:38 pm UTC

chridd wrote:Edit to add: Try adding the [DPI] flag


I get a 500 Internal Server Error when I do that; the documentation you have linked to states that it was introduced in version 2.2.12; the version at my hosting provider is too early.

Thank you for trying; but it seems that I'll just have to stick with the multiple redirect version, then.


Return to “The Help Desk”

Who is online

Users browsing this forum: No registered users and 4 guests