Blame docs/manual/rewrite/advanced.html.en

Packit 90a5c9
Packit 90a5c9
Packit 90a5c9
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
Packit 90a5c9
<meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" />
Packit 90a5c9
Packit 90a5c9
        XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Packit 90a5c9
              This file is generated from xml source: DO NOT EDIT
Packit 90a5c9
        XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Packit 90a5c9
      -->
Packit 90a5c9
<title>Advanced Techniques with mod_rewrite - Apache HTTP Server Version 2.4</title>
Packit 90a5c9
<link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
Packit 90a5c9
<link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
Packit 90a5c9
<link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
Packit 90a5c9
<script src="../style/scripts/prettify.min.js" type="text/javascript">
Packit 90a5c9
</script>
Packit 90a5c9
Packit 90a5c9
<link href="../images/favicon.ico" rel="shortcut icon" /></head>
Packit 90a5c9
<body id="manual-page">
Packit 90a5c9

Modules | Directives | FAQ | Glossary | Sitemap

Packit 90a5c9

Apache HTTP Server Version 2.4

Packit 90a5c9
Packit 90a5c9
<-
Packit 90a5c9
Packit 90a5c9
Apache > HTTP Server > Documentation > Version 2.4 > Rewrite

Advanced Techniques with mod_rewrite

Packit 90a5c9
Packit 90a5c9

Available Languages:  en  |

Packit 90a5c9
 fr 

Packit 90a5c9
Packit 90a5c9
Packit 90a5c9
Packit 90a5c9

This document supplements the mod_rewrite

Packit 90a5c9
reference documentation. It provides
Packit 90a5c9
a few advanced techniques using mod_rewrite.

