Welcome to WebmasterWorld Guest from 54.196.208.187

Forum Moderators: Ocean10000 & phranque

Message Too Old, No Replies

Clarification on RewriteCond, L flags, testing w/302s v 301s

     
4:54 pm on Jan 14, 2015 (gmt 0)

New User

joined:June 16, 2014
posts: 7
votes: 0


I really appreciate the help that I got for my previous question - I think it was just the answer I was looking for! I'm working on another .htaccess file for a different client and I'm back with some (probably) basic questions.

Here's the setup: The client is a group of restaurants. Originally, they had several websites for each of their restaurant, and a separate website where people could order food from any of those restaurants to be shipped to them. Now, the client would like to get rid of the separate food ordering website and redirect the various pages of it to the websites for the different stores.

I came up with a rough draft which I sent to my supervisor, and she came back with this version:

RewriteEngine on
RewriteCond %{REQUEST_URI} !^a-store$ [NC]

# Redirect [restaurant1] related pages to example.com pages
RewriteRule ^.*ED-03.*$ http://www.example.com/gift-shop/ [R=301]
RewriteRule ^.*c-Ed_DebevicAns.*$ http://www.example.com/gift-shop/ [R=301]
RewriteRule ^.*eds_p3.*$ http://www.example.com/menus/ [R=301]
RewriteRule ^.*eds_p5.*$ http://www.example.com/promotions/gift-certificates/ [R=301]
RewriteRule ^.*eds_p7.*$ http://www.example.com/cateringevents/ [R=301]
RewriteRule ^.*eds_p8.*$ http://www.example.com/promotions/ [R=301]

# Redirect [restaurant2] related pages to example2.com pages
RewriteRule ^.*edw_p2.*$ http://example.net/locations/ [R=301]
RewriteRule ^.*edw_p5.*$ http://example.net/product-category/gift-certificate/ [R=301]
RewriteRule ^.*c-EdwardoAns.*$ http://example.net/shop/ [R=301]
RewriteRule ^.*EDW-01.* http://example.net/shop/edwardos-9-stuffed-spinach-pizza/ [R=301]
RewriteRule ^.*EDW-02.* http://example.net/shop/edwardos-9-stuffed-sausage-pizza/ [R=301]
RewriteRule ^.*EDW-08.* http://example.net/shop/edwardos-9-stuffed-cheese-pizza/ [R=301]

# Redirect [restaurant3] related pages to example.org pages
RewriteRule ^.*c-GinoAns_East.*$ http://www.example.org/product-category/deep-dish/ [R=301]
RewriteRule ^.*gino_p5.*$ http://www.example.org/product-category/gift-certificate/ [R=301]
RewriteRule ^.*GINO-01.*$ http://www.example.org/shop/deep-dish-cheese-pizza-11/ [R=301]
RewriteRule ^.*GINO-02.*$ http://www.example.org/shop/deep-dish-crumbled-sausage-pizza-11/ [R=301]
RewriteRule ^.*GINO-04.*$ http://www.example.org/product-category/deep-dish/ [R=301]

# Redirect all [restaurant4] pages to example4.com
RewriteRule ^.*[m|M]it.*$ http://example4.com [R=301,L]

So, I have a few questions about this. 1) it's my understanding that a RewriteCond only applies to the RewriteRule directly below it, that it can't apply to more than one RewriteRule, and if you want all your rules to have conditions, you have to put a RewriteCond above every RewriteRule. My supervisor says that this is not the case as long as only the very last RewriteRule has an L flag. Is this true?

Which brings me to my next question: I thought that you were supposed to put an L flag after every rule. That good .htaccess practice is, you work from most specific to least specific, and put an L flag after every rule, so that if the server finds a rule that applies to the requested URL, it applies the first (most specific) rule that it finds, and it doesn't look for any other rules once it triggers the first one. That way it avoids confusion and possible redirect loops.

Also, in her email with the corrections, she sent me this statement: "A most important thing is to test with 302, not 301. While the .htaccess I sent you has 301, the test site is using 302 so your browser won’t trick you into thinking something works when it doesn’t, or trick you into thinking something doesn’t work when it does." What does this mean? How would testing something with 301s make your browser trick you into thinking something works when it doesn't, or not working when it does? Since I'm not 100% certain about the difference other than that one is permanent and one is temporary, I have no idea why this statement might be the case.

[edited by: Ocean10000 at 8:19 pm (utc) on Jan 14, 2015]
[edit reason] Unlinked URLs [/edit]

6:21 pm on Jan 14, 2015 (gmt 0)

Administrator from US 

WebmasterWorld Administrator not2easy is a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month

joined:Dec 27, 2006
posts:4201
votes: 265


