Solved

URL rewrite

Posted on 2006-12-01
15
272 Views
Last Modified: 2010-03-04
Trying it for the first time and having a problem with this stuff


RewriteEngine on

RewriteRule ^lotshop/index.php?main_page=product_info&cPath=2&products_id=([0-9]+)$ /trackdays/$1/ [R]
RewriteRule ^trackdays/([0-9]+)$ /trackdays/$1/ [R]
RewriteRule ^trackdays/([0-9]+)/$ /lotshop/index.php?main_page=product_info&cPath=2&products_id=$1

the problem lies with the first line. The second two work great.

Where have I gone wrong???


TIA
0
Comment
Question by:abenbow
  • 8
  • 7
15 Comments
 

Author Comment

by:abenbow
ID: 18058689
hmm

it's going to be the & isn't it.
0
 
LVL 16

Expert Comment

by:HackneyCab
ID: 18059398
No, it's actually the entire query string.

RewriteRule does not see the query string at all, so you can't match it with a regex pattern.

Instead, you need to use a RewriteCond and test the %{QUERY_STRING} variable.
0
 
LVL 16

Expert Comment

by:HackneyCab
ID: 18059405
For instance, your first line could become:

RewriteCond %{QUERY_STRING} main_page=product_info
RewriteCond %{QUERY_STRING} cPath=28
RewriteCond %{QUERY_STRING} products_id=([0-9]+)
RewriteRule ^lotshop/index.php$ /trackdays/%1

The %1 matches "the grouped parts (parentheses!) of the pattern from the last matched RewriteCond directive in the current bunch of conditions" (from the Apache manual).
0
VMware Disaster Recovery and Data Protection

In this expert guide, you’ll learn about the components of a Modern Data Center. You will use cases for the value-added capabilities of Veeam®, including combining backup and replication for VMware disaster recovery and using replication for data center migration.

 
LVL 16

Expert Comment

by:HackneyCab
ID: 18059406
(Sorry, I forgot the R flag at the end of the RewriteRule.)
0
 

Author Comment

by:abenbow
ID: 18059495
Ok thanks for that

this is where I am at now

RewriteEngine on

RewriteCond %{QUERY_STRING} main_page=product_info
RewriteCond %{QUERY_STRING} cPath=2
RewriteCond %{QUERY_STRING} products_id=([0-9]+)
RewriteRule ^lotshop/index.php$ /trackdays/%1/ [R]

RewriteRule ^trackdays/([0-9]+)$ /trackdays/$1/ [R]
RewriteRule ^trackdays/([0-9]+)/$ /lotshop/index.php?main_page=product_info&cPath=2&products_id=$1

basically it doesn't work. It takes an age to load the page - miniutes - and just display "page can not be found" The URL is not rewritten
0
 
LVL 16

Expert Comment

by:HackneyCab
ID: 18059528
That could be an infinite loop. Your second rule seems to be redirecting /trackdays/23 to /trackdays/23/, which the third rule will then redirect to /lotshop/index.php?main_page=product_info&cPath=28&products_id=23, which the first rule will then redirect to /trackdays/23/, and round and round it goes, forever.

Eventually Apache will realise it's not going anywhere and just timeout.

You need to redesign your rules so that they aren't cyclic.
0
 

Author Comment

by:abenbow
ID: 18059595
hmm, ok

This is what I thought was happening

SAMPLE URL
http://www.lotus-on-track.com/lotshop/index.php?main_page=product_info&cPath=2&products_id=128

the sections that you have posted would turn that URL into

http://www.lotus-on-track.com/trackdays/128/

this


RewriteRule ^trackdays/([0-9]+)$ /trackdays/$1/ [R]

would check for the trailing / and rewrite the URL to include it if it's not there.

then this

RewriteRule ^trackdays/([0-9]+)/$ /lotshop/index.php?main_page=product_info&cPath=2&products_id=$1

would get the send the code the correct information (lotshop/index.php?main_page=product_info&cPath=2&products_id=128) while still allowing http://www.lotus-on-track.com/trackdays/128/ to be displayed in the address bar.

If I just use

RewriteEngine on

RewriteRule ^trackdays/([0-9]+)$ /trackdays/$1/ [R]
RewriteRule ^trackdays/([0-9]+)/$ /lotshop/index.php?main_page=product_info&cPath=2&products_id=$1

then putting http://www.lotus-on-track.com/trackdays/128 into the address bar converts it to http://www.lotus-on-track.com/trackdays/128/ and displays it correctly, leaving http://www.lotus-on-track.com/trackdays/128/ in the address bar.

So now I'm confused
0
 

Author Comment

by:abenbow
ID: 18059667
OK

I have tried your code on it's own

RewriteEngine on

RewriteCond %{QUERY_STRING} main_page=product_info
RewriteCond %{QUERY_STRING} cPath=2
RewriteCond %{QUERY_STRING} products_id=([0-9]+)
RewriteRule ^lotshop/index.php$ /trackdays/%1/ [R]

and it's not working properly

Basically it converts

http://www.lotus-on-track.com/lotshop/index.php?main_page=product_info&cPath=2&products_id=128

to

