~ubuntu-branches/ubuntu/feisty/apache2/feisty

« back to all changes in this revision

Viewing changes to docs/manual/rewrite/rewrite_guide_advanced.html.en

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Barth
  • Date: 2006-12-09 21:05:45 UTC
  • mfrom: (0.6.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20061209210545-h70s0xaqc2v8vqr2
Tags: 2.2.3-3.2
* Non-maintainer upload.
* 043_ajp_connection_reuse: Patch from upstream Bugzilla, fixing a critical
  issue with regard to connection reuse in mod_proxy_ajp.
  Closes: #396265

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?xml version="1.0" encoding="ISO-8859-1"?>
 
2
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 
3
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head><!--
 
4
        XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 
5
              This file is generated from xml source: DO NOT EDIT
 
6
        XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 
7
      -->
 
8
<title>URL Rewriting Guide - Advanced topics - Apache HTTP Server</title>
 
9
<link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
 
10
<link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
 
11
<link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" />
 
12
<link href="../images/favicon.ico" rel="shortcut icon" /></head>
 
13
<body id="manual-page"><div id="page-header">
 
14
<p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="../faq/">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
 
15
<p class="apache">Apache HTTP Server Version 2.2</p>
 
16
<img alt="" src="../images/feather.gif" /></div>
 
17
<div class="up"><a href="./index.html"><img title="&lt;-" alt="&lt;-" src="../images/left.gif" /></a></div>
 
18
<div id="path">
 
19
<a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.2</a></div><div id="page-content"><div id="preamble"><h1>URL Rewriting Guide - Advanced topics</h1>
 
20
<div class="toplang">
 
21
<p><span>Available Languages: </span><a href="../en/rewrite/rewrite_guide_advanced.html" title="English">&nbsp;en&nbsp;</a></p>
 
22
</div>
 
23
 
 
24
 
 
25
    <p>This document supplements the <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>
 
26
    <a href="../mod/mod_rewrite.html">reference documentation</a>.
 
27
    It describes how one can use Apache's <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>
 
28
    to solve typical URL-based problems with which webmasters are
 
29
    commonony confronted. We give detailed descriptions on how to
 
30
    solve each problem by configuring URL rewriting rulesets.</p>
 
31
 
 
32
    <div class="warning">ATTENTION: Depending on your server configuration
 
33
    it may be necessary to slightly change the examples for your
 
34
    situation, e.g. adding the <code>[PT]</code> flag when
 
35
    additionally using <code class="module"><a href="../mod/mod_alias.html">mod_alias</a></code> and
 
36
    <code class="module"><a href="../mod/mod_userdir.html">mod_userdir</a></code>, etc. Or rewriting a ruleset
 
37
    to fit in <code>.htaccess</code> context instead
 
38
    of per-server context. Always try to understand what a
 
39
    particular ruleset really does before you use it. This
 
40
    avoids many problems.</div>
 
41
 
 
42
  </div>
 
43
<div id="quickview"><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#cluster">Webcluster through Homogeneous URL Layout</a></li>
 
44
<li><img alt="" src="../images/down.gif" /> <a href="#structuredhomedirs">Structured Homedirs</a></li>
 
45
<li><img alt="" src="../images/down.gif" /> <a href="#filereorg">Filesystem Reorganization</a></li>
 
46
<li><img alt="" src="../images/down.gif" /> <a href="#redirect404">Redirect Failing URLs To Other Webserver</a></li>
 
47
<li><img alt="" src="../images/down.gif" /> Archive Access Multiplexer</li>
 
48
<li><img alt="" src="../images/down.gif" /> <a href="#content">Content Handling</a></li>
 
49
<li><img alt="" src="../images/down.gif" /> <a href="#access">Access Restriction</a></li>
 
50
</ul><h3>See also</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Module
 
51
documentation</a></li><li><a href="rewrite_intro.html">mod_rewrite
 
52
introduction</a></li><li><a href="rewrite_guide.html">Practical solutions to common
 
53
problems</a></li><li><a href="rewrite_tech.html">Technical details</a></li></ul></div>
 
54
<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
 
55
<div class="section">
 
56
<h2><a name="cluster" id="cluster">Webcluster through Homogeneous URL Layout</a></h2>
 
57
 
 
58
      
 
59
 
 
60
      <dl>
 
61
        <dt>Description:</dt>
 
62
 
 
63
        <dd>
 
64
          <p>We want to create a homogeneous and consistent URL
 
65
          layout over all WWW servers on a Intranet webcluster, i.e.
 
66
          all URLs (per definition server local and thus server
 
67
          dependent!) become actually server <em>independent</em>!
 
68
          What we want is to give the WWW namespace a consistent
 
69
          server-independent layout: no URL should have to include
 
70
          any physically correct target server. The cluster itself
 
71
          should drive us automatically to the physical target
 
72
          host.</p>
 
73
        </dd>
 
74
 
 
75
        <dt>Solution:</dt>
 
76
 
 
77
        <dd>
 
78
          <p>First, the knowledge of the target servers come from
 
79
          (distributed) external maps which contain information
 
80
          where our users, groups and entities stay. The have the
 
81
          form</p>
 
82
 
 
83
<div class="example"><pre>
 
84
user1  server_of_user1
 
85
user2  server_of_user2
 
86
:      :
 
87
</pre></div>
 
88
 
 
89
          <p>We put them into files <code>map.xxx-to-host</code>.
 
90
          Second we need to instruct all servers to redirect URLs
 
91
          of the forms</p>
 
92
 
 
93
<div class="example"><pre>
 
94
/u/user/anypath
 
95
/g/group/anypath
 
96
/e/entity/anypath
 
97
</pre></div>
 
98
 
 
99
          <p>to</p>
 
100
 
 
101
<div class="example"><pre>
 
102
http://physical-host/u/user/anypath
 
103
http://physical-host/g/group/anypath
 
104
http://physical-host/e/entity/anypath
 
105
</pre></div>
 
106
 
 
107
          <p>when the URL is not locally valid to a server. The
 
108
          following ruleset does this for us by the help of the map
 
109
          files (assuming that server0 is a default server which
 
110
          will be used if a user has no entry in the map):</p>
 
111
 
 
112
<div class="example"><pre>
 
113
RewriteEngine on
 
114
 
 
115
RewriteMap      user-to-host   txt:/path/to/map.user-to-host
 
116
RewriteMap     group-to-host   txt:/path/to/map.group-to-host
 
117
RewriteMap    entity-to-host   txt:/path/to/map.entity-to-host
 
118
 
 
119
RewriteRule   ^/u/<strong>([^/]+)</strong>/?(.*)   http://<strong>${user-to-host:$1|server0}</strong>/u/$1/$2
 
120
RewriteRule   ^/g/<strong>([^/]+)</strong>/?(.*)  http://<strong>${group-to-host:$1|server0}</strong>/g/$1/$2
 
121
RewriteRule   ^/e/<strong>([^/]+)</strong>/?(.*) http://<strong>${entity-to-host:$1|server0}</strong>/e/$1/$2
 
122
 
 
123
RewriteRule   ^/([uge])/([^/]+)/?$          /$1/$2/.www/
 
124
RewriteRule   ^/([uge])/([^/]+)/([^.]+.+)   /$1/$2/.www/$3\
 
125
</pre></div>
 
126
        </dd>
 
127
      </dl>
 
128
 
 
129
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
 
130
<div class="section">
 
131
<h2><a name="structuredhomedirs" id="structuredhomedirs">Structured Homedirs</a></h2>
 
132
 
 
133
      
 
134
 
 
135
      <dl>
 
136
        <dt>Description:</dt>
 
137
 
 
138
        <dd>
 
139
          <p>Some sites with thousands of users usually use a
 
140
          structured homedir layout, i.e. each homedir is in a
 
141
          subdirectory which begins for instance with the first
 
142
          character of the username. So, <code>/~foo/anypath</code>
 
143
          is <code>/home/<strong>f</strong>/foo/.www/anypath</code>
 
144
          while <code>/~bar/anypath</code> is
 
145
          <code>/home/<strong>b</strong>/bar/.www/anypath</code>.</p>
 
146
        </dd>
 
147
 
 
148
        <dt>Solution:</dt>
 
149
 
 
150
        <dd>
 
151
          <p>We use the following ruleset to expand the tilde URLs
 
152
          into exactly the above layout.</p>
 
153
 
 
154
<div class="example"><pre>
 
155
RewriteEngine on
 
156
RewriteRule   ^/~(<strong>([a-z])</strong>[a-z0-9]+)(.*)  /home/<strong>$2</strong>/$1/.www$3
 
157
</pre></div>
 
158
        </dd>
 
159
      </dl>
 
160
 
 
161
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
 
162
<div class="section">
 
163
<h2><a name="filereorg" id="filereorg">Filesystem Reorganization</a></h2>
 
164
 
 
165
      
 
166
 
 
167
      <dl>
 
168
        <dt>Description:</dt>
 
169
 
 
170
        <dd>
 
171
          <p>This really is a hardcore example: a killer application
 
172
          which heavily uses per-directory
 
173
          <code>RewriteRules</code> to get a smooth look and feel
 
174
          on the Web while its data structure is never touched or
 
175
          adjusted. Background: <strong><em>net.sw</em></strong> is
 
176
          my archive of freely available Unix software packages,
 
177
          which I started to collect in 1992. It is both my hobby
 
178
          and job to to this, because while I'm studying computer
 
179
          science I have also worked for many years as a system and
 
180
          network administrator in my spare time. Every week I need
 
181
          some sort of software so I created a deep hierarchy of
 
182
          directories where I stored the packages:</p>
 
183
 
 
184
<div class="example"><pre>
 
185
drwxrwxr-x   2 netsw  users    512 Aug  3 18:39 Audio/
 
186
drwxrwxr-x   2 netsw  users    512 Jul  9 14:37 Benchmark/
 
187
drwxrwxr-x  12 netsw  users    512 Jul  9 00:34 Crypto/
 
188
drwxrwxr-x   5 netsw  users    512 Jul  9 00:41 Database/
 
189
drwxrwxr-x   4 netsw  users    512 Jul 30 19:25 Dicts/
 
190
drwxrwxr-x  10 netsw  users    512 Jul  9 01:54 Graphic/
 
191
drwxrwxr-x   5 netsw  users    512 Jul  9 01:58 Hackers/
 
192
drwxrwxr-x   8 netsw  users    512 Jul  9 03:19 InfoSys/
 
193
drwxrwxr-x   3 netsw  users    512 Jul  9 03:21 Math/
 
194
drwxrwxr-x   3 netsw  users    512 Jul  9 03:24 Misc/
 
195
drwxrwxr-x   9 netsw  users    512 Aug  1 16:33 Network/
 
196
drwxrwxr-x   2 netsw  users    512 Jul  9 05:53 Office/
 
197
drwxrwxr-x   7 netsw  users    512 Jul  9 09:24 SoftEng/
 
198
drwxrwxr-x   7 netsw  users    512 Jul  9 12:17 System/
 
199
drwxrwxr-x  12 netsw  users    512 Aug  3 20:15 Typesetting/
 
200
drwxrwxr-x  10 netsw  users    512 Jul  9 14:08 X11/
 
201
</pre></div>
 
202
 
 
203
          <p>In July 1996 I decided to make this archive public to
 
204
          the world via a nice Web interface. "Nice" means that I
 
205
          wanted to offer an interface where you can browse
 
206
          directly through the archive hierarchy. And "nice" means
 
207
          that I didn't wanted to change anything inside this
 
208
          hierarchy - not even by putting some CGI scripts at the
 
209
          top of it. Why? Because the above structure should be
 
210
          later accessible via FTP as well, and I didn't want any
 
211
          Web or CGI stuff to be there.</p>
 
212
        </dd>
 
213
 
 
214
        <dt>Solution:</dt>
 
215
 
 
216
        <dd>
 
217
          <p>The solution has two parts: The first is a set of CGI
 
218
          scripts which create all the pages at all directory
 
219
          levels on-the-fly. I put them under
 
220
          <code>/e/netsw/.www/</code> as follows:</p>
 
221
 
 
222
<div class="example"><pre>
 
223
-rw-r--r--   1 netsw  users    1318 Aug  1 18:10 .wwwacl
 
224
drwxr-xr-x  18 netsw  users     512 Aug  5 15:51 DATA/
 
225
-rw-rw-rw-   1 netsw  users  372982 Aug  5 16:35 LOGFILE
 
226
-rw-r--r--   1 netsw  users     659 Aug  4 09:27 TODO
 
227
-rw-r--r--   1 netsw  users    5697 Aug  1 18:01 netsw-about.html
 
228
-rwxr-xr-x   1 netsw  users     579 Aug  2 10:33 netsw-access.pl
 
229
-rwxr-xr-x   1 netsw  users    1532 Aug  1 17:35 netsw-changes.cgi
 
230
-rwxr-xr-x   1 netsw  users    2866 Aug  5 14:49 netsw-home.cgi
 
231
drwxr-xr-x   2 netsw  users     512 Jul  8 23:47 netsw-img/
 
232
-rwxr-xr-x   1 netsw  users   24050 Aug  5 15:49 netsw-lsdir.cgi
 
233
-rwxr-xr-x   1 netsw  users    1589 Aug  3 18:43 netsw-search.cgi
 
234
-rwxr-xr-x   1 netsw  users    1885 Aug  1 17:41 netsw-tree.cgi
 
235
-rw-r--r--   1 netsw  users     234 Jul 30 16:35 netsw-unlimit.lst
 
236
</pre></div>
 
237
 
 
238
          <p>The <code>DATA/</code> subdirectory holds the above
 
239
          directory structure, i.e. the real
 
240
          <strong><em>net.sw</em></strong> stuff and gets
 
241
          automatically updated via <code>rdist</code> from time to
 
242
          time. The second part of the problem remains: how to link
 
243
          these two structures together into one smooth-looking URL
 
244
          tree? We want to hide the <code>DATA/</code> directory
 
245
          from the user while running the appropriate CGI scripts
 
246
          for the various URLs. Here is the solution: first I put
 
247
          the following into the per-directory configuration file
 
248
          in the <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code>
 
249
          of the server to rewrite the announced URL
 
250
          <code>/net.sw/</code> to the internal path
 
251
          <code>/e/netsw</code>:</p>
 
252
 
 
253
<div class="example"><pre>
 
254
RewriteRule  ^net.sw$       net.sw/        [R]
 
255
RewriteRule  ^net.sw/(.*)$  e/netsw/$1
 
256
</pre></div>
 
257
 
 
258
          <p>The first rule is for requests which miss the trailing
 
259
          slash! The second rule does the real thing. And then
 
260
          comes the killer configuration which stays in the
 
261
          per-directory config file
 
262
          <code>/e/netsw/.www/.wwwacl</code>:</p>
 
263
 
 
264
<div class="example"><pre>
 
265
Options       ExecCGI FollowSymLinks Includes MultiViews
 
266
 
 
267
RewriteEngine on
 
268
 
 
269
#  we are reached via /net.sw/ prefix
 
270
RewriteBase   /net.sw/
 
271
 
 
272
#  first we rewrite the root dir to
 
273
#  the handling cgi script
 
274
RewriteRule   ^$                       netsw-home.cgi     [L]
 
275
RewriteRule   ^index\.html$            netsw-home.cgi     [L]
 
276
 
 
277
#  strip out the subdirs when
 
278
#  the browser requests us from perdir pages
 
279
RewriteRule   ^.+/(netsw-[^/]+/.+)$    $1                 [L]
 
280
 
 
281
#  and now break the rewriting for local files
 
282
RewriteRule   ^netsw-home\.cgi.*       -                  [L]
 
283
RewriteRule   ^netsw-changes\.cgi.*    -                  [L]
 
284
RewriteRule   ^netsw-search\.cgi.*     -                  [L]
 
285
RewriteRule   ^netsw-tree\.cgi$        -                  [L]
 
286
RewriteRule   ^netsw-about\.html$      -                  [L]
 
287
RewriteRule   ^netsw-img/.*$           -                  [L]
 
288
 
 
289
#  anything else is a subdir which gets handled
 
290
#  by another cgi script
 
291
RewriteRule   !^netsw-lsdir\.cgi.*     -                  [C]
 
292
RewriteRule   (.*)                     netsw-lsdir.cgi/$1
 
293
</pre></div>
 
294
 
 
295
          <p>Some hints for interpretation:</p>
 
296
 
 
297
          <ol>
 
298
            <li>Notice the <code>L</code> (last) flag and no
 
299
            substitution field ('<code>-</code>') in the forth part</li>
 
300
 
 
301
            <li>Notice the <code>!</code> (not) character and
 
302
            the <code>C</code> (chain) flag at the first rule
 
303
            in the last part</li>
 
304
 
 
305
            <li>Notice the catch-all pattern in the last rule</li>
 
306
          </ol>
 
307
        </dd>
 
308
      </dl>
 
309
 
 
310
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
 
311
<div class="section">
 
312
<h2><a name="redirect404" id="redirect404">Redirect Failing URLs To Other Webserver</a></h2>
 
313
 
 
314
      
 
315
 
 
316
      <dl>
 
317
        <dt>Description:</dt>
 
318
 
 
319
        <dd>
 
320
          <p>A typical FAQ about URL rewriting is how to redirect
 
321
          failing requests on webserver A to webserver B. Usually
 
322
          this is done via <code class="directive"><a href="../mod/core.html#errordocument">ErrorDocument</a></code> CGI-scripts in Perl, but
 
323
          there is also a <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> solution.
 
324
          But notice that this performs more poorly than using an
 
325
          <code class="directive"><a href="../mod/core.html#errordocument">ErrorDocument</a></code>
 
326
          CGI-script!</p>
 
327
        </dd>
 
328
 
 
329
        <dt>Solution:</dt>
 
330
 
 
331
        <dd>
 
332
          <p>The first solution has the best performance but less
 
333
          flexibility, and is less error safe:</p>
 
334
 
 
335
<div class="example"><pre>
 
336
RewriteEngine on
 
337
RewriteCond   /your/docroot/%{REQUEST_FILENAME} <strong>!-f</strong>
 
338
RewriteRule   ^(.+)                             http://<strong>webserverB</strong>.dom/$1
 
339
</pre></div>
 
340
 
 
341
          <p>The problem here is that this will only work for pages
 
342
          inside the <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code>. While you can add more
 
343
          Conditions (for instance to also handle homedirs, etc.)
 
344
          there is better variant:</p>
 
345
 
 
346
<div class="example"><pre>
 
347
RewriteEngine on
 
348
RewriteCond   %{REQUEST_URI} <strong>!-U</strong>
 
349
RewriteRule   ^(.+)          http://<strong>webserverB</strong>.dom/$1
 
350
</pre></div>
 
351
 
 
352
          <p>This uses the URL look-ahead feature of <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>.
 
353
          The result is that this will work for all types of URLs
 
354
          and is a safe way. But it does a performance impact on
 
355
          the webserver, because for every request there is one
 
356
          more internal subrequest. So, if your webserver runs on a
 
357
          powerful CPU, use this one. If it is a slow machine, use
 
358
          the first approach or better a <code class="directive"><a href="../mod/core.html#errordocument">ErrorDocument</a></code> CGI-script.</p>
 
359
        </dd>
 
360
      </dl>
 
361
 
 
362
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
 
363
<div class="section">
 
364
<h2>Archive Access Multiplexer</h2>
 
365
 
 
366
      
 
367
 
 
368
      <dl>
 
369
        <dt>Description:</dt>
 
370
 
 
371
        <dd>
 
372
          <p>Do you know the great CPAN (Comprehensive Perl Archive
 
373
          Network) under <a href="http://www.perl.com/CPAN">http://www.perl.com/CPAN</a>?
 
374
          This does a redirect to one of several FTP servers around
 
375
          the world which carry a CPAN mirror and is approximately
 
376
          near the location of the requesting client. Actually this
 
377
          can be called an FTP access multiplexing service. While
 
378
          CPAN runs via CGI scripts, how can a similar approach
 
379
          implemented via <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>?</p>
 
380
        </dd>
 
381
 
 
382
        <dt>Solution:</dt>
 
383
 
 
384
        <dd>
 
385
          <p>First we notice that from version 3.0.0
 
386
          <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> can
 
387
          also use the "<code>ftp:</code>" scheme on redirects.
 
388
          And second, the location approximation can be done by a
 
389
          <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code>
 
390
          over the top-level domain of the client.
 
391
          With a tricky chained ruleset we can use this top-level
 
392
          domain as a key to our multiplexing map.</p>
 
393
 
 
394
<div class="example"><pre>
 
395
RewriteEngine on
 
396
RewriteMap    multiplex                txt:/path/to/map.cxan
 
397
RewriteRule   ^/CxAN/(.*)              %{REMOTE_HOST}::$1                 [C]
 
398
RewriteRule   ^.+\.<strong>([a-zA-Z]+)</strong>::(.*)$  ${multiplex:<strong>$1</strong>|ftp.default.dom}$2  [R,L]
 
399
</pre></div>
 
400
 
 
401
<div class="example"><pre>
 
402
##
 
403
##  map.cxan -- Multiplexing Map for CxAN
 
404
##
 
405
 
 
406
de        ftp://ftp.cxan.de/CxAN/
 
407
uk        ftp://ftp.cxan.uk/CxAN/
 
408
com       ftp://ftp.cxan.com/CxAN/
 
409
 :
 
410
##EOF##
 
411
</pre></div>
 
412
        </dd>
 
413
      </dl>
 
414
 
 
415
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
 
416
<div class="section">
 
417
<h2><a name="content" id="content">Content Handling</a></h2>
 
418
 
 
419
    
 
420
 
 
421
   <h3>Browser Dependent Content</h3>
 
422
 
 
423
      
 
424
 
 
425
      <dl>
 
426
        <dt>Description:</dt>
 
427
 
 
428
        <dd>
 
429
          <p>At least for important top-level pages it is sometimes
 
430
          necessary to provide the optimum of browser dependent
 
431
          content, i.e. one has to provide a maximum version for the
 
432
          latest Netscape variants, a minimum version for the Lynx
 
433
          browsers and a average feature version for all others.</p>
 
434
        </dd>
 
435
 
 
436
        <dt>Solution:</dt>
 
437
 
 
438
        <dd>
 
439
          <p>We cannot use content negotiation because the browsers do
 
440
          not provide their type in that form. Instead we have to
 
441
          act on the HTTP header "User-Agent". The following condig
 
442
          does the following: If the HTTP header "User-Agent"
 
443
          begins with "Mozilla/3", the page <code>foo.html</code>
 
444
          is rewritten to <code>foo.NS.html</code> and and the
 
445
          rewriting stops. If the browser is "Lynx" or "Mozilla" of
 
446
          version 1 or 2 the URL becomes <code>foo.20.html</code>.
 
447
          All other browsers receive page <code>foo.32.html</code>.
 
448
          This is done by the following ruleset:</p>
 
449
 
 
450
<div class="example"><pre>
 
451
RewriteCond %{HTTP_USER_AGENT}  ^<strong>Mozilla/3</strong>.*
 
452
RewriteRule ^foo\.html$         foo.<strong>NS</strong>.html          [<strong>L</strong>]
 
453
 
 
454
RewriteCond %{HTTP_USER_AGENT}  ^<strong>Lynx/</strong>.*         [OR]
 
455
RewriteCond %{HTTP_USER_AGENT}  ^<strong>Mozilla/[12]</strong>.*
 
456
RewriteRule ^foo\.html$         foo.<strong>20</strong>.html          [<strong>L</strong>]
 
457
 
 
458
RewriteRule ^foo\.html$         foo.<strong>32</strong>.html          [<strong>L</strong>]
 
459
</pre></div>
 
460
        </dd>
 
461
      </dl>
 
462
 
 
463
    
 
464
 
 
465
    <h3>Dynamic Mirror</h3>
 
466
 
 
467
      
 
468
 
 
469
      <dl>
 
470
        <dt>Description:</dt>
 
471
 
 
472
        <dd>
 
473
          <p>Assume there are nice webpages on remote hosts we want
 
474
          to bring into our namespace. For FTP servers we would use
 
475
          the <code>mirror</code> program which actually maintains an
 
476
          explicit up-to-date copy of the remote data on the local
 
477
          machine. For a webserver we could use the program
 
478
          <code>webcopy</code> which acts similar via HTTP. But both
 
479
          techniques have one major drawback: The local copy is
 
480
          always just as up-to-date as often we run the program. It
 
481
          would be much better if the mirror is not a static one we
 
482
          have to establish explicitly. Instead we want a dynamic
 
483
          mirror with data which gets updated automatically when
 
484
          there is need (updated data on the remote host).</p>
 
485
        </dd>
 
486
 
 
487
        <dt>Solution:</dt>
 
488
 
 
489
        <dd>
 
490
          <p>To provide this feature we map the remote webpage or even
 
491
          the complete remote webarea to our namespace by the use
 
492
          of the <dfn>Proxy Throughput</dfn> feature
 
493
          (flag <code>[P]</code>):</p>
 
494
 
 
495
<div class="example"><pre>
 
496
RewriteEngine  on
 
497
RewriteBase    /~quux/
 
498
RewriteRule    ^<strong>hotsheet/</strong>(.*)$  <strong>http://www.tstimpreso.com/hotsheet/</strong>$1  [<strong>P</strong>]
 
499
</pre></div>
 
500
 
 
501
<div class="example"><pre>
 
502
RewriteEngine  on
 
503
RewriteBase    /~quux/
 
504
RewriteRule    ^<strong>usa-news\.html</strong>$   <strong>http://www.quux-corp.com/news/index.html</strong>  [<strong>P</strong>]
 
505
</pre></div>
 
506
        </dd>
 
507
      </dl>
 
508
 
 
509
    
 
510
 
 
511
    <h3>Reverse Dynamic Mirror</h3>
 
512
 
 
513
      
 
514
 
 
515
      <dl>
 
516
        <dt>Description:</dt>
 
517
 
 
518
        <dd>...</dd>
 
519
 
 
520
        <dt>Solution:</dt>
 
521
 
 
522
        <dd>
 
523
<div class="example"><pre>
 
524
RewriteEngine on
 
525
RewriteCond   /mirror/of/remotesite/$1           -U
 
526
RewriteRule   ^http://www\.remotesite\.com/(.*)$ /mirror/of/remotesite/$1
 
527
</pre></div>
 
528
        </dd>
 
529
      </dl>
 
530
 
 
531
    
 
532
 
 
533
    <h3>Retrieve Missing Data from Intranet</h3>
 
534
 
 
535
      
 
536
 
 
537
      <dl>
 
538
        <dt>Description:</dt>
 
539
 
 
540
        <dd>
 
541
          <p>This is a tricky way of virtually running a corporate
 
542
          (external) Internet webserver
 
543
          (<code>www.quux-corp.dom</code>), while actually keeping
 
544
          and maintaining its data on a (internal) Intranet webserver
 
545
          (<code>www2.quux-corp.dom</code>) which is protected by a
 
546
          firewall. The trick is that on the external webserver we
 
547
          retrieve the requested data on-the-fly from the internal
 
548
          one.</p>
 
549
        </dd>
 
550
 
 
551
        <dt>Solution:</dt>
 
552
 
 
553
        <dd>
 
554
          <p>First, we have to make sure that our firewall still
 
555
          protects the internal webserver and that only the
 
556
          external webserver is allowed to retrieve data from it.
 
557
          For a packet-filtering firewall we could for instance
 
558
          configure a firewall ruleset like the following:</p>
 
559
 
 
560
<div class="example"><pre>
 
561
<strong>ALLOW</strong> Host www.quux-corp.dom Port &gt;1024 --&gt; Host www2.quux-corp.dom Port <strong>80</strong>
 
562
<strong>DENY</strong>  Host *                 Port *     --&gt; Host www2.quux-corp.dom Port <strong>80</strong>
 
563
</pre></div>
 
564
 
 
565
          <p>Just adjust it to your actual configuration syntax.
 
566
          Now we can establish the <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>
 
567
          rules which request the missing data in the background
 
568
          through the proxy throughput feature:</p>
 
569
 
 
570
<div class="example"><pre>
 
571
RewriteRule ^/~([^/]+)/?(.*)          /home/$1/.www/$2
 
572
RewriteCond %{REQUEST_FILENAME}       <strong>!-f</strong>
 
573
RewriteCond %{REQUEST_FILENAME}       <strong>!-d</strong>
 
574
RewriteRule ^/home/([^/]+)/.www/?(.*) http://<strong>www2</strong>.quux-corp.dom/~$1/pub/$2 [<strong>P</strong>]
 
575
</pre></div>
 
576
        </dd>
 
577
      </dl>
 
578
 
 
579
    
 
580
 
 
581
    <h3>Load Balancing</h3>
 
582
 
 
583
      
 
584
 
 
585
      <dl>
 
586
        <dt>Description:</dt>
 
587
 
 
588
        <dd>
 
589
          <p>Suppose we want to load balance the traffic to
 
590
          <code>www.foo.com</code> over <code>www[0-5].foo.com</code>
 
591
          (a total of 6 servers). How can this be done?</p>
 
592
        </dd>
 
593
 
 
594
        <dt>Solution:</dt>
 
595
 
 
596
        <dd>
 
597
          <p>There are a lot of possible solutions for this problem.
 
598
          We will discuss first a commonly known DNS-based variant
 
599
          and then the special one with <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>:</p>
 
600
 
 
601
          <ol>
 
602
            <li>
 
603
              <strong>DNS Round-Robin</strong>
 
604
 
 
605
              <p>The simplest method for load-balancing is to use
 
606
              the DNS round-robin feature of <code>BIND</code>.
 
607
              Here you just configure <code>www[0-9].foo.com</code>
 
608
              as usual in your DNS with A(address) records, e.g.</p>
 
609
 
 
610
<div class="example"><pre>
 
611
www0   IN  A       1.2.3.1
 
612
www1   IN  A       1.2.3.2
 
613
www2   IN  A       1.2.3.3
 
614
www3   IN  A       1.2.3.4
 
615
www4   IN  A       1.2.3.5
 
616
www5   IN  A       1.2.3.6
 
617
</pre></div>
 
618
 
 
619
              <p>Then you additionally add the following entry:</p>
 
620
 
 
621
<div class="example"><pre>
 
622
www    IN  CNAME   www0.foo.com.
 
623
       IN  CNAME   www1.foo.com.
 
624
       IN  CNAME   www2.foo.com.
 
625
       IN  CNAME   www3.foo.com.
 
626
       IN  CNAME   www4.foo.com.
 
627
       IN  CNAME   www5.foo.com.
 
628
       IN  CNAME   www6.foo.com.
 
629
</pre></div>
 
630
 
 
631
              <p>Notice that this seems wrong, but is actually an
 
632
              intended feature of <code>BIND</code> and can be used
 
633
              in this way. However, now when <code>www.foo.com</code> gets
 
634
              resolved, <code>BIND</code> gives out <code>www0-www6</code>
 
635
              - but in a slightly permutated/rotated order every time.
 
636
              This way the clients are spread over the various
 
637
              servers. But notice that this not a perfect load
 
638
              balancing scheme, because DNS resolve information
 
639
              gets cached by the other nameservers on the net, so
 
640
              once a client has resolved <code>www.foo.com</code>
 
641
              to a particular <code>wwwN.foo.com</code>, all
 
642
              subsequent requests also go to this particular name
 
643
              <code>wwwN.foo.com</code>. But the final result is
 
644
              ok, because the total sum of the requests are really
 
645
              spread over the various webservers.</p>
 
646
            </li>
 
647
 
 
648
            <li>
 
649
              <strong>DNS Load-Balancing</strong>
 
650
 
 
651
              <p>A sophisticated DNS-based method for
 
652
              load-balancing is to use the program
 
653
              <code>lbnamed</code> which can be found at <a href="http://www.stanford.edu/~schemers/docs/lbnamed/lbnamed.html">
 
654
              http://www.stanford.edu/~schemers/docs/lbnamed/lbnamed.html</a>.
 
655
              It is a Perl 5 program in conjunction with auxilliary
 
656
              tools which provides a real load-balancing for
 
657
              DNS.</p>
 
658
            </li>
 
659
 
 
660
            <li>
 
661
              <strong>Proxy Throughput Round-Robin</strong>
 
662
 
 
663
              <p>In this variant we use <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>
 
664
              and its proxy throughput feature. First we dedicate
 
665
              <code>www0.foo.com</code> to be actually
 
666
              <code>www.foo.com</code> by using a single</p>
 
667
 
 
668
<div class="example"><pre>
 
669
www    IN  CNAME   www0.foo.com.
 
670
</pre></div>
 
671
 
 
672
              <p>entry in the DNS. Then we convert
 
673
              <code>www0.foo.com</code> to a proxy-only server,
 
674
              i.e. we configure this machine so all arriving URLs
 
675
              are just pushed through the internal proxy to one of
 
676
              the 5 other servers (<code>www1-www5</code>). To
 
677
              accomplish this we first establish a ruleset which
 
678
              contacts a load balancing script <code>lb.pl</code>
 
679
              for all URLs.</p>
 
680
 
 
681
<div class="example"><pre>
 
682
RewriteEngine on
 
683
RewriteMap    lb      prg:/path/to/lb.pl
 
684
RewriteRule   ^/(.+)$ ${lb:$1}           [P,L]
 
685
</pre></div>
 
686
 
 
687
              <p>Then we write <code>lb.pl</code>:</p>
 
688
 
 
689
<div class="example"><pre>
 
690
#!/path/to/perl
 
691
##
 
692
##  lb.pl -- load balancing script
 
693
##
 
694
 
 
695
$| = 1;
 
696
 
 
697
$name   = "www";     # the hostname base
 
698
$first  = 1;         # the first server (not 0 here, because 0 is myself)
 
699
$last   = 5;         # the last server in the round-robin
 
700
$domain = "foo.dom"; # the domainname
 
701
 
 
702
$cnt = 0;
 
703
while (&lt;STDIN&gt;) {
 
704
    $cnt = (($cnt+1) % ($last+1-$first));
 
705
    $server = sprintf("%s%d.%s", $name, $cnt+$first, $domain);
 
706
    print "http://$server/$_";
 
707
}
 
708
 
 
709
##EOF##
 
710
</pre></div>
 
711
 
 
712
              <div class="note">A last notice: Why is this useful? Seems like
 
713
              <code>www0.foo.com</code> still is overloaded? The
 
714
              answer is yes, it is overloaded, but with plain proxy
 
715
              throughput requests, only! All SSI, CGI, ePerl, etc.
 
716
              processing is completely done on the other machines.
 
717
              This is the essential point.</div>
 
718
            </li>
 
719
 
 
720
            <li>
 
721
              <strong>Hardware/TCP Round-Robin</strong>
 
722
 
 
723
              <p>There is a hardware solution available, too. Cisco
 
724
              has a beast called LocalDirector which does a load
 
725
              balancing at the TCP/IP level. Actually this is some
 
726
              sort of a circuit level gateway in front of a
 
727
              webcluster. If you have enough money and really need
 
728
              a solution with high performance, use this one.</p>
 
729
            </li>
 
730
          </ol>
 
731
        </dd>
 
732
      </dl>
 
733
 
 
734
    
 
735
 
 
736
    <h3>New MIME-type, New Service</h3>
 
737
 
 
738
      
 
739
 
 
740
      <dl>
 
741
        <dt>Description:</dt>
 
742
 
 
743
        <dd>
 
744
          <p>On the net there are a lot of nifty CGI programs. But
 
745
          their usage is usually boring, so a lot of webmaster
 
746
          don't use them. Even Apache's Action handler feature for
 
747
          MIME-types is only appropriate when the CGI programs
 
748
          don't need special URLs (actually <code>PATH_INFO</code>
 
749
          and <code>QUERY_STRINGS</code>) as their input. First,
 