Because each rule deals with a different URL parameter, there is no chance of looping, the file requested won't have two different directories as part of the URL so they can be "stacked" with the L on the last of those. The L prevent application of more than one rewrite, but the original one has taken care of it. (assuming there are no existing URLs with /GINO-02/GINO-01/ as part of the URL.)

As far as the 301/302 part, I would verify that she wants you to alter the code and remove the [R=301] during testing and hold this version for a final. The browser doesn't display one or the other unless you are viewing headers. The development (Test) site is not public, right? It sounds like there is concern about GA or something recording the new URLs as permanent ahead of schedule(?)
6:43 pm on Jan 14, 2015 (gmt 0)

Senior Member from GB 

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

joined:Aug 13, 2003
posts: 1053
votes: 3


The 301/302 is due to the fact one is a permanent and the other is a temporary redirect.

Some browsers cache the 301 redirects but not 302 redirects.
6:53 pm on Jan 14, 2015 (gmt 0)

New User

joined:June 16, 2014
posts: 7
votes: 0


Thanks for the replies! I guess I could theoretically see how the browser caching might make testing the redirects confusing.

I guess the L thing makes sense too, that as long as there is no chance of looping then you only need an L on the last one.

So to confirm, then, if there's only an L on the last one, then the RewriteCond works for the whole block of rules?
8:15 pm on Jan 14, 2015 (gmt 0)

Senior Member from US 

WebmasterWorld Senior Member lucy24 is a WebmasterWorld Top Contributor of All Time 5+ Year Member Top Contributors Of The Month

joined:Apr 9, 2011
posts:15504
votes: 749


If you need to name more than one domain, you can say example.org, example.net, or example.any-tld (including ones that don't really exist, like example.xyz).

Leave a blank line after each RewriteRule. That's for your own benefit; the server doesn't care.

as long as there is no chance of looping then you only need an L on the last one.

Every time you leave off an [L] the server has to continue looking at any and all following rules-- potentially including evaluating conditions-- whether or not there's any possibility that the rules or conditions will ever apply. If you've got a set of mutually exclusive rules, give each one an [L] so the server can stop looking.

The only time you omit the [L] flag is when it's either implied by some other flag like [F] or [G], or you need to allow for more than one rule executing on the same request. Most often that's only when you're not rewriting at all, such as setting a cookie or environmental variable.

Do everything in your power to avoid the
^.*
locution. Here it simply isn't needed; you can leave off both the opening anchor and the .* part and keep only the text to be matched. But only do this if there's a variety of possible text before the part you're matching. Otherwise say
^ED-03
or
^directory/ED-03
or whatever the exact path is, so the server can get out of there sooner.

Similarly, the form
.*$
is never needed. If you're not capturing, you don't need to say anything at all about the rest of the string.
10:11 pm on Jan 14, 2015 (gmt 0)

New User

joined:June 16, 2014
posts: 7
votes: 0


Ah! Thanks for fixing my examples so they're readable now.

Also thanks for clearing up my Regex.

So, maybe to clear up my thinking:

Here is an example of a couple of URLs that I need redirected (both of these go to the same place):
  • http://example.com/cgi-local/SoftCart.exe/a-store/edw_p5.shtml?L+scstore+xxbs2935fffb1efb+1420760246
  • http://example.com/a-store/edw_p5.shtml

    All the URLS that I need to redirect have "a-store" in them somewhere, and the "a-store" is directly in front of the unique part of the URL. Initially, all of my redirects had looked similar to this:

    RewriteRule .*a-store/edw_p5\.shtml.* http://www.example.com/our-story/ [R=301, L]


    (I see now that I didn't need the .* at the beginning or end, since I'm not capturing anything)

    So it looks like what my supervisor did was to take out the a-store from each rule, make it a condition, and then shorten each of the rules to the smallest unique part possible (from the above examples, the "edw_p5" part.) Also added the ^ and $ to the beginning and end, and took out the L flag on all but the last one.

    To be honest, I feel like it would be faster for the server if I just kept everything like it was previously.
  • 12:49 am on Jan 15, 2015 (gmt 0)

    Senior Member from US 

    WebmasterWorld Senior Member lucy24 is a WebmasterWorld Top Contributor of All Time 5+ Year Member Top Contributors Of The Month

    joined:Apr 9, 2011
    posts:15504
    votes: 749


    it looks like what my supervisor did was to take out the a-store from each rule, make it a condition

    Psst! Don't tell anyone, but ... your supervisor is wrong in two different ways.
    #1 Never put something in a Condition that can go in the body of the rule.
    #2 More seriously, a RewriteCond applies only to the immediately following rule. It isn't like an <If> envelope that can be used to group a series of related rules.

    To be honest, I feel like it would be faster for the server if I just kept everything like it was previously.

    To be honest, I agree with you :)

    Now let's all go home and re-read The Peter Principle.