Need to break out of Redirect Loop - SOLVED.

Discuss practical ways rearrange URLs using mod_rewrite.

Need to break out of Redirect Loop - SOLVED.

Postby dazzler » Sat Mar 28, 2009 8:21 am

I am trying to use a RewriteMap and want to use it to move some items to the new subsiteareas, yet be able to access the remaining items in the mainsitearea1. If I do not define DefaultValue, it just returns to the mainsitearea1 and does not allow for any subsiteareas. The items in the rewritemap DO make the proper connection.

I know the code below produces a redirect loop, but I don't know how to break the loop:

Code: Select all
RewriteMap listofrewrites txt:/etc/httpd/conf/rewrites/map_listofrewrites.txt
RewriteCond %{REQUEST_URI} !^/mainsitearea1/sitearea1/subsitearea1/(.+)?$ [NC]
RewriteCond %{REQUEST_URI} !^/mainsitearea1/sitearea1/subsitearea2/(.+)?$ [NC]
RewriteCond %{REQUEST_URI} !^/mainsitearea1/sitearea1/subsitearea3/(.+)?$ [NC]
RewriteRule ^/mainsitearea1/(.+)$ mainsitearea1${listofrewrites:$1|/$1} [R=301,L,NC]


Questions:
    Overall: How do I break this loop?
    Am I using DefaultValue correctly?
    Is there a flag I should try? I am trying last, and I have tried NS.
    We do have some friendly url rewrites that essentially cut the path down and make them look nice. They are being proxied:

    Code: Select all
    RewriteCond %{QUERY_STRING} !^stopnow
    RewriteRule ^/wps/wcm/myconnect/library/overallsitearea/mainsitearea1(.+)?$ /mainsitearea1_secured$1 [NC,R,L]
    RewriteRule ^/mainsitearea1_secured(.+)?$ /wps/wcm/myconnect/library/overallsitearea/mainsitearea1$1?stopnow [NC,P,QSA]
    RewriteCond %{QUERY_STRING} !^stopnow
    RewriteRule ^/wps/wcm/connect/library/overallsitearea/mainsitearea1(.+)?$ /mainsitearea1$1 [NC,R,L]
    RewriteRule ^/mainsitearea1(.+)?$ /wps/wcm/connect/library/overallsitearea/mainsitearea1$1?stopnow [NC,P,QSA]


    Is the above causing a conflict as well?
Last edited by dazzler on Sun Mar 29, 2009 9:19 am, edited 2 times in total.
dazzler
 
Posts: 3
Joined: Fri Mar 27, 2009 2:22 pm

Postby richardk » Sat Mar 28, 2009 8:42 am

Can you provide some examples of what's supposed to happen, eg.
Code: Select all
/abc --> matches map --> /def
/ghi --> doesn't match map --> /jkl
richardk
 
Posts: 8800
Joined: Wed Dec 21, 2005 7:50 am

Postby dazzler » Sat Mar 28, 2009 8:59 am

richardk wrote:Can you provide some examples of what's supposed to happen, eg.
Code: Select all
/abc --> matches map --> /def
/ghi --> doesn't match map --> /jkl


Sure, and thanks for the quick response!

Here is what we are trying to do:

Code: Select all
/mainsitearea1/abc ---> matches map --> /mainsitearea1/sitearea1/subsitearea1/abc
/mainsitearea1/def ---> matches map --> /mainsitearea1/sitearea1/subsitearea2/def
/mainsitearea1/ghi ---> matches map --> /mainsitearea1/sitearea1/subsitearea3/ghi

/mainsitearea1/jkl --> doesn't match map --> /mainsitearea1/jkl (essentially 'take no action')


We are better organize some pages, and utilize some dynamic sorts, and by moving some old content into some new site areas, this will help us accomplish this. We are using elements that will focus on content in subsitearea1, subsitearea2, and subsitearea3, and filter along with some tags added.

The reason for these RewriteCond:
Code: Select all
RewriteCond %{REQUEST_URI} !^/mainsitearea1/sitearea1/subsitearea1/(.+)?$ [NC]
RewriteCond %{REQUEST_URI} !^/mainsitearea1/sitearea1/subsitearea2/(.+)?$ [NC]
RewriteCond %{REQUEST_URI} !^/mainsitearea1/sitearea1/subsitearea3/(.+)?$ [NC]


is to stop these new redirects from continuing through the rewrites, which is the behavior I want for the non-matching items. But because they are in the main site area, it presents a problem, in that if I do a rewrite condition like the ones above, it won't even hit the rewritemap.

I know I can solve this with some one to one redirects, but there are over 100 items I would have to do this for, and we have over 2000 redirects in our .conf file already (much fun with maintenance).

Thanks again for any and all help.
dazzler
 
Posts: 3
Joined: Fri Mar 27, 2009 2:22 pm

Postby richardk » Sat Mar 28, 2009 6:32 pm

Try
Code: Select all
Options +FollowSymLinks

RewriteEngine On

RewriteMap listofrewrites txt:/etc/httpd/conf/rewrites/map_listofrewrites.txt