750
          let us configure a new file type with extension
 
751
          <code>.scgi</code> (for secure CGI) which will be processed
 
752
          by the popular <code>cgiwrap</code> program. The problem
 
753
          here is that for instance we use a Homogeneous URL Layout
 
754
          (see above) a file inside the user homedirs has the URL
 
755
          <code>/u/user/foo/bar.scgi</code>. But
 
756
          <code>cgiwrap</code> needs the URL in the form
 
757
          <code>/~user/foo/bar.scgi/</code>. The following rule
 
758
          solves the problem:</p>
 
759
 
 
760
<div class="example"><pre>
 
761
RewriteRule ^/[uge]/<strong>([^/]+)</strong>/\.www/(.+)\.scgi(.*) ...
 
762
... /internal/cgi/user/cgiwrap/~<strong>$1</strong>/$2.scgi$3  [NS,<strong>T=application/x-http-cgi</strong>]
 
763
</pre></div>
 
764
 
 
765
          <p>Or assume we have some more nifty programs:
 
766
          <code>wwwlog</code> (which displays the
 
767
          <code>access.log</code> for a URL subtree and
 
768
          <code>wwwidx</code> (which runs Glimpse on a URL
 
769
          subtree). We have to provide the URL area to these
 
770
          programs so they know on which area they have to act on.
 
771
          But usually this ugly, because they are all the times
 
772
          still requested from that areas, i.e. typically we would
 
773
          run the <code>swwidx</code> program from within
 
774
          <code>/u/user/foo/</code> via hyperlink to</p>
 
775
 
 
776
<div class="example"><pre>
 
777
/internal/cgi/user/swwidx?i=/u/user/foo/
 
778
</pre></div>
 
779
 
 
780
          <p>which is ugly. Because we have to hard-code
 
781
          <strong>both</strong> the location of the area
 
782
          <strong>and</strong> the location of the CGI inside the
 
783
          hyperlink. When we have to reorganize the area, we spend a
 
784
          lot of time changing the various hyperlinks.</p>
 
785
        </dd>
 
786
 
 
787
        <dt>Solution:</dt>
 
788
 
 
789
        <dd>
 
790
          <p>The solution here is to provide a special new URL format
 
791
          which automatically leads to the proper CGI invocation.
 
792
          We configure the following:</p>
 
793
 
 
794
<div class="example"><pre>
 
795
RewriteRule   ^/([uge])/([^/]+)(/?.*)/\*  /internal/cgi/user/wwwidx?i=/$1/$2$3/
 
796
RewriteRule   ^/([uge])/([^/]+)(/?.*):log /internal/cgi/user/wwwlog?f=/$1/$2$3
 
797
</pre></div>
 
798
 
 
799
          <p>Now the hyperlink to search at
 
800
          <code>/u/user/foo/</code> reads only</p>
 
801
 
 
802
<div class="example"><pre>
 
803
HREF="*"
 
804
</pre></div>
 
805
 
 
806
          <p>which internally gets automatically transformed to</p>
 
807
 
 
808
<div class="example"><pre>
 
809
/internal/cgi/user/wwwidx?i=/u/user/foo/
 
810
</pre></div>
 
811
 
 
812
          <p>The same approach leads to an invocation for the
 
813
          access log CGI program when the hyperlink
 
814
          <code>:log</code> gets used.</p>
 
815
        </dd>
 
816
      </dl>
 
817
 
 
818
    
 
819
 
 
820
    <h3>On-the-fly Content-Regeneration</h3>
 
821
 
 
822
      
 
823
 
 
824
      <dl>
 
825
        <dt>Description:</dt>
 
826
 
 
827
        <dd>
 
828
          <p>Here comes a really esoteric feature: Dynamically
 
829
          generated but statically served pages, i.e. pages should be
 
830
          delivered as pure static pages (read from the filesystem
 
831
          and just passed through), but they have to be generated
 
832
          dynamically by the webserver if missing. This way you can
 
833
          have CGI-generated pages which are statically served unless
 
834
          one (or a cronjob) removes the static contents. Then the
 
835
          contents gets refreshed.</p>
 
836
        </dd>
 
837
 
 
838
        <dt>Solution:</dt>
 
839
 
 
840
        <dd>
 
841
          This is done via the following ruleset:
 
842
 
 
843
<div class="example"><pre>
 
844
RewriteCond %{REQUEST_FILENAME}   <strong>!-s</strong>
 
845
RewriteRule ^page\.<strong>html</strong>$          page.<strong>cgi</strong>   [T=application/x-httpd-cgi,L]
 
846
</pre></div>
 
847
 
 
848
          <p>Here a request to <code>page.html</code> leads to a
 
849
          internal run of a corresponding <code>page.cgi</code> if
 
850
          <code>page.html</code> is still missing or has filesize
 
851
          null. The trick here is that <code>page.cgi</code> is a
 
852
          usual CGI script which (additionally to its <code>STDOUT</code>)
 
853
          writes its output to the file <code>page.html</code>.
 
854
          Once it was run, the server sends out the data of
 
855
          <code>page.html</code>. When the webmaster wants to force
 
856
          a refresh the contents, he just removes
 
857
          <code>page.html</code> (usually done by a cronjob).</p>
 
858
        </dd>
 
859
      </dl>
 
860
 
 
861
    
 
862
 
 
863
    <h3>Document With Autorefresh</h3>
 
864
 
 
865
      
 
866
 
 
867
      <dl>
 
868
        <dt>Description:</dt>
 
869
 
 
870
        <dd>
 
871
          <p>Wouldn't it be nice while creating a complex webpage if
 
872
          the webbrowser would automatically refresh the page every
 
873
          time we write a new version from within our editor?
 
874
          Impossible?</p>
 
875
        </dd>
 
876
 
 
877
        <dt>Solution:</dt>
 
878
 
 
879
        <dd>
 
880
          <p>No! We just combine the MIME multipart feature, the
 
881
          webserver NPH feature and the URL manipulation power of
 
882
          <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>. First, we establish a new
 
883
          URL feature: Adding just <code>:refresh</code> to any
 
884
          URL causes this to be refreshed every time it gets
 
885
          updated on the filesystem.</p>
 
886
 
 
887
<div class="example"><pre>
 
888
RewriteRule   ^(/[uge]/[^/]+/?.*):refresh  /internal/cgi/apache/nph-refresh?f=$1
 
889
</pre></div>
 
890
 
 
891
          <p>Now when we reference the URL</p>
 
892
 
 
893
<div class="example"><pre>
 
894
/u/foo/bar/page.html:refresh
 
895
</pre></div>
 
896
 
 
897
          <p>this leads to the internal invocation of the URL</p>
 
898
 
 
899
<div class="example"><pre>
 
900
/internal/cgi/apache/nph-refresh?f=/u/foo/bar/page.html
 
901
</pre></div>
 
902
 
 
903
          <p>The only missing part is the NPH-CGI script. Although
 
904
          one would usually say "left as an exercise to the reader"
 
905
          ;-) I will provide this, too.</p>
 
