Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reference capture groups of multiple RewriteCond in RewriteRule

When I have multiple RewriteCond chained together, only the capture groups of the last RewriteCond can be referenced with %0-%9.

In the following problem the parameters in the query string of the url can be in any order. To parse them into a fancy url I would need to match each parameter in the query string individually:

RewriteCond %{QUERY_STRING} param1=([^&]+)
RewriteCond %{QUERY_STRING} param2=([^&]+)
RewriteCond %{QUERY_STRING} param3=([^&]+)
RewriteRule ^foo$ bar/%1/%2/%3/ [R]

Like I pointed out... this doesn't work. To fix this, I could reference the capture group of the previous RewriteCond in the next RewriteCond and 'propagate' each parameter to the actual RewriteRule:

RewriteCond %{QUERY_STRING} param1=([^&]+)
RewriteCond %1&%{QUERY_STRING} ^([^&]*)&.*param2=([^&]+)
RewriteCond %1&%2&%{QUERY_STRING} ^([^&]*)&([^&]*)&.*param3=([^&]+)
RewriteRule ^foo$ bar/%1/%2/%3/ [R]

This should work, but for each additional parameter it get's messier. An other solution could possibly be parsing one parameter and redirecting the client after each parameter (resulting in a lengthy chain of redirects, which I would like to avoid).

Is there an cleaner way of accessing the capture groups of all RewriteCond's in the RewriteRule (e.g. is it possible to name them or assign them to a variable so I can reference them somewhere else?)

like image 618
Sumurai8 Avatar asked Jul 22 '13 10:07

Sumurai8


1 Answers

You could try constructing the target URL inside the rewrite conditions:

RewriteCond ##%{QUERY_STRING}      (.*)##(|.*&)param1=([^&]+)
RewriteCond %1/%3##%{QUERY_STRING} (.*)##(|.*&)param2=([^&]+)
RewriteCond %1/%3##%{QUERY_STRING} (.*)##(|.*&)param3=([^&]+)
RewriteCond %1/%3##%{QUERY_STRING} (.*)##(|.*&)param4=([^&]+)
RewriteCond %1/%3##%{QUERY_STRING} (.*)##(|.*&)param5=([^&]+)
RewriteCond %1/%3##%{QUERY_STRING} (.*)##(|.*&)param6=([^&]+)

RewriteRule ^foo$ /bar%1/%3? [L,R]

When I try to request:

/foo?param1=a&param2=b&param6=3&param3=4&param5=5&param4=6

I get redirected to:

/bar/a/b/4/6/5/3

Adding any additional required query string parameters won't make it look any more messy than it already is.

like image 180
Jon Lin Avatar answered Oct 25 '22 10:10

Jon Lin