# Check the map.
RewriteCond ${listofrewrites:$1|not_found} ^(.+)$
# If it wasn't found, don't continue.
RewriteCond %1 !^not_found$
RewriteRule ^/mainsitearea1/(.+)$ /mainsitearea1%1 [NC,R=301,L]
richardk
 
Posts: 8800
Joined: Wed Dec 21, 2005 7:50 am

Postby dazzler » Sun Mar 29, 2009 6:07 am

Richard,

This appears to be working without disturbing the other 2000 links! I am truly grateful for your thought and work on this. I have a couple of questions to make sure I understand the implications of this solution:

I am unfamiliar with the Options Directive and FollowSymLinks - Are there any risks in using FollowSymLinks? So far, I don't see it affecting our other links, but any time I turn on something in Mod_Rewrite, I do get a little nervous ("damn cool voodoo...but just that, 'voodoo'"). I can't find any immediate risks as I research it.

Is there a place I can get a better handle on the DefaultValue values and what set to use for this? Is not_found just a user-defined variable? If I used 'pickle', it would have the same effect?

Again, thank you, and let me know if anyone knows of any dangers of using 'FollowSymLinks'. I would love to get this into production today.

Unless there are any objections to this method, I am considering it resolved.

With my code, I got as far as this (including a known redirect loop):
Code: Select all
RewriteMap listofrewrites txt:/etc/httpd/conf/rewrites/map_listofrewrites.txt
RewriteCond %{REQUEST_URI} !^/mainsitearea1/sitearea1/subsitearea1/(.+)?$ [NC]
RewriteCond %{REQUEST_URI} !^/mainsitearea1/sitearea1/subsitearea2/(.+)?$ [NC]
RewriteCond %{REQUEST_URI} !^/mainsitearea1/sitearea1/subsitearea3/(.+)?$ [NC]
RewriteRule ^/mainsitearea1/(.+)$ mainsitearea1${listofrewrites:$1|/$1} [R=301,L,NC]


Currently, with Options +FollowSymLinks enabled, I have no redirect loop and items in the mainsitearea1 are functioning as expected using this code:
Code: Select all
RewriteMap listofrewrites txt:/etc/httpd/conf/rewrites/map_listofrewrites.txt
RewriteCond ${listofrewrites:$1|not_found} ^(.+)$
RewriteCond %1 !^not_found$
RewriteRule ^/mainsitearea1/(.+)$ /mainsitearea1%1 [NC,R=301,L]


Richard, THANKS FOR ALL YOUR HELP!
dazzler
 
Posts: 3
Joined: Fri Mar 27, 2009 2:22 pm

Postby richardk » Sun Mar 29, 2009 9:37 am

I am unfamiliar with the Options Directive and FollowSymLinks - Are there any risks in using FollowSymLinks?

You can remove it if you are not using a .htaccess file (and possibly <Directory>).

FollowSymLinks forces Apache to follow symbolic links, it has nothing to do with the loop. It is a requirement for mod_rewrite (presumably so you rewrite to the right place and not where you shouldn't be able to acess) for per-directory rewrites.
http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewriterule wrote:Per-directory Rewrites

The rewrite engine may be used in .htaccess files. To enable the rewrite engine for these files you need to set "RewriteEngine On" and "Options FollowSymLinks" must be enabled. If your administrator has disabled override of FollowSymLinks for a user's directory, then you cannot use the rewrite engine. This restriction is required for security reasons.

When using the rewrite engine in .htaccess files the per-directory prefix (which always is the same for a specific directory) is automatically removed for the pattern matching and automatically added after the substitution has been done. This feature is essential for many sorts of rewriting; without this, you would always have to match the parent directory, which is not always possible. There is one exception: If a substitution string starts with http://, then the directory prefix will not be added, and an external redirect (or proxy throughput, if using flag P) is forced. See the RewriteBase directive for more information.

The rewrite engine may also be used in <Directory> sections with the same prefix-matching rules as would be applied to .htaccess files. It is usually simpler, however, to avoid the prefix substitution complication by putting the rewrite rules in the main server or virtual host context, rather than in a <Directory> section.

Although rewrite rules are syntactically permitted in <Location> sections, this should never be necessary and is unsupported.


Is there a place I can get a better handle on the DefaultValue values and what set to use for this? Is not_found just a user-defined variable? If I used 'pickle', it would have the same effect?

It is the user defined default value. If it isn't found in the RewriteMap that value is used.

With my code, I got as far as this (including a known redirect loop):

The problem with your code is that when you go to /mainsitearea1/abc, it is found in the RewriteMap, you redirect to /mainsitearea1/sitearea1/subsitearea1/abc. The user requests /mainsitearea1/sitearea1/subsitearea1/abc, it does not match (because of the RewriteCond !^/mainsite...). That's OK.

However, if you go to /mainsitearea1/def it does not match to the RewriteMap, you redirect to /mainsitearea1/def. The user requests /mainsitearea1/def, it does not match the RewriteMap, the user is redirected to /mainsitearea1/def. Loop. Whereas in mine, if it is not found it fails in the second condition and no redirect occurs.
richardk
 
Posts: 8800
Joined: Wed Dec 21, 2005 7:50 am


Return to Friendly URLs with Mod_Rewrite

Who is online

Users browsing this forum: Google [Bot] and 26 guests

cron