906
 
 
907
<div class="example"><pre>
 
908
#!/sw/bin/perl
 
909
##
 
910
##  nph-refresh -- NPH/CGI script for auto refreshing pages
 
911
##  Copyright (c) 1997 Ralf S. Engelschall, All Rights Reserved.
 
912
##
 
913
$| = 1;
 
914
 
 
915
#   split the QUERY_STRING variable
 
916
@pairs = split(/&amp;/, $ENV{'QUERY_STRING'});
 
917
foreach $pair (@pairs) {
 
918
    ($name, $value) = split(/=/, $pair);
 
919
    $name =~ tr/A-Z/a-z/;
 
920
    $name = 'QS_' . $name;
 
921
    $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
 
922
    eval "\$$name = \"$value\"";
 
923
}
 
924
$QS_s = 1 if ($QS_s eq '');
 
925
$QS_n = 3600 if ($QS_n eq '');
 
926
if ($QS_f eq '') {
 
927
    print "HTTP/1.0 200 OK\n";
 
928
    print "Content-type: text/html\n\n";
 
929
    print "&amp;lt;b&amp;gt;ERROR&amp;lt;/b&amp;gt;: No file given\n";
 
930
    exit(0);
 
931
}
 
932
if (! -f $QS_f) {
 
933
    print "HTTP/1.0 200 OK\n";
 
934
    print "Content-type: text/html\n\n";
 
935
    print "&amp;lt;b&amp;gt;ERROR&amp;lt;/b&amp;gt;: File $QS_f not found\n";
 
936
    exit(0);
 
937
}
 
