Product Documentation

Migration of Apache mod_rewrite Rules to the Default Syntax

May 26, 2015

The Apache HTTP Server provides an engine known as mod_rewrite for rewriting HTTP request URLs. If you migrate the mod_rewrite rules from Apache to the NetScaler, you boost back-end server performance. In addition, because the NetScaler typically load balances multiple (sometimes thousands of) Web servers, after migrating the rules to the NetScaler you will have a single point of control for these rules.

Following are examples of mod_rewrite functions, and translations of these functions into Rewrite and Responder policies on the NetScaler.

Converting URL Variations into Canonical URLs

On some Web servers you can have multiple URLs for a resource. Although the canonical URLs should be used and distributed, other URLs can exist as shortcuts or internal URLs. You can make sure that users see the canonical URL regardless of the URL used to make an initial request.

In the following examples, the URL /~user is converted to /u/user.

Apache mod_rewrite solution for converting a URL

RewriteRule   ^/~([^/]+)/?(.*)    /u/$1/$2[R] 

NetScaler solution for converting a URL

add responder action act1 redirect '"/u/"+HTTP.REQ.URL.AFTER_STR("/~")' -bypassSafetyCheck yes 
add responder policy pol1 'HTTP.REQ.URL.STARTSWITH("/~") && HTTP.REQ.URL.LENGTH.GT(2)' act1  
bind responder global pol1 100

Converting Host Name Variations to Canonical Host Names

You can enforce the use of a particular host name for reaching a site. For example, you can enforce the use of www.example.com instead of example.com.

Apache mod_rewrite solution for enforcing a particular host name 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] 

Apache mod_rewrite solution for enforcing a particular host name for sites running on port 80

 
RewriteCond %{HTTP_HOST}   !^www.example.com  
RewriteCond %{HTTP_HOST}   !^$ 
RewriteRule ^/(.*)         http://www.example.com/$1 [L,R] 

NetScaler solution for enforcing a particular host name for sites running on a port other than 80

 
add responder action act1 redirect '"http://www.example.com:"+CLIENT.TCP.DSTPORT+HTTP.REQ.URL' -bypassSafetyCheck yes 
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 

NetScaler solution for enforcing a particular host name for sites running on port 80

 
add responder action act1 redirect '"http://www.example.com"+HTTP.REQ.URL' -bypassSafetyCheck yes 
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 

Moving a Document Root

Usually the document root of a Web server is based on the URL “/”. However, the document root can be any directory. You can redirect traffic to the document root if it changes from the top-level “/” directory to another directory.

In the following examples, you change the document root from / to /e/www. The first two examples simply replace one string with another. The third example is more universal because, along with replacing the root directory, it preserves the rest of the URL (the path and query string), for example, redirecting /example/file.html to /e/www/example/file.html.

Apache mod_rewrite solution for moving the document root

 
RewriteEngine on 
RewriteRule   ^/$  /e/www/  [R] 

NetScaler solution for moving the document root

 
add responder action act1 redirect '"/e/www/"' -bypassSafetyCheck yes 
add responder policy pol1 'HTTP.REQ.URL.EQ("/")' act1 
bind responder global pol1 100 

NetScaler solution for moving the document root and appending path information to the request

 
add responder action act1 redirect '"/e/www"+HTTP.REQ.URL' -bypassSafetyCheck yes 
add responder policy pol1 '!HTTP.REQ.URL.STARTSWITH("/e/www/")' act1 
bind responder global pol1 100 END 

Moving Home Directories to a New Web Server

You may want to redirect requests that are sent to home directories on a Web server to a different Web server. For example, if a new Web server is replacing an old one over time, as you migrate home directories to the new location you need to redirect requests for the migrated home directories to the new Web server.

In the following examples, the host name for the new Web server is newserver.

Apache mod_rewrite solution for redirecting to another Web server

 
RewriteRule   ^/(.+)  http://newserver/$1     [R,L] 

NetScaler solution for redirecting to another Web server (method 1)

 
add responder  action act1 redirect '"http://newserver"+HTTP.REQ.URL' -bypassSafetyCheck yes 
add responder policy pol1 'HTTP.REQ.URL.REGEX_MATCH(re#^/(.+)#)'   act1 
bind responder global pol1 100 END 

NetScaler solution for redirecting to another Web server (method 2)

 
add responder  action act1 redirect '"http://newserver"+HTTP.REQ.URL' -bypassSafetyCheck yes 
add responder policy pol1 'HTTP.REQ.URL.LENGTH.GT(1)' act1 
bind responder global pol1 100 END 

Working with Structured Home Directories

Typically, a site with thousands of users has a structured home directory layout. For example, each home directory may reside under a subdirectory that is named using the first character of the user name. For example, the home directory for jsmith (/~jsmith/anypath) might be /home/j/smith/.www/anypath, and the home directory for rvalveti (/~rvalveti/anypath) might be /home/r/rvalveti/.www/anypath.

