RewriteRule expression not working - apache

I want to rewrite a URl to another, but the Rewrite expression is not working.
Ex. URL1: "http://www.demo.com/de-ch/case1/?id=23"
And
Ex. URL2: 'http://www.demo.com/de-ch?id=23'
RULE: RewriteRule ^(.....)([\?]|(.*))$ http://www.result.com/$1
This rule gives follow result:
http://www.result.com/de-ch?id=23
But I just need the iso codes http://www.result.com/de-ch
What am I missing in the Regex?

You can't match against the query string in the rule's pattern. The query string isn't technically part of the path. You'll need to use a RewriteCond and the %{QUERY_STRING} variable:
RewriteCond %{QUERY_STRING} ^id=23
RewriteRule ^(.....) http://www.result.com/$1?
Note the "?" at the end of the rule's result. That will remove the query string.
However, since you're not doing anything with the query string, you can just leave it out entirely and only have:
RewriteRule ^(.....) http://www.result.com/$1?
Note that this rule will cause the browser to get redirected to http://www.result.com/de-ch and if you don't have a resource that resolves at that URL, then you'll simply get a 404 or some related error.

Related

Rewrite URL containing directory path and parameters to parameter based URL using both path and query string

I use htaccess to rewrite this path:
/inventory/products/tools/
to this url with query string:
/inventory.php?cat=products&type=tools
using the following rule:
RewriteRule ^inventory/(.*)/(.*)/? /inventory.php?cat=$1&type=$2 [L,R=301]
When I add a query string to my url path
/inventory/products/tools/?sort=pricehigh
and use this rule
RewriteCond %{QUERY_STRING} ^(.*)$ [NC]
RewriteRule ^inventory/(.*)/(.*)/? /inventory.php?cat=$1&type=$2&%1 [L,R=301]
I am getting a redirect loop and the urlstring is rewritten over and over
I am trying to end up with the following destination url
/inventory.php?cat=products&type=tools&sort=pricehigh
In the example rule above I am using R=301 in order to visualize the url.
In a production I would use [L] only
Without the trailing slash, the second (.*) also allows for matching zero characters - so due to the greediness of regular expressions, the first (.*) matches products/tools already.
The following should work:
RewriteRule ^inventory/([^/]+)/([^/]+)/?$ /inventory.php?cat=$1&type=$2 [QSA,L,R=302,NE]
([^/]+) demands one or more characters, out of the class of characters that contains everything but the /.
The NE/noescape flag seems necessary here for some reason, otherwise the resulting query string will contain ?cat=products%26type=..., with the & URL-encoded.

Remove Query String from the end of the URL after passing through Rewrite Map

I have a list of several hundred URL redirects/rewrites inside of a rewrite map. Most of the URL's contain query strings that match a specific entry in the rewrite map. I found this question on how to pass the query string into the rewrite map. I got this working fine but the problem now is that the existing query string is appended to the end of the rewritten URL. For example:
Expected Rewrite:
/subdir/dir.cfm?categoryID=123 -> https://example.com/subdir/endurl
Actual Rewrite:
https://example.com/subdir/endurl?categoryID=123
Expected Rewrite
/subdir/dir.cfm?videoID=3422424-131FDDFD-234 -> https://example.com/subdir/awesome/stuff
Actual Rewrite:
https://example.com/subdir/awesome/stuff?videoID=3422424-131FDDFD-234
This is the rewrite rules I have:
RewriteEngine on
RewriteMap redirects dbm=sdbm:C:\Apache24\conf\redirects.sdbm
RewriteCond ${redirects:$1} !=""
RewriteRule ^(.*\.(cfm|cfml)) ${redirects:$1?%{QUERY_STRING}} [NC,R=301,L]
How can I remove the query string appended to the URL after the rewrite?
EDIT
I was able to actually get this working using this:
RewriteMap redirects dbm=sdbm:C:\Apache24\conf\redirects.sdbm
RewriteCond ${redirects:$1} !=""
RewriteRule ^(.*\.(cfm|cfml)) ${redirects:$1?%{QUERY_STRING}} [NC,C]
RewriteRule (.*) $1? [L,R=301]
However I am not sure if someone knows of a better way to accomplish what I am doing? I am thinking this might break if I ever have to redirect to a URL that contains a query string to another url that contains a query string.
In Apache version 2.4.0 and later, you can use [QSD] flag (Query String Discard):
RewriteRule ^(.*\.(cfm|cfml)) ${redirects:$1?%{QUERY_STRING}} [QSD,NC]
In Apache version 2.2, there is no [QSD] flag, but if the replacement URI contains a query string, the default behavior of RewriteRule is to discard the existing query string, so by just adding a ? to your rewrite URI, you will get the same effect:
RewriteRule ^(.*\.(cfm|cfml)) ${redirects:$1?%{QUERY_STRING}}? [NC]
(your newly added rewrite rule actually uses this feature)