938
 
 
939
sub print_http_headers_multipart_begin {
 
940
    print "HTTP/1.0 200 OK\n";
 
941
    $bound = "ThisRandomString12345";
 
942
    print "Content-type: multipart/x-mixed-replace;boundary=$bound\n";
 
943
    &amp;print_http_headers_multipart_next;
 
944
}
 
945
 
 
946
sub print_http_headers_multipart_next {
 
947
    print "\n--$bound\n";
 
948
}
 
949
 
 
950
sub print_http_headers_multipart_end {
 
951
    print "\n--$bound--\n";
 
952
}
 
953
 
 
954
sub displayhtml {
 
955
    local($buffer) = @_;
 
956
    $len = length($buffer);
 
957
    print "Content-type: text/html\n";
 
958
    print "Content-length: $len\n\n";
 
959
    print $buffer;
 
960
}
 
961
 
 
962
sub readfile {
 
963
    local($file) = @_;
 
964
    local(*FP, $size, $buffer, $bytes);
 
965
    ($x, $x, $x, $x, $x, $x, $x, $size) = stat($file);
 
966
    $size = sprintf("%d", $size);
 
967
    open(FP, "&amp;lt;$file");
 
968
    $bytes = sysread(FP, $buffer, $size);
 
969
    close(FP);
 
970
    return $buffer;
 
971
}
 