The following examples redirect requests to the home directory.

Apache mod_rewrite solution for structured home directories

 
RewriteRule   ^/~(([a-z])[a-z0-9]+)(.*)  /home/$2/$1/.www$3 

NetScaler solution for structured home directories

 
NetScaler solution for structured home directories 
 
add rewrite action act1 replace 'HTTP.REQ.URL'  '"/home/"+ HTTP.REQ.URL.AFTER_STR("~").PREFIX(1)+"/"+ HTTP.REQ.URL.AFTER_STR("~").BEFORE_STR("/")+"/.www"+HTTP.REQ.URL.SKIP(\'/\',1)'  -bypassSafetyCheck yes 
add rewrite policy pol1  'HTTP.REQ.URL.PATH.STARTSWITH("/~")' act1 
bind rewrite global pol1 100 

Redirecting Invalid URLs to Other Web Servers

If a URL is not valid, it should be redirected to another Web server. For example, you should redirect to another Web server if a file that is named in a URL does not exist on the server that is named in the URL.

On Apache, you can perform this check using mod_rewrite. On the NetScaler, an HTTP callout can check for a file on a server by running a script on the server. In the following NetScaler examples, a script named file_check.cgi processes the URL and uses this information to check for the presence of the target file on the server. The script returns TRUE or FALSE, and the NetScaler uses the value that the script returns to validate the policy.

In addition to performing the redirection, the NetScaler can add custom headers or, as in the second NetScaler example, it can add text in the response body.

Apache mod_rewrite solution for redirection if a URL is wrong

 
RewriteCond   /your/docroot/%{REQUEST_FILENAME} !-f 
RewriteRule   ^(.+)      http://webserverB.com/$1 [R] 

NetScaler solution for redirection if a URL is wrong (method 1)

 
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' -bypassSafetyCheck yes 
add responder policy pol1 '!HTTP.REQ.HEADER("Name").EXISTS  &&  !SYS.HTTP_CALLOUT(call)' act1 
bind responder global pol1 100  

NetScaler solution for redirection if a URL is wrong (method 2)

 
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+"\r\n\r\nHTTPCallout Used"' -bypassSafetyCheck yes 
add responder policy pol1 '!HTTP.REQ.HEADER("Name").EXISTS  &&  !SYS.HTTP_CALLOUT(call)' act1 
bind responder global pol1 100  

Rewriting a URL Based on Time

You can rewrite a URL based on the time. The following examples change a request for example.html to example.day.html or example.night.html, depending on the time of day.

Apache mod_rewrite solution for rewriting a URL based on the time

 
RewriteCond   %{TIME_HOUR}%{TIME_MIN} >0700 
RewriteCond   %{TIME_HOUR}%{TIME_MIN} <1900 
RewriteRule   ^example\.html$ example.day.html [L] 
RewriteRule   ^example\.html$ example.night.html 

NetScaler solution for rewriting a URL based on the time

 
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 

Redirecting to a New File Name (Invisible to the User)

If you rename a Web page, you can continue to support the old URL for backward compatibility while preventing users from recognizing that the page was renamed.

In the first two of the following examples, the base directory is /~quux/. The third example accommodates any base directory and the presence of query strings in the URL.

Apache mod_rewrite solution for managing a file name change in a fixed location

 
RewriteEngine  on 
RewriteBase    /~quux/ 
RewriteRule    ^foo\.html$  bar.html 

NetScaler solution for managing a file name change in a fixed location

 
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  

NetScaler solution for managing a file name change regardless of the base directory or query strings in the URL

 
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 

Redirecting to New File Name (User-Visible URL)

If you rename a Web page, you may want to continue to support the old URL for backward compatibility and allow users to see that the page was renamed by changing the URL that is displayed in the browser.

In the first two of the following examples, redirection occurs when the base directory is /~quux/. The third example accommodates any base directory and the presence of query strings in the URL.

Apache mod_rewrite solution for changing the file name and the URL displayed in the browser

 
RewriteEngine on 
RewriteBase    /~quux/ 
RewriteRule    ^old\.html$ new.html  [R] 

NetScaler solution for changing the file name and the URL displayed in the browser

 
add responder action act1 redirect 'HTTP.REQ.URL.BEFORE_STR("foo.html")+"new.html"' -bypassSafetyCheck yes 
add responder policy pol1 'HTTP.REQ.URL.ENDSWITH("/~quux/old.html")' act1 
bind responder global pol1 100 

NetScaler solution for changing the file name and the URL displayed in the browser regardless of the base directory or query strings in the URL

 
add responder action act1 redirect 'HTTP.REQ.URL.PATH.BEFORE_STR("old.html")+"new.html"+HTTP.REQ.URL.AFTER_STR("old.html")' -bypassSafetyCheck yes 
add responder policy pol1 'HTTP.REQ.URL.PATH.CONTAINS("old.html")' act1 
bind responder global pol1 100 