http://www.lotus-on-track.com/trackdays/128/?main_page=product_info&cPath=2&products_id=128
0
 
LVL 16

Expert Comment

by:HackneyCab
ID: 18059979
Ah, sorry. (I just solved this very problem in another thread.)

To clear the query string, you just append a question mark to the end of the RewriteRule target:

RewriteRule ^lotshop/index.php$ /trackdays/%1/? [R]

I'm assured (by the poster of the other thread) that Apache is smart enough to see the empty query-string and it won't put the question mark on the end of the rewritten URL.
0
 

Author Comment

by:abenbow
ID: 18060045
ok, thanks for that. It does fix the code you posted

any ideas on how do I stop it from looping??
0
 
LVL 16

Expert Comment

by:HackneyCab
ID: 18061005
Well, you need to decide what the underlying URL is (the actual path to an actual document or script) and what is the superficial URL is (the one the user sees in their browser window).

The superficial URL should internally (without the user noticing) redirect to the underlying URL.

I get the impression you want the URL the user sees to be /trackdays/23/ (for instance), and the actual script is found at /lotshop/index.php. But I might be wrong. Let me know how your site is (or is intended to be) structured with regards to this.
0
 

Author Comment

by:abenbow
ID: 18061115
ok

this is the site
http://www.lotus-on-track.com/lotshop/

.htaccess is located here
http://www.lotus-on-track.com

Currently an event url looks like this
http://www.lotus-on-track.com/lotshop/index.php?main_page=product_info&cPath=2&products_id=160

I want to change that to
http://www.lotus-on-track.com/trackdays/160/

If I show the URL
http://www.lotus-on-track.com/trackdays/160/

then I need .htaccess to silently send
http://www.lotus-on-track.com/lotshop/index.php?main_page=product_info&cPath=2&products_id=160

to the code so that the code still works.

All the links in the code will sow up as
http://www.lotus-on-track.com/lotshop/index.php?main_page=product_info&cPath=2&products_id=160

so I need .htaccess to convert those to
http://www.lotus-on-track.com/trackdays/160/

in the address bar.





RewriteEngine on

RewriteCond %{QUERY_STRING} main_page=product_info
RewriteCond %{QUERY_STRING} cPath=2
RewriteCond %{QUERY_STRING} products_id=([0-9]+)
RewriteRule ^lotshop/index.php$ /trackdays/%1/? [R]


RewriteRule ^trackdays/([0-9]+)$ /trackdays/$1/ [R]
RewriteRule ^trackdays/([0-9]+)/$ /lotshop/index.php?main_page=product_info&cPath=2&products_id=$1


Your section will convert the URL to the format I want.
My section will get the right information to the code and display the correct event on the page whilest leaving the URL http://www.lotus-on-track.com/trackdays/160/ in the address bar.

The problem is they won't work together. If you put them together then you end up looping and ultimately the page doesn't load.


Thanks

Andy
0
 
LVL 16

Accepted Solution

by:
HackneyCab earned 500 total points
ID: 18062914
Ah, I now see why you ended up with rules that resulted in an infinite loop.

I don't think it's possible to achieve the result you're trying to get. When a redirect occurs (internal or external), the rewritten URL starts a new request, and the RewriteRules will be evaluated from scratch using the new requested URL. Which means your rules will always lead to an infinite loop.

The only way I can think of to avoid this is to set a new part in the query string of the real URL. Like this:

RewriteRule ^trackdays/([0-9]+)/$ /lotshop/index.php?main_page=product_info&cPath=2&products_id=$1&done_redirect=1

Then add a new RewriteCond to the first rule:

RewriteCond %{QUERY_STRING} !done_redirect=1

which will only trigger if the done_redirect=1 part of the query string is not present.

This might work, but I strongly recommend you modify your code to produce links that use the new URL. For a start, you need to consider a common problem with using silent redirects. The web browser thinks it is in a directory called /trackdays/ but no such directory actually exsts. So requests for images using relative paths will fail. So you may need to change HTML in affected pages so that images and files use absolute paths (beginning with a forward slash).
0
 

Author Comment

by:abenbow
ID: 18062930
oh that is genius!

it works amazingly well.

Thank you
0
 
LVL 16

Expert Comment

by:HackneyCab
ID: 18062977
Glad you got it working.
0

Featured Post

VMware Disaster Recovery and Data Protection

In this expert guide, you’ll learn about the components of a Modern Data Center. You will use cases for the value-added capabilities of Veeam®, including combining backup and replication for VMware disaster recovery and using replication for data center migration.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

As Wikipedia explains 'robots.txt' as -- the robot exclusion standard, also known as the Robots Exclusion Protocol or robots.txt protocol, is a convention to prevent cooperating web spiders and other web robots from accessing all or part of a websit…
It is possible to boost certain documents at query time in Solr. Query time boosting can be a powerful resource for finding the most relevant and "best" content. Of course the more information you index, the more fields you will be able to use for y…
This video shows how to quickly and easily add an email signature for all users on Exchange 2016. The resulting signature is applied on a server level by Exchange Online. The email signature template has been downloaded from: www.mail-signatures…
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

773 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question