972
 
 
973
$buffer = &amp;readfile($QS_f);
 
974
&amp;print_http_headers_multipart_begin;
 
975
&amp;displayhtml($buffer);
 
976
 
 
977
sub mystat {
 
978
    local($file) = $_[0];
 
979
    local($time);
 
980
 
 
981
    ($x, $x, $x, $x, $x, $x, $x, $x, $x, $mtime) = stat($file);
 
982
    return $mtime;
 
983
}
 
984
 
 
985
$mtimeL = &amp;mystat($QS_f);
 
986
$mtime = $mtime;
 
987
for ($n = 0; $n &amp;lt; $QS_n; $n++) {
 
988
    while (1) {
 
989
        $mtime = &amp;mystat($QS_f);
 
990
        if ($mtime ne $mtimeL) {
 
991
            $mtimeL = $mtime;
 
992
            sleep(2);
 
993
            $buffer = &amp;readfile($QS_f);
 
994
            &amp;print_http_headers_multipart_next;
 
995
            &amp;displayhtml($buffer);
 
996
            sleep(5);
 
997
            $mtimeL = &amp;mystat($QS_f);
 
998
            last;
 
999
        }
 
1000
        sleep($QS_s);
 
1001
    }
 
1002
}
 
1003
 
 
1004
&amp;print_http_headers_multipart_end;
 