Accommodating Browser Dependent Content

To accommodate browser-specific limitations—at least for important top-level pages—it is sometimes necessary to set restrictions on the browser type and version. For example, you might want to set a maximum version for the latest Netscape variants, a minimum version for Lynx browsers, and an average feature version for all others.

The following examples act on the HTTP header "User-Agent", such that if this header begins with "Mozilla/3", the page MyPage.html is rewritten to MyPage.NS.html. If the browser is "Lynx" or "Mozilla" version 1 or 2, the URL becomes MyPage.20.html. All other browsers receive page MyPage.32.html.

Apache mod_rewrite solution for browser-specific settings

 
RewriteCond %{HTTP_USER_AGENT}  ^Mozilla/3.* 
RewriteRule ^MyPage\.html$ MyPage.NS.html [L] 
RewriteCond %{HTTP_USER_AGENT}  ^Lynx/.* [OR] 
RewriteCond %{HTTP_USER_AGENT}  ^Mozilla/[12].* 
RewriteRule ^MyPage\.html$ MyPage.20.html [L] 
RewriteRule ^fMyPage\.html$ MyPage.32.html [L] 
NetScaler solution for browser-specific settings 
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 

Blocking Access by Robots

You can block a robot from retrieving pages from a specific directory or a set of directories to ease up the traffic to and from these directories. You can restrict access based on the specific location or you can block requests based on information in User-Agent HTTP headers.

In the following examples, the Web location to be blocked is /~quux/foo/arc/, the IP addresses to be blocked are 123.45.67.8 and 123.45.67.9, and the robot’s name is NameOfBadRobot.

Apache mod_rewrite solution for blocking a path and a User-Agent header

 
RewriteCond %{HTTP_USER_AGENT}   ^NameOfBadRobot.*       
RewriteCond %{REMOTE_ADDR}       ^123\.45\.67\.[8-9]$ 
RewriteRule ^/~quux/foo/arc/.+   -   [F] 

NetScaler solution for blocking a path and a User-Agent header

 
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(123.45.67.8)&&CLIENT.IP.SRC.EQ(123.45.67.9) && HTTP.REQ.URL.STARTSWITH("/~quux/foo/arc")' act1 
bind responder global pol1 100 

Blocking Access to Inline Images

If you find people frequently going to your server to copy inline graphics for their own use (and generating unnecessary traffic), you may want to restrict the browser’s ability to send an HTTP Referer header.

In the following example, the graphics are located in http://www.quux-corp.de/~quux/.

Apache mod_rewrite solution for blocking access to an inline image

 
RewriteCond %{HTTP_REFERER} !^$                                   
RewriteCond %{HTTP_REFERER} !^http://www.quux-corp.de/~quux/.*$  
RewriteRule .*\.gif$ - [F]  

NetScaler solution for blocking access to an inline image

 
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.quux-corp.de/~quux/")&&HTTP.REQ.URL.ENDSWITH_ANY("pat1")' act1 
bind responder global pol1 100 

Redirecting a Working URI to a New Format

Suppose that you have a set of working URLs that resemble the following:

/index.php?id=nnnn

To change these URLs to /nnnn and make sure that search engines update their indexes to the new URI format, you need to do the following:

  • Redirect the old URIs to the new ones so that search engines update their indexes.
  • Rewrite the new URI back to the old one so that the index.php script runs correctly.

To accomplish this, you can insert marker code into the query string (making sure that the marker code is not seen by visitors), and then removing the marker code for the index.php script.

The following examples redirect from an old link to a new format only if a marker is not present in the query string. The link that uses the new format is re-written back to the old format, and a marker is added to the query string.

Apache mod_rewrite solution

 
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] 
NetScaler solution 
add responder action act_redirect redirect 'HTTP.REQ.URL.PATH.BEFORE_STR("index.php")+HTTP.REQ.URL.QUERY.VALUE("id")' -bypassSafetyCheck yes 
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.PATH.SUFFIX(\'/\',0)' -bypassSafetyCheck yes 
add rewrite policy pol1 '!HTTP.REQ.URL.QUERY.CONTAINS("marker")'  act1 
bind rewrite global pol1 100 END 

Ensuring That a Secure Server Is Used for Selected Pages

To make sure that only secure servers are used for selected Web pages, you can use the following Apache mod_rewrite code or NetScaler Responder policies.

Apache mod_rewrite solution

 
RewriteCond %{SERVER_PORT} !^443$  
RewriteRule ^/?(page1|page2|page3|page4|page5)$  https://www.example.com/%1 [R,L] 

NetScaler solution using regular expressions

 
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 

NetScaler solution using pattern sets

 
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' -bypassSafetyCheck yes 
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