On some web servers there are more than one URL for a resource. Usually there are canonical URLs (which should be actually used and distributed) and those which are shortcuts, internal URLs, and so on. Independent of which URL is supplied with the request to the user, he should finally only see the canonical URL.
Example: Converting URL /~user to /u/user.
Apache_Rewrite:
rewriterule ^/~([^/]+)/?(.*) /u/$1/$2[R]
AppExpert:
add responder action act1 redirect '"/u/"+ HTTP.REQ.URL.HTTP_URL_SAFE.AFTER_STR ("/~")' add responder policy pol1 'HTTP.REQ.URL.STARTSWITH("/~") && HTTP.REQ.URL.LENGTH.GT(2)' act1 bind responder global pol1 100
The goal of this rule is to force the use of a particular hostname, in preference to other hostnames, which might be used to reach the same site. For example, if you wish to force the use of www.example.com instead of example.com, you might use a variant of the following rules.
Example: Changing example.com to www.example.com
Apache_Rewrite:
# For sites running on a port other than 80 RewriteCond %{HTTP_HOST} !^www.example.com RewriteCond %{HTTP_HOST} !^$ RewriteCond %{SERVER_PORT} !^80$ RewriteRule ^/(.*) http://www.example.com:%{SERVER_PORT}/$1 [L,R] # And for a site running on port 80 RewriteCond %{HTTP_HOST} !^www.example.com RewriteCond %{HTTP_HOST} !^$ RewriteRule ^/(.*) http://www.example.com/$1 [L,R]
AppExpert:
Case 1: for sites running on a port other than 80
add responder action act1 redirect '"http://www.example.com:"+CLIENT.TCP.DSTPORT+HTTP.REQ.URL.HTTP_URL_SAFE' add responder policy pol1 '!HTTP.REQ.HOSTNAME.CONTAINS("www.example.com")&&!HTTP.REQ.HOSTNAME.EQ("")&&!HTTP.REQ.HOSTNAME.PORT.EQ(80)&&HTTP.REQ.HOSTNAME.CONTAINS("example.com")' act1 bind responder global pol1 100 END
Case 2: for sites running on port 80
add responder action act1 redirect '"http://www.example.com” +HTTP.REQ.URL.HTTP_URL_SAFE' add responder policy pol1 '!HTTP.REQ.HOSTNAME.CONTAINS("www.example.com")&&!HTTP.REQ.HOSTNAME.EQ("")&&HTTP.REQ.HOSTNAME.PORT.EQ(80)&&HTTP.REQ.HOSTNAME.CONTAINS("example.com")' act1 bind responder global pol1 100 END
Usually, the Document Root of the web server directly relates to the URL “/”. But in some scenario, the document root could shift to some other directory, also. The following rules can be used to implement this.
Example: Rewrite the url / to /e/www
Apache_Rewrite:
RewriteEngine on RewriteRule ^/$ /e/www/ [R]
AppExpert:
Solution 1: Converting ApacheRewrite example as it is to AppExpert add responder action act1 redirect '"/e/www/"' -bypassSafetyCheck yes add responder policy pol1 'HTTP.REQ.URL.EQ("/")' act1 bind responder global pol1 100
A request might have file path, query, and so on. You can replace the root directory with the new location (path, query, and so on) and rest is present in the redirected request. For example, a request like: /abc/file.html will be redirected to /e/www/abc/file.html
add responder action act1 redirect '"/e/www"+ HTTP.REQ.URL.HTTP_URL_SAFE' add responder policy pol1 '!HTTP.REQ.URL.STARTSWITH("/e/www/")' act1 bind responder global pol1 100 END
In this scenario you want to redirect request for homedirs on a web server to another web server. Usually, such a need arises when establishing a newer web server to replace the old one over time. You must redirect all the requests for a particular homedir to another web server.
Example: Let the hostname for new Web server be newserver.
Apache_Rewrite:
RewriteRule ^/(.+) http://newserver/$1 [R,L]
AppExpert - First Method:
Add responder action act1 redirect '"http://newserver"+ HTTP.REQ.URL.HTTP_URL_SAFE' Add responder policy pol1 'HTTP.REQ.URL.REGEX_MATCH(re#^/(.+)#)' act1 Bind responder global pol1 100 END
AppExpert - Second Method:
Add responder action act1 redirect '"http://newserver"+ HTTP.REQ.URL.HTTP_URL_SAFE' Add responder policy pol1 'HTTP.REQ.URL.LENGTH.GT(1)' act1 Bind responder global pol1 100 END
Some sites with thousands of users usually use a structured homedir layout, that is, each homedir is in a sub-directory which begins, for instance, with the first character of the username. So, /~foo/anypath is /home/f/foo/.www/anypath while /~bar/anypath is /home/b/bar/.www/anypath. The following rules could be used to implement this.
Apache_Rewrite:
RewriteRule ^/~(([a-z])[a-z0-9]+)(.*) /home/$2/$1/.www$3
AppExpert:
Add rewrite action act1 replace 'HTTP.REQ.URL' '"/home/"+ HTTP.REQ.URL.HTTP_URL_SAFE.AFTER_STR ("~").PREFIX(1)+"/"+ HTTP.REQ.URL.HTTP_URL_SAFE.AFTER_STR ("~").BEFORE_STR("/")+"/.www"+ HTTP.REQ.URL.HTTP_URL_SAFE.SKIP (\'/\',1)' Add rewrite policy pol1 'HTTP.REQ.URL.PATH.STARTSWITH("/~")' act1 Bind rewrite global pol1 100
In this scenario, the current URL is not valid and must be redirected to another web server. The following steps could be taken.
You must verify whether the requested filename exists on the server or not. Therefore, if it fails, you must redirect it to another web server (say, webServerB.com). In the case of AppExpert, HTTPCallout is used to verify the presence of the file on server by running a script file_check.cgi on the server. The returned value from HTTPCallout is used to validate the policy.
The Script file_check.cgi takes the URL as the argument and checks for its presence on the server and returns True or False.
Apache_Rewrite:
RewriteCond /your/docroot/%{REQUEST_FILENAME} !-f RewriteRule ^(.+) http://webserverB.com/$1 [R]
AppExpert - First Method:
add HTTPCallout Call set policy httpCallout Call -IPAddress 10.102.59.101 -port 80 -hostExpr '"10.102.59.101"' -returnType BOOL -ResultExpr 'HTTP.RES.BODY(100).CONTAINS("True")' -urlStemExpr '"/cgi-bin/file_check.cgi"' -parameters query=http.req.url.path -headers Name("ddd") add responder action act1 redirect '"http://webserverB.com"+ HTTP.REQ.URL.HTTP_URL_SAFE ' add responder policy pol1 '!HTTP.REQ.HEADER("Name").EXISTS && !SYS.HTTP_CALLOUT(call)' act1 bind responder global pol1 100
AppExpert - Second Method:
Use respondwith in responder action act1, with the help of respondwith, add custom headers, or send some data in body, and so on, like in this example some text in body is added. add HTTPCallout Call set policy httpCallout Call -IPAddress 10.102.59.101 -port 80 -hostExpr '"10.102.59.101"' -returnType BOOL -ResultExpr 'HTTP.RES.BODY(100).CONTAINS("True")' -urlStemExpr '"/cgi-bin/file_check.cgi"' -parameters query=http.req.url.path -headers Name("ddd") add responder action act1 respondwith '"HTTP/1.1 302 Moved Temporarily\r\nLocation: http://webserverB.com"+HTTP.REQ.URL.HTTP_URL_SAFE +"\r\n\r\nHTTPCallout Used"' add responder policy pol1 '!HTTP.REQ.HEADER("Name").EXISTS && !SYS.HTTP_CALLOUT(call)' act1 bind responder global pol1 100
Rewriting the URL based on the time.
Example: Changing the request foo.html to foo.day.html or foo.night.html according to the time.
Apache_Rewrite:
RewriteCond %{TIME_HOUR}%{TIME_MIN} >0700 RewriteCond %{TIME_HOUR}%{TIME_MIN} <1900 RewriteRule ^foo\.html$ foo.day.html [L] RewriteRule ^foo\.html$ foo.night.html
AppExpert:
Add rewrite action act1 insert_before 'HTTP.REQ.URL.PATH.SUFFIX(\'.\',0)' '"day."' Add rewrite action act2 insert_before 'HTTP.REQ.URL.PATH.SUFFIX(\'.\',0)' '"night."' add rewrite policy pol1 'SYS.TIME.WITHIN(LOCAL 07h 00m,LOCAL 18h 59m)' act1 add rewrite policy pol2 'true' act2 bind rewrite global pol1 101 bind rewrite global pol2 102
Assume you have recently renamed the page foo.html to bar.html and now want to provide the old URL for backward compatibility. Actually, you want users of the old URL to not even recognize that the pages were renamed.
Rewrite the old URL to the new one internally using the following rule, let the base directory be /~quux/.
Apache_Rewrite:
RewriteEngine on RewriteBase /~quux/ RewriteRule ^foo\.html$ bar.html
AppExpert - Solution 1: Converting the ApacheRewrite example, as it is, to APPExpert
add rewrite action act1 replace 'HTTP.REQ.URL.AFTER_STR("/~quux").SUBSTR("foo.html")' '"bar.html"' add rewrite policy pol1 'HTTP.REQ.URL.ENDSWITH("/~quux/foo.html")' act1 bind rewrite global pol1 100
AppExpert - Solution 2 Generic Case: The above case was not generic because it was expecting foo.html to be directly under directory /~quux/. A more generic case is to convert a file foo.html to bar.html without considering any base directory. Also, a request URL could come with some query.
Add rewrite action act1 replace 'HTTP.REQ.URL.PATH.SUFFIX(\'/\',0)' '"bar.html"' Add rewrite policy pol1 'HTTP.REQ.URL.PATH.CONTAINS("foo.html")' act1 Bind rewrite global pol1 100
Assume that you have recently renamed the page foo.html to bar.html and now want to provide the old URL for backward compatibility. But this time, you want the users of the old URL to get directed to the new one, that is, their browsers Location field should change, too.
The following rules can force an HTTP redirect to the new URL, which leads to a change of the browsers and thus the user view:
Apache_Rewrite:
RewriteEngine on RewriteBase /~quux/ RewriteRule ^foo\.html$ bar.html [R]
AppExpert - Solution 1: Converting the ApacheRewrite example, as it is, to APPExpert
add responder action act1 redirect 'HTTP.REQ.URL.HTTP_URL_SAFE.BEFORE_STR("foo.html")+"bar.html"' add responder policy pol1 'HTTP.REQ.URL.ENDSWITH("/~quux/foo.html")' act1 bind responder global pol1 100
AppExpert - Solution 2 Generic Case: The above case was not generic because it was expecting foo.html to be directly under the /~quux/ directory. A more generic case is to convert a file foo.html to bar.html without considering any base directory. Also, a request URL could come with some query.
add responder action act1 redirect 'HTTP.REQ.URL.PATH.HTTP_URL_SAFE.BEFORE_STR("foo.html")+"bar.html"+HTTP.REQ.URL.HTTP_URL_SAFE.AFTER_STR("foo.html")' add responder policy pol1 'HTTP.REQ.URL.PATH.CONTAINS("foo.html")' act1 bind responder global pol1 100
At least for important top-level pages, it is sometimes necessary to provide the optimum of browser-dependent content, that is, you have to provide a maximum version for the latest Netscape variants, a minimum version for the Lynx browsers, and an average feature version for all others.
Act on the HTTP header "User-Agent". The following configuration does the following: If the HTTP header "User-Agent" begins with "Mozilla/3", then the page foo.html rewrites to foo.NS.html and the rewriting stops. If the browser is "Lynx" or "Mozilla", of version 1 or 2, the URL becomes foo.20.html. All other browsers receive page foo.32.html. This is done by the following rule set:
Apache_Rewrite:
RewriteCond %{HTTP_USER_AGENT} ^Mozilla/3.* RewriteRule ^foo\.html$ foo.NS.html [L] RewriteCond %{HTTP_USER_AGENT} ^Lynx/.* [OR] RewriteCond %{HTTP_USER_AGENT} ^Mozilla/[12].* RewriteRule ^foo\.html$ foo.20.html [L] RewriteRule ^foo\.html$ foo.32.html [L]
AppExpert:
Add patset pat1 Bind patset pat1 Mozilla/1 Bind Patset pat1 Mozilla/2 Bind patset pat1 Lynx Bind Patset pat1 Mozilla/3 add rewrite action act1 insert_before 'HTTP.REQ.URL.SUFFIX' '"NS."' add rewrite action act2 insert_before 'HTTP.REQ.URL.SUFFIX' '"20."' add rewrite action act3 insert_before 'HTTP.REQ.URL.SUFFIX' '"32."' add rewrite policy pol1 'HTTP.REQ.HEADER("User-Agent").STARTSWITH_INDEX("pat1").EQ(4)' act1 add rewrite policy pol2 'HTTP.REQ.HEADER("User-Agent").STARTSWITH_INDEX("pat1").BETWEEN(1,3)' act2 add rewrite policy pol3 '!HTTP.REQ.HEADER("User-Agent").STARTSWITH_ANY("pat1")' act3 bind rewrite global pol1 101 END bind rewrite global pol2 102 END bind rewrite global pol3 103 END
You can block a really annoying robot from retrieving pages of a specific web area and ease-up the traffic at some directories.
This could be done by using a rule set which forbids the URLs of the web area /~quux/foo/arc/. This could also be accomplished by matching the User-Agent HTTP header information. Let the IP addresses to block be 10.45.67.8 and 10.45.67.9.
Apache_Rewrite:
RewriteCond %{HTTP_USER_AGENT} ^NameOfBadRobot.* RewriteCond %{REMOTE_ADDR} ^10\.45\.67\.[8-9]$ RewriteRule ^/~quux/foo/arc/.+ - [F]
AppExpert:
add responder action act1 respondwith '"HTTP/1.1 403 Forbidden\r\n\r\n"' add responder policy pol1 'HTTP.REQ.HEADER("User_Agent").STARTSWITH("NameOfBadRobot")&& (CLIENT.IP.SRC.EQ(10.45.67.8) || CLIENT.IP.SRC.EQ(10.45.67.9)) && HTTP.REQ.URL.STARTSWITH("/~quux/foo/arc")' act1 bind responder global pol1 100
Assume you have under http://www.example.de/~quux/ some pages with inline GIF graphics. These graphics are nice, so others directly incorporate them using hyperlinks to their pages. You do not like this practice because it adds useless traffic to your server.
You can restrict the cases where the browser sends an HTTP Referer header.
Apache_Rewrite:
RewriteCond %{HTTP_REFERER} !^$ RewriteCond %{HTTP_REFERER} !^http://www.example.de/~quux/.*$ RewriteRule .*\.gif$ - [F]
AppExpert:
Add patset pat1 Bind patset pat1 .gif Bind patset pat1 .jpeg add responder action act1 respondwith '"HTTP/1.1 403 Forbidden\r\n\r\n"' add responder policy pol1 '!HTTP.REQ.HEADER("Referer").EQ("") && !HTTP.REQ.HEADER("Referer").STARTSWITH("http://www.example.de/~quux/")&&HTTP.REQ.URL.ENDSWITH_ANY("pat1")' act1 bind responder global pol1 100
Sometimes you might want to support extensionless links, either to hide extension from end users or to make the URL easy to remember.
This behavior is achieved by adding the extension on the fly using the following rewrite rules.
Case 1: Add a .php extension to all requests
Apache_Rewrite:
RewriteRule ^/?([a-z]+)$ $1.php [L]
AppExpert:
Add rewrite action act1 insert_after 'HTTP.REQ.URL' '".php"' add rewrite policy pol1 'HTTP.REQ.URL.PATH.REGEX_MATCH(re#^/([a-z]+)$#)' act1 Bind rewrite global pol1 100
Case 2: If you have a mixture of both .html and .php files , then you can use the following rules:
Apache_Rewrite:
RewriteCond %{REQUEST_FILENAME}.php -f RewriteRule ^/?([a-zA-Z0-9]+)$ $1.php [L] RewriteCond %{REQUEST_FILENAME}.html –f RewriteRule ^/?([a-zA-Z0-9]+)$ $1.html [L]
AppExpert: Here HTTPCallout is used. Script file_check.cgi, hosted on 10.102.59.101, is used to check whether a provided argument is a valid file name or not.
add HTTPCallout Call_html add HTTPCallout Call_php set policy httpCallout Call_html -IPAddress 10.102.59.101 -port 80 -hostExpr '"10.102.59.101"' -returnType BOOL -ResultExpr 'HTTP.RES.BODY(100).CONTAINS("True")' -urlStemExpr '"/cgi-bin/file_check.cgi"' -parameters query=http.req.url+".html" set policy httpCallout Call_php -IPAddress 10.102.59.101 -port 80 -hostExpr '"10.102.59.101"' -returnType BOOL -ResultExpr 'HTTP.RES.BODY(100).CONTAINS("True")' -urlStemExpr '"/cgi-bin/file_check.cgi"' -parameters query=http.req.url+".php" Add patset pat1 Bind patset pat1 .html Bind patset pat1 .php Bind patset pat1 .asp Bind patset pat1 .cgi Add rewrite action act1 insert_after 'HTTP.REQ.URL.PATH' '".html"' Add rewrite action act2 insert_after "HTTP.REQ.URL.PATH" '".php"' Add rewrite policy pol1 '!HTTP.REQ.URL.CONTAINS_ANY("pat1") && SYS.HTTP_CALLOUT(Call_html)' act1 Add rewrite policy pol2 '!HTTP.REQ.URL.CONTAINS_ANY("pat1") && SYS.HTTP_CALLOUT(Call_php)' act2 Bind rewrite global pol1 100 END Bind rewrite global pol2 101 END
In an example, say that you have a set of working URLs that look like this: /index.php?id=nnnn. However, you would really like to change them to /nnnn and make sure search engines update their indexes to the new URI format. First, you must redirect the old URIs to the new ones so that search engines update their indexes, but you still must rewrite the new URI back to the old one so that the index.php script runs.
Place a marker code into the query string that visitors cannot see. Redirect from the old link to the new format only if the marker is not present in the query string. Then, rewrite the new format link back to the old format and add a marker to the query string.
Apache_Rewrite:
RewriteCond %{QUERY_STRING} !marker RewriteCond %{QUERY_STRING} id=([-a-zA-Z0-9_+]+) RewriteRule ^/?index\.php$ %1? [R,L] RewriteRule ^/?([-a-zA-Z0-9_+]+)$ index.php?marker&id=$1 [L]
AppExpert:
Add responder action act_redirect redirect 'HTTP.REQ.URL.PATH.HTTP_URL_SAFE.BEFORE_STR("index.php")+HTTP.REQ.URL.QUERY.VALUE("id").HTTP_URL_SAFE' Add responder policy pol_redirect '!HTTP.REQ.URL.QUERY.CONTAINS("marker")&& HTTP.REQ.URL.QUERY.VALUE("id").REGEX_MATCH(re/[-a-zA-Z0-9_+]+/) && HTTP.REQ.URL.PATH.CONTAINS("index.php")' act_redirect Bind responder global pol_redirect 100 END Add rewrite action act1 replace 'HTTP.REQ.URL.PATH.SUFFIX(\'/\',0)' '"index.phpmarker&id="+ HTTP.REQ.URL.HTTP_URL_SAFE.SUFFIX (\'/\',0)' Add rewrite policy pol1 '!HTTP.REQ.URL.QUERY.CONTAINS("marker")' act1 Bind rewrite global pol1 100 END
In scenarios where you want to ensure that for some selected pages only secure server are used, use the following rules.
Apache_Rewrite:
RewriteCond %{SERVER_PORT} !^443$ RewriteRule ^/?(page1|page2|page3|page4|page5)$ https://www.example.com/%1 [R,L]
AppExpert - First Method:
Add responder action res_redirect redirect '"https://www.example.com"+HTTP.REQ.URL' -bypassSafetyCheck yes Add responder policy pol_redirect '!CLIENT.TCP.DSTPORT.EQ(443)&&HTTP.REQ.URL.REGEX_MATCH(re/page[1-5]/)' res_redirect Bind responder global pol_redirect 100 END
AppExpert - Second Method:
Add patset pat1 Bind patset pat1 page1 Bind patset pat1 page2 Bind patset pat1 page3 Bind patset pat1 page4 Bind patset pat1 page5 Add responder action res_redirect redirect '"https://www.example.com"+HTTP.REQ.URL.HTTP_URL_SAFE' Add responder policy pol_redirect '!CLIENT.TCP.DSTPORT.EQ(443)&&HTTP.REQ.URL.CONTAINS_ANY("pat1")' res_redirect Bind responder global pol_redirect 100 END