1005
 
 
1006
exit(0);
 
1007
 
 
1008
##EOF##
 
1009
</pre></div>
 
1010
        </dd>
 
1011
      </dl>
 
1012
 
 
1013
    
 
1014
 
 
1015
    <h3>Mass Virtual Hosting</h3>
 
1016
 
 
1017
      
 
1018
 
 
1019
      <dl>
 
1020
        <dt>Description:</dt>
 
1021
 
 
1022
        <dd>
 
1023
          <p>The <code class="directive"><a href="../mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code> feature of Apache is nice
 
1024
          and works great when you just have a few dozens
 
1025
          virtual hosts. But when you are an ISP and have hundreds of
 
1026
          virtual hosts to provide this feature is not the best
 
1027
          choice.</p>
 
1028
        </dd>
 
1029
 
 
1030
        <dt>Solution:</dt>
 
1031
 
 
1032
        <dd>
 
1033
          <p>To provide this feature we map the remote webpage or even
 
1034
          the complete remote webarea to our namespace by the use
 
1035
          of the <dfn>Proxy Throughput</dfn> feature (flag <code>[P]</code>):</p>
 
1036
 
 
1037
<div class="example"><pre>
 
1038
##
 
1039
##  vhost.map
 
1040
##
 
1041
www.vhost1.dom:80  /path/to/docroot/vhost1
 