Packit 90a5c9
Packit 90a5c9
Note that many of these examples won't work unchanged in your
Packit 90a5c9
particular server configuration, so it's important that you understand
Packit 90a5c9
them, rather than merely cutting and pasting the examples into your
Packit 90a5c9
configuration.
Packit 90a5c9
Packit 90a5c9
Packit 90a5c9
Packit 90a5c9
  • On-the-fly Content-Regeneration
  • Packit 90a5c9
  • Load Balancing
  • Packit 90a5c9
  • Structured Userdirs
  • Packit 90a5c9
  • Redirecting Anchors
  • Packit 90a5c9
  • Time-Dependent Rewriting
  • Packit 90a5c9
  • Set Environment Variables Based On URL Parts
  • Packit 90a5c9

    See also

    Packit 90a5c9
    top
    Packit 90a5c9
    Packit 90a5c9

    URL-based sharding across multiple backends

    Packit 90a5c9
    Packit 90a5c9
      
    Packit 90a5c9
    Packit 90a5c9
      
    Packit 90a5c9
        
    Description:
    Packit 90a5c9
    Packit 90a5c9
        
    Packit 90a5c9
          

    A common technique for distributing the burden of

    Packit 90a5c9
          server load or storage space is called "sharding".
    Packit 90a5c9
          When using this method, a front-end server will use the
    Packit 90a5c9
          url to consistently "shard" users or objects to separate
    Packit 90a5c9
          backend servers.

    Packit 90a5c9
        
    Packit 90a5c9
    Packit 90a5c9
        
    Solution:
    Packit 90a5c9
    Packit 90a5c9
        
    Packit 90a5c9
          

    A mapping is maintained, from users to target servers, in

    Packit 90a5c9
          external map files. They look like:

    Packit 90a5c9
    Packit 90a5c9

    Packit 90a5c9
    user1  physical_host_of_user1
    Packit 90a5c9
    user2  physical_host_of_user2
    Packit 90a5c9
    :      :
    Packit 90a5c9

    Packit 90a5c9
    Packit 90a5c9
      

    We put this into a map.users-to-hosts file. The

    Packit 90a5c9
        aim is to map;

    Packit 90a5c9
    Packit 90a5c9

    Packit 90a5c9
    /u/user1/anypath
    Packit 90a5c9

    Packit 90a5c9
    Packit 90a5c9
      

    to

    Packit 90a5c9
    Packit 90a5c9

    Packit 90a5c9
    http://physical_host_of_user1/u/user/anypath
    Packit 90a5c9

    Packit 90a5c9
    Packit 90a5c9
          

    thus every URL path need not be valid on every backend physical

    Packit 90a5c9
          host. The following ruleset does this for us with the help of the map
    Packit 90a5c9
          files assuming that server0 is a default server which will be used if
    Packit 90a5c9
          a user has no entry in the map:

    Packit 90a5c9
    Packit 90a5c9
    RewriteEngine on
    Packit 90a5c9
    RewriteMap      users-to-hosts   "txt:/path/to/map.users-to-hosts"
    Packit 90a5c9
    RewriteRule   "^/u/([^/]+)/?(.*)"   "http://${users-to-hosts:$1|server0}/u/$1/$2"
    Packit 90a5c9
    Packit 90a5c9
        
    Packit 90a5c9
      
    Packit 90a5c9
    Packit 90a5c9
      

    See the RewriteMap

    Packit 90a5c9
      documentation for more discussion of the syntax of this directive.

    Packit 90a5c9
    Packit 90a5c9
    top
    Packit 90a5c9
    Packit 90a5c9

    On-the-fly Content-Regeneration

    Packit 90a5c9
    Packit 90a5c9
      
    Packit 90a5c9
    Packit 90a5c9
      
    Packit 90a5c9
        
    Description:
    Packit 90a5c9
    Packit 90a5c9
        
    Packit 90a5c9
          

    We wish to dynamically generate content, but store it

    Packit 90a5c9
          statically once it is generated. This rule will check for the
    Packit 90a5c9
          existence of the static file, and if it's not there, generate
    Packit 90a5c9
          it. The static files can be removed periodically, if desired (say,
    Packit 90a5c9
          via cron) and will be regenerated on demand.

    Packit 90a5c9
        
    Packit 90a5c9
    Packit 90a5c9
        
    Solution:
    Packit 90a5c9
    Packit 90a5c9
        
    Packit 90a5c9
          This is done via the following ruleset:
    Packit 90a5c9
    Packit 90a5c9
    # This example is valid in per-directory context only
    Packit 90a5c9
    RewriteCond "%{REQUEST_URI}"   "!-U"
    Packit 90a5c9
    RewriteRule "^(.+)\.html$"          "/regenerate_page.cgi"   [PT,L]
    Packit 90a5c9
    Packit 90a5c9
    Packit 90a5c9
        

    The -U operator determines whether the test string

    Packit 90a5c9
        (in this case, REQUEST_URI) is a valid URL. It does
    Packit 90a5c9
        this via a subrequest. In the event that this subrequest fails -
    Packit 90a5c9
        that is, the requested resource doesn't exist - this rule invokes
    Packit 90a5c9
        the CGI program /regenerate_page.cgi, which generates
    Packit 90a5c9
        the requested resource and saves it into the document directory, so
    Packit 90a5c9
        that the next time it is requested, a static copy can be served.

    Packit 90a5c9
    Packit 90a5c9
        

    In this way, documents that are infrequently updated can be served in

    Packit 90a5c9
        static form. if documents need to be refreshed, they can be deleted
    Packit 90a5c9
        from the document directory, and they will then be regenerated the
    Packit 90a5c9
        next time they are requested.

    Packit 90a5c9
        
    Packit 90a5c9
      
    Packit 90a5c9
    Packit 90a5c9
    top
    Packit 90a5c9
    Packit 90a5c9

    Load Balancing

    Packit 90a5c9
    Packit 90a5c9
      
    Packit 90a5c9
    Packit 90a5c9
      
    Packit 90a5c9
        
    Description:
    Packit 90a5c9
    Packit 90a5c9
        
    Packit 90a5c9
          

    We wish to randomly distribute load across several servers

    Packit 90a5c9
          using mod_rewrite.

    Packit 90a5c9
        
    Packit 90a5c9
    Packit 90a5c9
        
    Solution:
    Packit 90a5c9
    Packit 90a5c9
        
    Packit 90a5c9
          

    We'll use RewriteMap and a list of servers

    Packit 90a5c9
          to accomplish this.

    Packit 90a5c9
    Packit 90a5c9
    RewriteEngine on
    Packit 90a5c9
    RewriteMap lb "rnd:/path/to/serverlist.txt"
    Packit 90a5c9
    RewriteRule "^/(.*)" "http://${lb:servers}/$1" [P,L]
    Packit 90a5c9
    Packit 90a5c9
    Packit 90a5c9

    serverlist.txt will contain a list of the servers:

    Packit 90a5c9
    Packit 90a5c9

    Packit 90a5c9
    ## serverlist.txt
    Packit 90a5c9

    Packit 90a5c9
    servers one.example.com|two.example.com|three.example.com
    Packit 90a5c9

    Packit 90a5c9
    Packit 90a5c9

    If you want one particular server to get more of the load than the

    Packit 90a5c9
    others, add it more times to the list.

    Packit 90a5c9
    Packit 90a5c9
       
    Packit 90a5c9
    Packit 90a5c9
       
    Discussion
    Packit 90a5c9
       
    Packit 90a5c9

    Apache comes with a load-balancing module -

    Packit 90a5c9
    mod_proxy_balancer - which is far more flexible and
    Packit 90a5c9
    featureful than anything you can cobble together using mod_rewrite.

    Packit 90a5c9
       
    Packit 90a5c9
      
    Packit 90a5c9
    Packit 90a5c9
    top
    Packit 90a5c9
    Packit 90a5c9

    Structured Userdirs

    Packit 90a5c9
    Packit 90a5c9
      
    Packit 90a5c9
    Packit 90a5c9
      
    Packit 90a5c9
        
    Description:
    Packit 90a5c9
    Packit 90a5c9
        
    Packit 90a5c9
          

    Some sites with thousands of users use a

    Packit 90a5c9
          structured homedir layout, i.e. each homedir is in a
    Packit 90a5c9
          subdirectory which begins (for instance) with the first
    Packit 90a5c9
          character of the username. So, /~larry/anypath
    Packit 90a5c9
          is /home/l/larry/public_html/anypath
    Packit 90a5c9
          while /~waldo/anypath is
    Packit 90a5c9
          /home/w/waldo/public_html/anypath.

    Packit 90a5c9
        
    Packit 90a5c9
    Packit 90a5c9
        
    Solution:
    Packit 90a5c9
    Packit 90a5c9
        
    Packit 90a5c9
          

    We use the following ruleset to expand the tilde URLs

    Packit 90a5c9
          into the above layout.

    Packit 90a5c9
    Packit 90a5c9
    RewriteEngine on
    Packit 90a5c9
    RewriteRule   "^/~(([a-z])[a-z0-9]+)(.*)"  "/home/$2/$1/public_html$3"
    Packit 90a5c9
    Packit 90a5c9
        
    Packit 90a5c9
      
    Packit 90a5c9
    Packit 90a5c9
    top
    Packit 90a5c9
    Packit 90a5c9

    Redirecting Anchors

    Packit 90a5c9
    Packit 90a5c9
      
    Packit 90a5c9
    Packit 90a5c9
      
    Packit 90a5c9
        
    Description:
    Packit 90a5c9
    Packit 90a5c9
        
    Packit 90a5c9
        

    By default, redirecting to an HTML anchor doesn't work,

    Packit 90a5c9
        because mod_rewrite escapes the # character,
    Packit 90a5c9
        turning it into %23. This, in turn, breaks the
    Packit 90a5c9
        redirection.

    Packit 90a5c9
        
    Packit 90a5c9
    Packit 90a5c9
        
    Solution:
    Packit 90a5c9
    Packit 90a5c9
        
    Packit 90a5c9
          

    Use the [NE] flag on the

    Packit 90a5c9
          RewriteRule. NE stands for No Escape.
    Packit 90a5c9
          

    Packit 90a5c9
        
    Packit 90a5c9
    Packit 90a5c9
        
    Discussion:
    Packit 90a5c9
        
    This technique will of course also work with other
    Packit 90a5c9
        special characters that mod_rewrite, by default, URL-encodes.
    Packit 90a5c9
      
    Packit 90a5c9
    Packit 90a5c9
    top
    Packit 90a5c9
    Packit 90a5c9

    Time-Dependent Rewriting

    Packit 90a5c9
    Packit 90a5c9
      
    Packit 90a5c9
    Packit 90a5c9
      
    Packit 90a5c9
        
    Description:
    Packit 90a5c9
    Packit 90a5c9
        
    Packit 90a5c9
          

    We wish to use mod_rewrite to serve different content based on

    Packit 90a5c9
          the time of day.

    Packit 90a5c9
        
    Packit 90a5c9
    Packit 90a5c9
        
    Solution:
    Packit 90a5c9
    Packit 90a5c9
        
    Packit 90a5c9
          

    There are a lot of variables named TIME_xxx

    Packit 90a5c9
          for rewrite conditions. In conjunction with the special
    Packit 90a5c9
          lexicographic comparison patterns <STRING,
    Packit 90a5c9
          >STRING and =STRING we can
    Packit 90a5c9
          do time-dependent redirects:

    Packit 90a5c9
    Packit 90a5c9
    RewriteEngine on
    Packit 90a5c9
    RewriteCond   "%{TIME_HOUR}%{TIME_MIN}" ">0700"
    Packit 90a5c9
    RewriteCond   "%{TIME_HOUR}%{TIME_MIN}" "<1900"
    Packit 90a5c9
    RewriteRule   "^foo\.html$"             "foo.day.html" [L]
    Packit 90a5c9
    RewriteRule   "^foo\.html$"             "foo.night.html"
    Packit 90a5c9
    Packit 90a5c9
    Packit 90a5c9
          

    This provides the content of foo.day.html

    Packit 90a5c9
          under the URL foo.html from
    Packit 90a5c9
          07:01-18:59 and at the remaining time the
    Packit 90a5c9
          contents of foo.night.html.

    Packit 90a5c9
    Packit 90a5c9
          
    mod_cache, intermediate proxies
    Packit 90a5c9
          and browsers may each cache responses and cause the either page to be
    Packit 90a5c9
          shown outside of the time-window configured.
    Packit 90a5c9
          mod_expires may be used to control this
    Packit 90a5c9
          effect. You are, of course, much better off simply serving the
    Packit 90a5c9
          content dynamically, and customizing it based on the time of day.
    Packit 90a5c9
    Packit 90a5c9
        
    Packit 90a5c9
      
    Packit 90a5c9
    Packit 90a5c9
    top
    Packit 90a5c9
    Packit 90a5c9

    Set Environment Variables Based On URL Parts

    Packit 90a5c9
    Packit 90a5c9
      
    Packit 90a5c9
    Packit 90a5c9
      
    Packit 90a5c9
        
    Description:
    Packit 90a5c9
    Packit 90a5c9
        
    Packit 90a5c9
          

    At time, we want to maintain some kind of status when we

    Packit 90a5c9
          perform a rewrite. For example, you want to make a note that
    Packit 90a5c9
          you've done that rewrite, so that you can check later to see if a
    Packit 90a5c9
          request can via that rewrite. One way to do this is by setting an
    Packit 90a5c9
          environment variable.

    Packit 90a5c9
        
    Packit 90a5c9
    Packit 90a5c9
        
    Solution:
    Packit 90a5c9
    Packit 90a5c9
        
    Packit 90a5c9
          

    Use the [E] flag to set an environment variable.

    Packit 90a5c9
    Packit 90a5c9
    RewriteEngine on
    Packit 90a5c9
    RewriteRule   "^/horse/(.*)"   "/pony/$1" [E=rewritten:1]
    Packit 90a5c9
    Packit 90a5c9
    Packit 90a5c9
        

    Later in your ruleset you might check for this environment

    Packit 90a5c9
        variable using a RewriteCond:

    Packit 90a5c9
    Packit 90a5c9
    RewriteCond "%{ENV:rewritten}" "=1"
    Packit 90a5c9
    Packit 90a5c9
    Packit 90a5c9
        

    Note that environment variables do not survive an external

    Packit 90a5c9
        redirect. You might consider using the [CO] flag to set a
    Packit 90a5c9
        cookie.

    Packit 90a5c9
    Packit 90a5c9
        
    Packit 90a5c9
      
    Packit 90a5c9
    Packit 90a5c9
    Packit 90a5c9
    Packit 90a5c9

    Available Languages:  en  |

    Packit 90a5c9
     fr 

    Packit 90a5c9
    top

    Comments

    Notice:
    This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed again by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Freenode, or sent to our mailing lists.
    Packit 90a5c9
    <script type="text/javascript">
    Packit 90a5c9
    var comments_shortname = 'httpd';
    Packit 90a5c9
    var comments_identifier = 'http://httpd.apache.org/docs/2.4/rewrite/advanced.html';
    Packit 90a5c9
    (function(w, d) {
    Packit 90a5c9
        if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
    Packit 90a5c9
            d.write('
    <\/div>');
    Packit 90a5c9
            var s = d.createElement('script');
    Packit 90a5c9
            s.type = 'text/javascript';
    Packit 90a5c9
            s.async = true;
    Packit 90a5c9
            s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
    Packit 90a5c9
            (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
    Packit 90a5c9
        }
    Packit 90a5c9
        else { 
    Packit 90a5c9
            d.write('
    Comments are disabled for this page at the moment.<\/div>');
    Packit 90a5c9
        }
    Packit 90a5c9
    })(window, document);
    Packit 90a5c9
    //--></script>
    Packit 90a5c9

    Copyright 2018 The Apache Software Foundation.
    Licensed under the Apache License, Version 2.0.

    Packit 90a5c9

    Modules | Directives | FAQ | Glossary | Sitemap

    <script type="text/javascript">
    Packit 90a5c9
    if (typeof(prettyPrint) !== 'undefined') {
    Packit 90a5c9
        prettyPrint();
    Packit 90a5c9
    }
    Packit 90a5c9
    //--></script>
    Packit 90a5c9
    </body></html>