.htaccess redirect with attributes - regex

I am trying to make a .htaccess redirect rule to achieve the following
https://www.example.net/index.php?a=in&u=testUser&api_key=4r98f4r98f&ip_address=127.0.0.1
TO
https://www.example.net/api.php?ip=127.0.0.1&username=testUser
but i can't make it work, any hint?
RewriteEngine on
RewriteCond %{QUERY_STRING} ^a=([^&]+)&u=([^&]+)&api_key=([^&]+)&api_key=([^&]+)&ip_address=([^&]+)$ [NC]
RewriteRule ^index\.php$ https://www.example.net/api.php?ip=%5&username=%2? [NC,L,R]

You have api_key parameter twice in your condition, moreover don't capture a value that you don't need to reuse in the target. You also have an extra misplaced ? at the end.
Have your rule like this:
RewriteCond %{QUERY_STRING} ^a=[^&]*&u=([^&]+)&api_key=[^&]*&ip_address=([^&]+)$ [NC]
RewriteRule ^index\.php$ /api.php?ip=%2&username=%1 [NC,L,NE,R=302]

Related

Handle one query parameter specifically

I need to handle one query parameter specifically.
The url can look like the following:
https://example.com/?app=egov&map=1337
https://example.com/?app=egov&map=1337&showoptions=true
https://example.com/?app=egov&map=1337&showoptions=true&anotherparam=helloWorld
The redirect should point to
https://example.com/contextName/resources/apps/egov/index.html?map=1337
https://example.com/contextName/resources/apps/egov/index.html?map=1337&showoptions=true
https://example.com/contextName/resources/apps/egov/index.html?map=1337&anotherparam=helloWorld
As you can see, the app-Parameter needs to be used as an URL-part; the others need to be used like traditional query-params.
I've figured out, how to implement the first part, where https://example.com/?app=egov points to https://example.com/contextName/resources/apps/egov/index.html using the following
RewriteCond %{REQUEST_URI} ^/$
RewriteCond %{QUERY_STRING} ^app\=(.+)
RewriteRule ^/$ "/contextName/resources/apps/%1/index.html" [R,L,QSA]
but I'm struggeling how to realize the correct handling of the other params.
All these combination of query string can be handled by a single rule loke this:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^app=([\w-]+)(?:&(.*))?$ [NC]
RewriteRule ^$ contextName/resources/apps/%1/index.html?%2 [L]
RewriteCond matches app query parameter and captures it in %1 while rest of the query string after & is captured in %2.
With your shown samples, please try following htaccess Rules file. Please make sure to clear your browser cache before testing your URLs.
RewriteEngine ON
####Apache documentation link https://httpd.apache.org/docs/trunk/rewrite/remapping.html for more info.
##Internal rewrite rule for URL https://example.com/?app=egov&map=1337
RewriteCond %{QUERY_STRING} ^app=([^&]*)&map=(\d+)$ [NC]
RewriteRule ^/?$ contextName/resources/apps/%1/index.html?map=%2 [L]
##Internal rewrite rule for URL https://example.com/?app=egov&map=1337&showoptions=true
RewriteCond %{QUERY_STRING} ^app=([^&]*)&map=(\d+)&showoptions=(.*)$ [NC]
RewriteRule ^/?$ contextName/resources/apps/%1/index.html?map=%2&showoptions=%3 [L]
##Internal rewrite rule for https://example.com/?app=egov&map=1337&showoptions=true&anotherparam=helloWorl
RewriteCond %{QUERY_STRING} ^app=([^&]*)&map=(\d+)&showoptions=([^&]*)&anotherparam=(.*)$ [NC]
RewriteRule ^/?$ contextName/resources/apps/%1/index.html?map=%2&anotherparam=%4 [L]
All of your URLs uri part is NULL, so rules are written based on that.

.htaccess rewrite w/ regular expression and ?lang=en parameter

I need a hand with creating a regex rewrite rule for my .htaccess.
Here's the problem. My previous URLs structure was:
http://example.com/whatever-the-url-is/?lang=en
now I turned it into
http://example.com/en/whatever-the-url-is/
I'd like to create an .htaccess URL that 301 redirects all the URLs from the previous structure to the new one.
Also the .htaccess is shared between different domains, and so there should be
RewriteCond %{http_host} !^example.com$ [NC] condition at the beginning...
Is it possible? Do you have any suggestions?
You can use:
RewriteEngine on
RewriteCond %{HTTP_HOST} !^example.com$ [NC]
RewriteCond %{QUERY_STRING} (?:^|&)lang=(.+?)(?:&|$) [NC]
RewriteRule ^(.*)$ /%1/$1? [R=301,L]
You can add the RewriteRule after RewriteCond %{HTTP_HOST}:
RewriteCond %{REQUEST_URI} !^/(?:en|fr|sp)/ [NC]
Where you test if langcode is already in the url.

Rewrite URL's with variable query string placement with .htaccess

I'm trying to rewrite a few different URL's so they redirect to different places, however they aren't static URL's.
I need to redirect:
/index.php?app=core&section=register
to for example:
htttp://www.mysite.com/register.php
However, what I want to do is just make sure that /index.php?app=core&section=register starts with /index.php? but there may be more parameters included and also want to make sure it's still redirected if they are in a different position, so basically it just needs to match it if app=core and section=register exists in the URL.
Lastly, if I wanted to add a second one such as..
/index.php?app=core&section=login to htttp://www.mysite.com/login.php how would I add a second one?
Try this rule:
RewriteCond %{QUERY_STRING} (?:^|&)app=core(?:&|$) [NC]
RewriteCond %{QUERY_STRING} (?:^|&)section=(register|login)(?:&|$) [NC]
RewriteRule ^index\.php$ /%1.php? [NC,L,R=302]
As per comments:
RewriteCond %{QUERY_STRING} (?:^|&)app=core(?:&|$) [NC]
RewriteCond %{QUERY_STRING} (?:^|&)section=(somepath)(?:&|$) [NC]
RewriteRule ^index\.php$ /mypath.php? [NC,L,R=302]

