Rewriting 2nd parameter in query string - apache

Like so many I am struggling with what ought to be a simple rewrite
The initial form is something like:
http://cassie-family.co.uk/individual.php?pid=I807&ged=Cassy%20Family%20History.ged
The last parameter only needs rewriting, as in:
http://cassie-family.co.uk/individual.php?pid=I807&ged=Cassie%20-%20Cassy%20Family%20History
I have tried to trap the first parameter using:
RewriteCond %{QUERY_STRING} ^pid=([^&]+) [NC]
The nearest (incorrect) RewriteRule is:
RewriteRule ^(.*)$ individual.php&pid=%1&ged=Cassie%20-%20Cassy%20Family%20History [L, NC, R=301]
The moment I try to replace the '&' after individual.php with the correct '?' the URL is written as:
http://cassie-family.co.uk/individual.php
So.. the parameter is being trapped correctly but the rewrite rule is clearly mangled. The error lies in here:
^(.*)$ individual.php&
What construct should I be using to replace only the 2nd (passed-in) parameter value (which is always the same fixed string) with a different 2nd value (which is always the same but slightly different fixed string)? Adding a B flag seems to make no difference.
All suggestions welcome,
Thanks,
Ric

Related

Checking if query_string has a value or else redirect it

I am learning .htaccess
My URL string is
http://abc.bcd.com/company/abc
I do apply to redirect my page if the company name is abc, xyz etc. and my rewrite rule is
RewriteRule ^/company/(.*?)$ /hhhhh/ll/test_page.html?company_letter=$1 [L,PT]
Sometimes my url change to
http://abc.bcd.com/company/abc?locale=en
What will be query string condition to accommodate both the url and should work properly ?
I have tried this but not helping .
RewriteCond %{QUERY_STRING} ^locale=(.*)$
The rewrite condition should help me like
if(locale="something")
/hhhhh/ll/test_page.html?company_letter=abc&locale=something
else
/hhhhh/ll/test_page.html?company_letter=abc
You just need to add QSA flag in your rule:
RewriteRule ^/?company/(.*)$ /hhhhh/ll/test_page.html?company_letter=$1 [L,QSA]
QSA (Query String Append) flag preserves existing query parameters while adding a new one.
The query string part of the incoming URL is a very specific thing. First you should know that classical rewriteRules are not managing the query string.
So, for example, you cannot make a RewriteRule with a check for a query string parameter value. Query strings parameters could be repeted several times, could appear in any order, and are not url-decoded (the location part of the url is url-decoded when mod_rewrite works on it).
This explains why some RewriteCond are sometimes used on the %{QUERY_STRING}, it cannot be done in RewriteRule but could be tested in rewriteCond, with all the previous probelsm ( repetition, order, url-encoding, etc).
But some rewriteRule tags can be applied for query string managment. Currently your tags are [L,PT], which also be writtent [last,passthrough].
You can add a qsappend or QSA tag which explicitly tells mod_rewrite to combine the original query string and the generated one.
So with
RewriteRule ^/company/(.*?)$ /hhhhh/ll/test_page.html?company_letter=$1 [last,passthrough,qsappend]
This:
http://abc.bcd.com/company/abc
Will go to
/hhhhh/ll/test_page.html?company_letter=abc
And this:
http://abc.bcd.com/company/abc?locale=en
Will go to
/hhhhh/ll/test_page.html?company_letter=abc&locale=en

How to extract GET parameter argument value in Apache?

I have following URL:
myUrl?path=123&param=val
Can you help me to write regular expression which will return path value. i.e
123
at this case?
P.S.
I have
REQUEST_URI and QUERY_STRING arguments.
P.S.
more global goal:
rewrite following url:
site.com/cat1/cat2?path=val&param=ololo
to
site.com/cat1/cat2/val
P.P.S
I have read following answer:
https://stackoverflow.com/a/2252242/2674303
but there are a bit another situation.
RewriteCond %{QUERY_STRING} (.*(?:^|&))path=([^&]*)(.*)
RewriteRule ^/?cat1/cat2$ /cat1/cat2/%2? [PT]
Note, the final '?' drops the old query string.

RewriteRule comes back to the same directory

I am trying to make two rewrite rules which should point to different files. However, they somehow are pointing to the same PHP file.
Can somebody help take a look please?
RewriteRule ^destinations/([a-z]+)-(.*)$ /a.php?x=$1&y=$2 [NC]
This should be linked to www.example.com/destination/us-united-state
RewriteRule ^destinations/([a-z]+)-(.+)-(.+)$ /b.php?a=$1&b=$2&c=$3 [NC]
This should be linked to www.example.com/destination/us-united-state-california
A regular expression finds the longest possible match. So, ([a-z]+)-(.*)$ will match one or more a through z characters followed by a dash followed by ANYTHING.
([a-z]+)-(.+)-(.+) requires two dashes, but the above expression will match these too.
be sure that you have the correct number of dashes matched:
RewriteRule ^destinations/([a-z]+)-([^-]+)$ /a.php?x=$1&y=$2 [NC]
and rename the page to
www.example.com/destination/us-unitedstate
then
RewriteRule ^destinations/([a-z]+)-([^-]+)-([^-]+)$ /b.php?a=$1&b=$2&c=$3 [NC]
to match pages like
www.example.com/destination/us-unitedstate-california
Use an other delimiter between us and united-state and between united-state and california. There is no way you can detect if the three seperate words in www.example.com/destination/us-united-state are actually two or three 'things'. I advice using slashes as delimiter instead: www.example.com/destination/us/united-state and www.example.com/destination/us/united-state/california.
Your rules would be:
RewriteRule ^destinations/([a-z]+)/([^/]+)/?$ /a.php?x=$1&y=$2 [NC]
RewriteRule ^destinations/([a-z]+)/([^/]+)/([^/]+)/?$ /b.php?a=$1&b=$2&c=$3 [NC]
This uses [^/]+, which matches anything but the / character. This prevents a capturing group from matching something like us/united-states where it should only match us. Please note that this code is untested as I can't test on this computer.