1042
www.vhost2.dom:80  /path/to/docroot/vhost2
 
1043
     :
 
1044
www.vhostN.dom:80  /path/to/docroot/vhostN
 
1045
</pre></div>
 
1046
 
 
1047
<div class="example"><pre>
 
1048
##
 
1049
##  httpd.conf
 
1050
##
 
1051
    :
 
1052
#   use the canonical hostname on redirects, etc.
 
1053
UseCanonicalName on
 
1054
 
 
1055
    :
 
1056
#   add the virtual host in front of the CLF-format
 
1057
CustomLog  /path/to/access_log  "%{VHOST}e %h %l %u %t \"%r\" %&gt;s %b"
 
1058
    :
 
1059
 
 
1060
#   enable the rewriting engine in the main server
 
1061
RewriteEngine on
 
1062
 
 
1063
#   define two maps: one for fixing the URL and one which defines
 
1064
#   the available virtual hosts with their corresponding
 
1065
#   DocumentRoot.
 
1066
RewriteMap    lowercase    int:tolower
 
1067
RewriteMap    vhost        txt:/path/to/vhost.map
 
1068
 
 
1069
#   Now do the actual virtual host mapping
 
1070
#   via a huge and complicated single rule:
 
1071
#
 
1072
#   1. make sure we don't map for common locations
 
1073
RewriteCond   %{REQUEST_URI}  !^/commonurl1/.*
 
1074
RewriteCond   %{REQUEST_URI}  !^/commonurl2/.*
 
1075
    :
 
1076
RewriteCond   %{REQUEST_URI}  !^/commonurlN/.*
 
1077
#
 
1078
#   2. make sure we have a Host header, because
 
1079
#      currently our approach only supports
 
1080
#      virtual hosting through this header
 
1081
RewriteCond   %{HTTP_HOST}  !^$
 
1082
#
 
1083
#   3. lowercase the hostname
 
1084
RewriteCond   ${lowercase:%{HTTP_HOST}|NONE}  ^(.+)$
 
1085
#
 
1086
#   4. lookup this hostname in vhost.map and
 
1087
#      remember it only when it is a path
 
1088
#      (and not "NONE" from above)
 
1089
RewriteCond   ${vhost:%1}  ^(/.*)$
 
1090
#
 
1091
#   5. finally we can map the URL to its docroot location
 
1092
#      and remember the virtual host for logging puposes
 
1093
RewriteRule   ^/(.*)$   %1/$1  [E=VHOST:${lowercase:%{HTTP_HOST}}]
 
1094
    :
 
1095
</pre></div>
 
1096
        </dd>
 
1097
      </dl>
 
1098
 
 
1099
    
 
1100
 
 
1101
  </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
 
1102
<div class="section">
 
1103
<h2><a name="access" id="access">Access Restriction</a></h2>
 
1104
 
 
1105
    
 
1106
 
 
1107
    <h3>Host Deny</h3>
 
1108
 
 
1109
      
 
1110
 
 
1111
      <dl>
 
1112
        <dt>Description:</dt>
 
1113
 
 
1114
        <dd>
 
1115
          <p>How can we forbid a list of externally configured hosts
 
1116
          from using our server?</p>
 
1117
        </dd>
 
1118
 
 
1119
        <dt>Solution:</dt>
 
1120
 
 
1121
        <dd>
 
1122
          <p>For Apache &gt;= 1.3b6:</p>
 
1123
 
 
1124
<div class="example"><pre>
 
1125
RewriteEngine on
 
1126
RewriteMap    hosts-deny  txt:/path/to/hosts.deny
 