How to remove any query except `callback` for specific URLs with RewriteRule?

The current RewriteRule removes any query except query callback for any URL.
# Remove question mark and parameters
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^?#\ ]*)\?[^\ ]*\ HTTP/ [NC]
# Query rewrite exceptions
##RewriteCond %{REQUEST_URI}?%{QUERY_STRING} !^/api.*?callback=.* #does not work
RewriteCond %{QUERY_STRING} !callback=
RewriteRule .*$ %{REQUEST_URI}? [R=301,L]
How to avoid query callback rewrite just from URL ^api\/?([^\/]*)$? Excepted result:
no rewrite for /api?callback=1, /api/user?callback=1, /api/user/2?callback=1
rewrite for /apis?callback=1, /user?callback=1, /api/user?foo=1 etc.
I finally understood your question...
Replace these lines:
##RewriteCond %{REQUEST_URI}?%{QUERY_STRING} !^/api.*?callback=.* #does not work
RewriteCond %{QUERY_STRING} !callback=
with this line:
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} !^/api(/.*)?\?callback=.*
Important notice:
if your script isn't located in the document root, but, i.e., in dir /htest,
and full URL looks like mine: http://localhost/htest/api/?callback=1, then you have to put full path to API in your RewriteCond:
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} !^/htest/api(/.*)?\?callback=.*
You can overcome that by beginning your regex with !/api instead of ^/path/to/api, but /foo/api and /bar/api will be skipped from rewriting too.
Update:
this .htaccess works fine in document root:
RewriteEngine On
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^?#\ ]*)\?[^\ ]*\ HTTP/ [NC]
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} !^/api(/.*)?\?callback=.*
RewriteRule .*$ %{REQUEST_URI}? [R=temporary,L]
you may try using it without any other rules to check what is wrong
Update 2
If you have other condition, i.e.,
RewriteRule ^([^.]*)$ index.php?url=$1 [QSA,L]
repeat RewriteCond before it:
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} !^/api(/.*)?\?callback=.*
RewriteRule ^([^.]*)$ index.php?url=$1 [QSA,L]
also to be able to use these rules in /foo subdir, replace ^/api with ^/foo/api
To enable RewriteRule for index.php, need to add in query rewrite exceptions.
This rules works fine and fixes this issue:
# Remove question mark and parameters
RewriteCond %{QUERY_STRING} .+
# Query rewrite exceptions
RewriteCond %{REQUEST_FILENAME} !index.php
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} !/api(/.*)?\?callback=.*
RewriteRule .*$ %{REQUEST_URI}? [R=301,L]

Using MOD_REWRITE for URL variables and removing empty parameters when not used

I am trying to create a mod_rewrite that when a user enters, or it shows in the URL:
www.example.com/var1/var2/var3/var4/
it outputs the same as
www.example.com?page=var1&cat=var2&subcat=var3&subsubcat=var4
but if there is a change in the number variables, it will still work, so the variables could be:
www.example.com/var1/
or
www.example.com/var1/var2/
or
www.example.com/var1/var2/var3/
or
www.example.com/var1/var2/var3/var4/
If I use the following, it only works for www.example.com/var1/var2/var3/var4/ but not the others:
Options +FollowSymLinks RewriteEngine On RewriteBase /
RewriteRule ^([^&]+)/([^&]*)/([^&]*)/([^&]*)/$ /?page=$1&cat=$2&subcat=$3&subsubcat=$4 [L]
If I use the following code using CHAINING, it works as a chain to an extent, but the problem is that for
www.example.com/var1/var2/
www.example.com/var1/var2/var3/
www.example.com/var1/var2/var3/var4/
it outputs the VAR1 as "/", so it is ignoring the first variable using the following code:
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteRule ^([^&]+)/$ /?page=$1 [C]
RewriteRule ^([^&]+)/([^&]*)/$ /?page=$1&cat=$2 [C]
RewriteRule ^([^&]+)/([^&]*)/([^&]*)/$ /?page=$1&cat=$2&subcat=$3 [C]
RewriteRule ^([^&]+)/([^&]*)/([^&]*)/([^&]*)/$ /?page=$1&cat=$2&subcat=$3&subsubcat=$4 [L]
The order is always the same so this should be easy. How can I make this work please?
Probably I am missing something but IMO you don't need chaining C flag here. Please consider these rules:
RewriteEngine on
Options +FollowSymlinks -MultiViews
RewriteCond %{QUERY_STRING} !^page= [NC]
RewriteRule ^([^/]+)/?$ /?page=$1 [L]
RewriteCond %{QUERY_STRING} !^page= [NC]
RewriteRule ^([^/]+)/([^/]*)/?$ /?page=$1&cat=$2 [L]
RewriteCond %{QUERY_STRING} !^page= [NC]
RewriteRule ^([^/]+)/([^/]*)/([^/]*)/?$ /?page=$1&cat=$2&subcat=$3 [L]
RewriteCond %{QUERY_STRING} !^page= [NC]
RewriteRule ^([^/]+)/([^/]*)/([^/]*)/([^/]*)/?$ /?page=$1&cat=$2&subcat=$3&subsubcat=$4 [L]
I added RewriteCond %{QUERY_STRING} !^page= [NC] in all rules to make sure there is infinite looping. Also I made trailing slash optional by adding ? in the end of each rule.
All of above rules are working fine in my testing.