Mod_rewrite. Redirect url with Special Characters (question marks)

I have a website with joomla and I need to redirect (301) some links
They are in this form (index.php?Itemid= identify them - all links that doesn't have this part shouldn't be redirected)
/index.php?Itemid=544&catid=331:savona&id=82356:smembramento-dei-cantieri-baglietto-di-varazze-lopposizione-delle-maestranze&option=com_content&view=article
This should work
RewriteRule ^index.php?Itemid(.*)$ http://www.ligurianotizie.it/archive/index.php?Itemid$1 [L,R=301]
But the first ? (question mark) seems to cause problems.
In fact, if we suppose that the links are without the question mark
/index.phpItemid=544&catid=331:savona&id=82356:smembramento-dei-cantieri-baglietto-di-varazze-lopposizione-delle-maestranze&option=com_content&view=article
I would use
RewriteRule ^index.phpItemid(.*)$ http://www.ligurianotizie.it/archive/index.php?Itemid$1 [L,R=301]
and everything is perfect. But unfortunately real links has that question mark, and I have to find a solution.
What I have to do with that question mark?
Is the ? character escaped? try to add the NE (noescape) flag like this:
RewriteRule ^index.php?Itemid(.*)$ http://www.ligurianotizie.it/archive/index.php?Itemid$1 [L,R=301,NE]
The part behind the question mark is the query string. You can use RewriteCondto determine if it is not empty, and based on that make the decision to redirect.
Note: Query String
The Pattern will not be matched against the query string. Instead, you must use a RewriteCond with the %{QUERY_STRING} variable. You can, however, create URLs in the substitution string, containing a query string part. Simply use a question mark inside the substitution string, to indicate that the following text should be re-injected into the query string. When you want to erase an existing query string, end the substitution string with just a question mark. To combine a new query string with an old one, use the [QSA] flag.
Source: http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html
This should help you:
RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} Itemid
RewriteRule ^index.php(.*)$ http://www.ligurianotizie.it/archive/index.php$1 [L,R=301]
Every link containing "Itemid" will be redirected, the others not.

htaccess question: Remove 1(!) param from URL query

my URL looks like
page.html?L=0&a=1&b=2&c=6 OR
page.html?a=1&b=2&L=0&c=6 OR
page.html?a=1&b=2&c=6&L=0
I need to delete the L=0, where L can be either 0 or 1. But I need to keep all other params. How can this be done?
Try this rule:
RewriteCond %{QUERY_STRING} ^(([^&]*&+)*)L=[01](&+(.*))?$
RewriteRule ^page\.html$ %{REQUEST_URI}?%1%4 [L,R=301]
Ok, I played around a lot on http://gskinner.com/RegExr/.
I simply can't find a regex that works on all these cases:
domain.com/login.html?p1=1&p2=2&L=0&P3=3
domain.com/login.html?p1=1&p2=2&L=1&P3=3
domain.com/login.html?p1=1&p2=2&L=0
domain.com/login.html?&L=0
domain.com/login.html?L=0
domain.com/login.html?L=0&p1=1&p2=2&P3=3
Last best guess was (.)(L=[a-zA-Z0-9]&?)(&?)(.) >>> $1$3$4
This resulted in
domain.com/login.html?p1=1&p2=2&P3=3
domain.com/login.html?p1=1&p2=2&P3=3
domain.com/login.html?p1=1&p2=2&
domain.com/login.html?&
domain.com/login.html?
domain.com/login.html?p1=1&p2=2&P3=3
What I try is:
- Cut out the L param if it is in the middle
- Cut off the L param if it is at the end of a loner param string
- Cut off the L param AND "?" if it is the only param
Can you provide some more hints?
Ok, another headache and I am finally there. I just post this here in case I
missed something
maybe this can help someone else in a similar situation
.htaccess rule
# Rewrite Typo3 links with multilanguage Param "L"
RewriteCond %{QUERY_STRING} (.*)(^L=[a-zA-Z0-9]+&?|^&L=[a-zA-Z0-9]+&|&L=[a-zA-Z0-9]+)(&?.*)
RewriteRule (.*) %{REQUEST_URI}?%1%3 [L,R=301]
Explanation
The rule tries to cover all the following cases
domain.com/login.html?p1=1&p2=2&L=abc&P3=3
domain.com/login.html?p1=1&p2=2&L=def
domain.com/login.html?&L=eh1
domain.com/login.html?&L=asdfasd&p1=1&p2=2
domain.com/login.html?L=0
domain.com/login.html?L=1&p1=1&p2=2&P3=3
As far as my knowledge goes, the regex works as follow:
(.*) checks if there is anything before the following L-param option
The second ( )-pair group contains 3 alternatives/cases on how the L-param could be present in the query string
the third (.*) simply covers everthing that might follow the L-param
Therefor the replacement only needs %{REQUEST_URI}?%1%3. This will cut out the second ( ) group with the different L-param options.
End result
The URL query string will be stripped of the L-param, but leave everything else.
Any comments? Feel free to vote if this is valuable for you, too.
Thanks to all who helped me find the correct solution!