1127
RewriteCond   ${hosts-deny:%{REMOTE_HOST}|NOT-FOUND} !=NOT-FOUND [OR]
 
1128
RewriteCond   ${hosts-deny:%{REMOTE_ADDR}|NOT-FOUND} !=NOT-FOUND
 
1129
RewriteRule   ^/.*  -  [F]
 
1130
</pre></div>
 
1131
 
 
1132
          <p>For Apache &lt;= 1.3b6:</p>
 
1133
 
 
1134
<div class="example"><pre>
 
1135
RewriteEngine on
 
1136
RewriteMap    hosts-deny  txt:/path/to/hosts.deny
 
1137
RewriteRule   ^/(.*)$ ${hosts-deny:%{REMOTE_HOST}|NOT-FOUND}/$1
 
1138
RewriteRule   !^NOT-FOUND/.* - [F]
 
1139
RewriteRule   ^NOT-FOUND/(.*)$ ${hosts-deny:%{REMOTE_ADDR}|NOT-FOUND}/$1
 
1140
RewriteRule   !^NOT-FOUND/.* - [F]
 
1141
RewriteRule   ^NOT-FOUND/(.*)$ /$1
 
1142
</pre></div>
 
1143
 
 
1144
<div class="example"><pre>
 
1145
##
 
1146
##  hosts.deny
 
1147
##
 
1148
##  ATTENTION! This is a map, not a list, even when we treat it as such.
 
1149
##             mod_rewrite parses it for key/value pairs, so at least a
 
1150
##             dummy value "-" must be present for each entry.
 
1151
##
 
1152
 
 
1153
193.102.180.41 -
 
1154
bsdti1.sdm.de  -
 
1155
192.76.162.40  -
 
1156
</pre></div>
 
1157
        </dd>
 
1158
      </dl>
 
1159
 
 
1160
    
 
1161
 
 
1162
    <h3>Proxy Deny</h3>
 
1163
 
 
1164
      
 
1165
 
 
1166
      <dl>
 
1167
        <dt>Description:</dt>
 
1168
 
 
1169
        <dd>
 
1170
          <p>How can we forbid a certain host or even a user of a
 
1171
          special host from using the Apache proxy?</p>
 
1172
        </dd>
 
1173
 
 
1174
        <dt>Solution:</dt>
 
1175
 
 
1176
        <dd>
 
1177
          <p>We first have to make sure <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>
 
1178
          is below(!) <code class="module"><a href="../mod/mod_proxy.html">mod_proxy</a></code> in the Configuration
 
1179
          file when compiling the Apache webserver. This way it gets
 
1180
          called <em>before</em> <code class="module"><a href="../mod/mod_proxy.html">mod_proxy</a></code>. Then we
 
1181
          configure the following for a host-dependent deny...</p>
 
1182
 
 
1183
<div class="example"><pre>
 
1184
RewriteCond %{REMOTE_HOST} <strong>^badhost\.mydomain\.com$</strong>
 
1185
RewriteRule !^http://[^/.]\.mydomain.com.*  - [F]
 
1186
</pre></div>
 
1187
 
 
1188
          <p>...and this one for a user@host-dependent deny:</p>
 
1189
 
 
1190
<div class="example"><pre>
 
1191
RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST}  <strong>^badguy@badhost\.mydomain\.com$</strong>
 
1192
RewriteRule !^http://[^/.]\.mydomain.com.*  - [F]
 
1193
</pre></div>
 
1194
        </dd>
 
1195
      </dl>
 
1196
 
 
1197
    
 
1198
 
 
1199
    <h3>Special Authentication Variant</h3>
 
1200
 
 
1201
      
 
1202
 
 
1203
      <dl>
 
1204
        <dt>Description:</dt>
 
1205
 
 
1206
        <dd>
 
1207
          <p>Sometimes a very special authentication is needed, for
 
1208
          instance a authentication which checks for a set of
 
1209
          explicitly configured users. Only these should receive
 
1210
          access and without explicit prompting (which would occur
 
1211
          when using the Basic Auth via <code class="module"><a href="../mod/mod_auth.html">mod_auth</a></code>).</p>
 
1212
        </dd>
 
1213
 
 
1214
        <dt>Solution:</dt>
 
1215
 
 
1216
        <dd>
 
1217
          <p>We use a list of rewrite conditions to exclude all except
 
1218
          our friends:</p>
 
1219
 
 
1220
<div class="example"><pre>
 
1221
RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST} <strong>!^friend1@client1.quux-corp\.com$</strong>
 
1222
RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST} <strong>!^friend2</strong>@client2.quux-corp\.com$
 
1223
RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST} <strong>!^friend3</strong>@client3.quux-corp\.com$
 
1224
RewriteRule ^/~quux/only-for-friends/      -                                 [F]
 
1225
</pre></div>
 
1226
        </dd>
 
1227
      </dl>
 
1228
 
 
1229
    
 
1230
 
 
1231
    <h3>Referer-based Deflector</h3>
 
1232
 
 
1233
      
 
1234
 
 
1235
      <dl>
 
1236
        <dt>Description:</dt>
 
1237
 
 
1238
        <dd>
 
1239
          <p>How can we program a flexible URL Deflector which acts
 
1240
          on the "Referer" HTTP header and can be configured with as
 
1241
          many referring pages as we like?</p>
 
1242
        </dd>
 
1243
 
 
1244
        <dt>Solution:</dt>
 
1245
 
 
1246
        <dd>
 
1247
          <p>Use the following really tricky ruleset...</p>
 
1248
 
 
1249
<div class="example"><pre>
 
1250
RewriteMap  deflector txt:/path/to/deflector.map
 
1251
 
 
1252
RewriteCond %{HTTP_REFERER} !=""
 
1253
RewriteCond ${deflector:%{HTTP_REFERER}} ^-$
 
1254
RewriteRule ^.* %{HTTP_REFERER} [R,L]
 
1255
 
 
1256
RewriteCond %{HTTP_REFERER} !=""
 
1257
RewriteCond ${deflector:%{HTTP_REFERER}|NOT-FOUND} !=NOT-FOUND
 
1258
RewriteRule ^.* ${deflector:%{HTTP_REFERER}} [R,L]
 
1259
</pre></div>
 
1260
 
 
1261
          <p>... in conjunction with a corresponding rewrite
 
1262
          map:</p>
 
1263
 
 
1264
<div class="example"><pre>
 
1265
##
 
1266
##  deflector.map
 
1267
##
 
1268
 
 
1269
http://www.badguys.com/bad/index.html    -
 
1270
http://www.badguys.com/bad/index2.html   -
 
1271
http://www.badguys.com/bad/index3.html   http://somewhere.com/
 
1272
</pre></div>
 
1273
 
 
1274
          <p>This automatically redirects the request back to the
 
1275
          referring page (when "<code>-</code>" is used as the value
 
1276
          in the map) or to a specific URL (when an URL is specified
 
1277
          in the map as the second argument).</p>
 
1278
        </dd>
 
1279
      </dl>
 
1280
 
 
1281
    
 
1282
 
 
1283
  </div></div>
 
1284
<div class="bottomlang">
 
1285
<p><span>Available Languages: </span><a href="../en/rewrite/rewrite_guide_advanced.html" title="English">&nbsp;en&nbsp;</a></p>
 
1286
</div><div id="footer">
 
1287
<p class="apache">Copyright 2006 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
 
1288
<p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="../faq/">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div>
 
1289
</body></html>
 
 
b'\\ No newline at end of file'