How I can rewrite a query-string based URL only partially

I want to rewrite the following URL, based on part of its query string, but at the same time, I want to keep the rest of the Query String.
Original URL:
http://example.com/index.php?route=product/show&item_id=25&show_mobile=true
To be converted to:
http://example.com/product/show/?item_id=25&show_mobile=true
I have searched and found the following wiki on Apache:
https://wiki.apache.org/httpd/RewriteQueryString
But it hasn't a section for rewriting a single Key&Value pair in Query string and keeping the rest.
This should get you close, it's based on the "remove a key" entry from the wiki. You want to isolate the part that will go into the path in the first capture and use the 2nd capture for the remaining query string.
RewriteCond %{QUERY_STRING} ^(route=[^&]*)&(.*)
RewriteRule ^index.php /%1?%2
You can use this generic rule to capture parameter value of route in any order from query string and reuse in target URL:
RewriteEngine On
RewriteCond %{THE_REQUEST} \?(.*&)?route=([^&]*)&?(\S*)\sHTTP [NC]
RewriteRule ^index\.php$ /%2?%1%3 [R=301,NE,L]

How to mod_rewrite redirect php-file-url to new path

I want to redirect
http://api.domain.com/api.php?debug=true
to
http://api.domain.com/getData/?debug=true
What's wrong?
RewriteCond %{REQUEST_URI} !^/api\.php/.*
RewriteRule ^(.*)$ /getData/$1
Also not working
RewriteRule ^/api\.php(.*)$ /getData/$1 [PT]
That did the job
RewriteRule ^api.php$ /getData/
Let me first tell you what is wrong with your two attempts:
RewriteCond %{REQUEST_URI} !^/api\.php/.*
RewriteRule ^(.*)$ /getData/$1
This translates to: If the URI part of the url (after the domain and before the query string) does not match api.php, translate ^(.*)$ to /getData/$1. You want however to do it when the uri does match that string, making the condition obsolete.
RewriteRule ^/api\.php(.*)$ /getData/$1 [PT]
You tried to match the query string here with (.*), but that is not how it works. Besides that, in per-directory context (which is what .htaccess is), the url never starts with a slash. ^/ therefore never ever matches.
If you don't define a query string in the rewritten part, then the query string of the old url is appended to the new url. The correct rewriterule would be:
RewriteRule ^api\.php$ getData [R=301,L]
Please note that \. means "a literal dot". If I wouldn't escape it, then apisphp would redirect too. The R=301 flag will make it an external permanent redirect. The L flag will say that this is the last rule to match for this run through .htaccess. This is to prevent other rules matching on the full url, causing all kind of weird behaviour.

url rewriting problem

I'm trying to map any request like /?page=pagename to this /html/pagename.html ( sort of opposite of what people normally do), so for example if the request was mydomain.com/?page=home then I want my server to return this file : /html/home.html
I tried this rule, but gives my error 500 :
RewriteRule ?page=(.*) /html/$1.html [NC]
any idea folks ?
Try this:
RewriteCond %{QUERY_STRING} page=(.*)
RewriteRule .* /html/%1.html [NC]
RewriteRule matches and rewrites only URIs. The query string (the stuff after the question mark) is not part of the URI, so it'll never match against a RewriteRule pattern. You have to use a RewriteCond to conditionally evaluate a rule (in this case, on every URI) when the query string matches something.