]> granicus.if.org Git - apache/commitdiff
Add documentation for mod_policy, as well as explanatory documentation
authorGraham Leggett <minfrin@apache.org>
Wed, 21 Dec 2011 10:45:03 +0000 (10:45 +0000)
committerGraham Leggett <minfrin@apache.org>
Wed, 21 Dec 2011 10:45:03 +0000 (10:45 +0000)
for developers or end users affected by each policy.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1221670 13f79535-47bb-0310-9956-ffa450edef68

docs/manual/compliance.xml [new file with mode: 0644]
docs/manual/filter.xml
docs/manual/index.xml
docs/manual/mod/allmodules.xml
docs/manual/mod/mod_policy.xml [new file with mode: 0644]

diff --git a/docs/manual/compliance.xml b/docs/manual/compliance.xml
new file mode 100644 (file)
index 0000000..655e187
--- /dev/null
@@ -0,0 +1,534 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE manualpage SYSTEM "./style/manualpage.dtd">
+<?xml-stylesheet type="text/xsl" href="./style/manual.en.xsl"?>
+<!-- $LastChangedRevision: 1189549 $ -->
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manualpage metafile="compliance.xml.meta">
+
+  <title>HTTP Protocol Compliance</title>
+
+  <summary>
+    <p>This document describes the mechanism to set a policy for HTTP
+    protocol compliance for a given URL space by the origin servers or
+    applications behind that URL space.</p>
+
+    <p>For those who may have received an error message from a rejected
+    policy, and need to know what the policy rejection means and what
+    they might do to fix the error, each policy is described below.</p>
+  </summary>
+  <seealso><a href="filter.html">Filters</a></seealso>
+
+  <section id="intro">
+    <title>Enforcing HTTP Protocol Compliance in Apache 2</title>
+    <related>
+      <modulelist>
+        <module>mod_policy</module>
+      </modulelist>
+      <directivelist>
+        <directive module="mod_policy">PolicyConditional</directive>
+        <directive module="mod_policy">PolicyLength</directive>
+        <directive module="mod_policy">PolicyKeepalive</directive>
+        <directive module="mod_policy">PolicyType</directive>
+        <directive module="mod_policy">PolicyVary</directive>
+        <directive module="mod_policy">PolicyValidation</directive>
+        <directive module="mod_policy">PolicyNocache</directive>
+        <directive module="mod_policy">PolicyMaxage</directive>
+        <directive module="mod_policy">PolicyVersion</directive>
+      </directivelist>
+    </related>
+
+    <p>The HTTP protocol follows the <strong>robustness principle</strong>
+    as described in <a href="http://tools.ietf.org/html/rfc1122">RFC1122</a>,
+    which states <strong>"Be liberal in what you accept, and conservative in
+    what you send"</strong>. As a result of this principle, HTTP clients will
+    compensate for and recover from incorrect or misconfigured responses, or
+    responses that are uncacheable.</p>
+
+    <p>As a website is scaled up to face greater and greater traffic loads,
+    suboptimal or misconfigured applications or server configurations can
+    threaten both the stability and scalability of the website, as well as
+    the hosting costs associated with it. A website can also scale up to face
+    greater configuration complexity, and it can be increasingly difficult to
+    detect and keep track of suboptimally configured URL spaces on a given
+    server.</p>
+
+    <p>Eventually a point is reached where the principle "conservative in
+    what you send" needs to be enforced by the server administrator.</p>
+
+    <p>The <module>mod_policy</module> module provides a set of filters
+    which can be applied to a server, allowing key features of the HTTP
+    protocol to be explicitly tested, and non compliant responses logged as
+    warnings, or rejected outright as an error. Each filter can be applied
+    separately, allowing the administrator to pick and choose which policies
+    should be enforced depending on the circumstances of their environment.
+    </p>
+
+    <p>The filters might be placed in testing and staging environments for
+    the benefit of application and website developers, or may be applied
+    to production servers to protect infrastructure from systems outside
+    the administrator's direct control.</p>
+
+    <p class="figure">
+    <img src="images/compliance-reverse-proxy.png" width="666" height="239" alt=
+    "Enforcing HTTP protocol compliance for an application server"/>
+    </p>
+
+    <p>In the above example, an Apache httpd server has been placed between
+    the application server and the internet at large, and configured to cache
+    responses from the application server. The <module>mod_policy</module>
+    filters have been added to enforce support for cacheable content and
+    conditional requests, ensuring that both <module>mod_cache</module> and
+    public caches on the internet are fully able to cache content created
+    by the restful application server efficiently.</p>
+
+    <p class="figure">
+    <img src="images/compliance-static.png" width="469" height="239" alt=
+    "Enforcing HTTP protocol compliance in a static server"/>
+    </p>
+
+    <p>In the above simpler example, a static server serving highly cacheable
+    content has a set of policies applied to ensure that the server configuration
+    conforms to a minimum level of compliance.</p>
+
+  </section>
+
+  <section id="policyconditional">
+    <title>Conditional Request Policy</title>
+    <related>
+      <modulelist>
+        <module>mod_policy</module>
+      </modulelist>
+      <directivelist>
+        <directive module="mod_policy">PolicyConditional</directive>
+      </directivelist>
+    </related>
+
+    <p>This policy will be rejected if the server does not correctly respond
+    to a conditional request with the appropriate status code.</p>
+
+    <p>Conditional requests form the mechanism by which an HTTP cache makes
+    stale content fresh again, and particularly for content with short freshness
+    lifetimes, lack of support for conditional requests can add avoidable load
+    to the server.</p>
+
+    <p>Most specifically, the existence of any of following headers in the
+    request makes the request conditional:</p>
+
+    <dl>
+    <dt><code>If-Match</code></dt>
+    <dd>If the provided ETag in the <code>If-Match</code> header does not match
+    the ETag of the response, the server should return
+    <code>412 Precondition Failed</code>. Full details of how to handle an
+    <code>If-Match</code> header can be found in
+    <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.24">
+    RFC2616 section 14.24</a>.</dd>
+
+    <dt><code>If-None-Match</code></dt>
+    <dd>If the provided ETag in the <code>If-None-Match</code> header matches
+    the ETag of the response, the server should return either
+    <code>304 Not Modified</code> for GET/HEAD requests, or
+    <code>412 Precondition Failed</code> for other methods. Full details of how
+    to handle an <code>If-None-Match</code> header can be found in
+    <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.26">
+    RFC2616 section 14.26</a>.</dd>
+
+    <dt><code>If-Modified-Since</code></dt>
+    <dd>If the provided date in the <code>If-Modified-Since</code> header is
+    older than the <code>Last-Modified</code> header of the response, the server
+    should return <code>304 Not Modified</code>. Full details of how to handle an
+    <code>If-Modified-Since</code> header can be found in
+    <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.25">
+    RFC2616 section 14.25</a>.</dd>
+
+    <dt><code>If-Unmodified-Since</code></dt>
+    <dd>If the provided date in the <code>If-Modified-Since</code> header is
+    newer than the <code>Last-Modified</code> header of the response, the server
+    should return <code>412 Precondition Failed</code>. Full details of how to
+    handle an <code>If-Unmodified-Since</code> header can be found in
+    <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.28">
+    RFC2616 section 14.28</a>.</dd>
+
+    <dt><code>If-Range</code></dt>
+    <dd>If the provided ETag or date in the <code>If-Range</code> header matches
+    the ETag or Last-Modified of the response, and a valid <code>Range</code>
+    is present, the server should return
+    <code>206 Partial Response</code>. Full details of how to handle an
+    <code>If-Range</code> header can be found in
+    <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.27">
+    RFC2616 section 14.27</a>.</dd>
+
+    </dl>
+
+    <p>If the response is detected to have been successful (a 2xx response),
+    but was conditional and one of the responses above was expected instead,
+    this policy will be rejected. Responses that indicate a redirect or a
+    failure of some kind (3xx, 4xx, 5xx) will be ignored by this policy.</p>
+
+    <p>This policy is implemented by the <strong>POLICY_CONDITIONAL</strong>
+    filter.</p>
+
+  </section>
+
+  <section id="policylength">
+    <title>Content-Length Policy</title>
+    <related>
+      <modulelist>
+        <module>mod_policy</module>
+      </modulelist>
+      <directivelist>
+        <directive module="mod_policy">PolicyLength</directive>
+      </directivelist>
+    </related>
+
+    <p>This policy will be rejected if the server response does not contain
+    an explicit <code>Content-Length</code> header.</p>
+    
+    <p>There are a number of ways of determining the length of a response
+    body, described in full in
+    <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec4.4">
+    RFC2616 section 4.4 Message Length</a>.</p>
+    
+    <p>When the <code>Content-Length</code> header is present, the size of
+    the body is declared at the start of the response. If this information
+    is missing, an HTTP cache might choose to ignore the response, as it
+    does not know in advance whether the response will fit within the
+    cache's defined limits.</p>
+
+    <p>HTTP/1.1 defines the <code>Transfer-Encoding</code> header as an
+    alternative to <code>Content-Length</code>, allowing the end of the
+    response to be indicated to the client without the client having to
+    know the length beforehand. However, when HTTP/1.0 requests are
+    processed, and no <code>Content-Length</code> is specified, the only
+    mechanism available to the server to indicate the end of the request
+    is to drop the connection. In an environment containing load
+    balancers, this can cause the keepalive mechanism to be bypassed.
+    </p>
+
+    <p>If the response is detected to have been successful (a 2xx response),
+    and has a response body (this excludes <code>204 No Content</code>), and
+    the <code>Content-Length</code> header is missing, this policy will be
+    rejected. Responses that indicate a redirect or a failure of some kind
+    (3xx, 4xx, 5xx) will be ignored by this policy.</p>
+
+    <note type="warning">It should be noted that some modules, such as
+    <module>mod_proxy</module>, add their own <code>Content-Length</code>
+    header should the response be small enough for it to have been possible
+    to read the response lacking such a header in one go. This may cause
+    small responses to pass this policy, while larger responses may
+    fail for the same URL.</note>
+
+    <p>This policy is implemented by the <strong>POLICY_LENGTH</strong>
+    filter.</p>
+
+  </section>
+
+  <section id="policytype">
+    <title>Content-Type Policy</title>
+    <related>
+      <modulelist>
+        <module>mod_policy</module>
+      </modulelist>
+      <directivelist>
+        <directive module="mod_policy">PolicyType</directive>
+      </directivelist>
+    </related>
+
+    <p>This policy will be rejected if the server response does not contain
+    an explicit and syntactically correct <code>Content-Type</code> header
+    that matches the server defined pattern.</p>
+
+    <p>The media type of the body is placed in the <code>Content-Type</code>
+    header, and the format of the header is described in full in
+    <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec3.7">
+    RFC2616 section 3.7 Media Types</a>.</p>
+    
+    <p>A syntactically valid content type might look as follows:</p>
+    
+    <example>
+      Content-Type: text/html; charset=iso-8859-1
+    </example>
+
+    <p>Invalid content types might include:</p>
+
+    <example>
+      # invalid<br />
+      Content-Type: foo<br />
+      # blank<br />
+      Content-Type: 
+    </example>
+
+    <p>The server administrator has the option to restrict the policy to one
+    or more specific types, or could specify a general wildcard type such as
+    <code>*/*</code>.</p>
+
+    <p>This policy is implemented by the <strong>POLICY_TYPE</strong>
+    filter.</p>
+
+  </section>
+
+  <section id="policykeepalive">
+    <title>Keepalive Policy</title>
+    <related>
+      <modulelist>
+        <module>mod_policy</module>
+      </modulelist>
+      <directivelist>
+        <directive module="mod_policy">PolicyKeepalive</directive>
+      </directivelist>
+    </related>
+
+    <p>This policy will be rejected if the server response does not contain
+    an explicit <code>Content-Length</code> header, or a
+    <code>Transfer-Encoding</code> of chunked.</p>
+    
+    <p>There are a number of ways of determining the length of a response
+    body, described in full in
+    <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec4.4">
+    RFC2616 section 4.4 Message Length</a>.</p>
+    
+    <p>When the <code>Content-Length</code> header is present, the size of
+    the body is declared at the start of the response. HTTP/1.1 defines the
+    <code>Transfer-Encoding</code> header as an alternative to
+    <code>Content-Length</code>, allowing the end of the response to be
+    indicated to the client without the client having to know the length
+    beforehand. In the absence of these two mechanisms, the only way for
+    a server to indicate the end of the request is to drop the connection.
+    In an environment containing load balancers, this can cause the keepalive
+    mechanism to be bypassed.
+    </p>
+
+    <p>Most specifically, we follow these rules:</p>
+    
+    <dl>
+    <dt>IF</dt>
+    <dd>we have not marked this connection as errored;</dd>
+    
+    <dt>and</dt>
+    <dd>the client isn't expecting 100-continue</dd>
+    
+    <dt>and</dt>
+    <dd>the response status does not require a close;</dd>
+    
+    <dt>and</dt>
+    <dd>the response body has a defined length due to the status code
+    being 304 or 204, the request method being HEAD, already having defined
+    Content-Length or Transfer-Encoding: chunked, or the request version
+    being HTTP/1.1 and thus capable of being set as chunked</dd>
+    
+    <dt>THEN</dt>
+    <dd>we support keepalive.</dd>
+    </dl>
+   
+    <note type="warning">The server may choose to turn off keepalive for
+    various reasons, such as an imminent shutdown, or a Connection: close from
+    the client, or an HTTP/1.0 client request with a response with no
+    <code>Content-Length</code>, but for our purposes we only care that
+    keepalive was possible from the application, not that keepalive actually
+    took place.</note> 
+
+    <p>It should also be noted that the Apache httpd server includes a filter
+    that adds chunked encoding to responses without an explicit content
+    length. This policy catches those cases where this filter is bypassed or
+    not in effect.</p>
+
+    <p>This policy is implemented by the <strong>POLICY_KEEPALIVE</strong>
+    filter.</p>
+    
+  </section>
+
+  <section id="policymaxage">
+    <title>Freshness Lifetime / Maxage Policy</title>
+    <related>
+      <modulelist>
+        <module>mod_policy</module>
+      </modulelist>
+      <directivelist>
+        <directive module="mod_policy">PolicyMaxage</directive>
+      </directivelist>
+    </related>
+
+    <p>This policy will be rejected if the server response does not have
+    an explicit <strong>freshness lifetime</strong> at least as long
+    as the server defined limit, or if the freshness lifetime is
+    calculated based on a heuristic.</p>
+
+    <p>Full details of how a freshness lifetime is calculated is described in
+    full in
+    <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec13.2">
+    RFC2616 section 13.2 Expiration Model</a>.</p>
+
+    <p>During the freshness lifetime, a cache does not need to contact the
+    origin server at all, it can simply pass the cached content as is back
+    to the client.</p>
+
+    <p>When the freshness lifetime is reached, the cache should contact the
+    origin server in an effort to check whether the content is still fresh,
+    and if not, replace the content.</p>
+
+    <p>When the freshness lifetime is too short, it can result in excessive
+    load on the server. In addition, should an outage occur that is as long
+    or longer than the freshness lifetime, all cached content will become
+    stale, which could cause a thundering herd of traffic when the
+    server or network returns.</p>
+
+    <p>This policy is implemented by the <strong>POLICY_MAXAGE</strong>
+    filter.</p>
+
+  </section>
+  
+  <section id="policynocache">
+    <title>No Cache Policy</title>
+    <related>
+      <modulelist>
+        <module>mod_policy</module>
+      </modulelist>
+      <directivelist>
+        <directive module="mod_policy">PolicyNocache</directive>
+      </directivelist>
+    </related>
+
+    <p>This policy will be rejected if the server response declares itself
+    uncacheable using either the <code>Cache-Control</code> or
+    <code>Pragma</code> headers.</p>
+
+    <p>Full details of how content may be declared uncacheable is described in
+    full in
+    <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1">
+    RFC2616 section 14.9.1 What is Cacheable</a>, and within the definition
+    for the <code>Pragma</code> header in
+    <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.32">
+    RFC2616 section 14.32 Pragma</a>.</p>
+
+    <p>Most specifically, should any of the following header combinations
+    exist in the response headers, the response will be rejected:</p>
+
+    <ul>
+    <li><code>Cache-Control: no-cache</code></li>
+    <li><code>Cache-Control: no-store</code></li>
+    <li><code>Cache-Control: private</code></li>
+    <li><code>Pragma: no-cache</code></li>
+    </ul>
+
+    <p>When unexpected, uncacheable content may produce unacceptable levels
+    of server load, or may incur significant cost. When this policy is enabled,
+    all server defined uncacheable content will be rejected.</p>
+
+    <p>This policy is implemented by the <strong>POLICY_NOCACHE</strong>
+    filter.</p>
+
+  </section>
+  
+  <section id="policyvalidation">
+    <title>Validation Policy</title>
+    <related>
+      <modulelist>
+        <module>mod_policy</module>
+      </modulelist>
+      <directivelist>
+        <directive module="mod_policy">PolicyValidation</directive>
+      </directivelist>
+    </related>
+
+    <p>This policy will be rejected if the server response does not contain
+    either a syntactically correct <code>ETag</code> or
+    <code>Last-Modified</code> header.</p>
+
+    <p>The <code>ETag</code> header is described in full in
+    <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.19">
+    RFC2616 section 14.19 Etag</a>, and the <code>Last-Modified</code> header
+    is described in full in
+    <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.29">
+    RFC2616 section 14.29 Last-Modified</a>.</p>
+
+    <p>In addition to being checked present, the headers are checked for
+    syntax.</p>
+
+    <p>An <code>ETag</code> that is not surrounded with quotes, or is not
+    declared "weak" by prefixing it with a "W/" will cause the policy to be
+    rejected. A <code>Last-Modified</code> that is not parsed as a valid date
+    will cause the policy to be rejected.</p>
+
+    <p>This policy is implemented by the <strong>POLICY_VALIDATION</strong>
+    filter.</p>
+
+  </section>
+  
+  <section id="policyvary">
+    <title>Vary Header Policy</title>
+    <related>
+      <modulelist>
+        <module>mod_policy</module>
+      </modulelist>
+      <directivelist>
+        <directive module="mod_policy">PolicyVary</directive>
+      </directivelist>
+    </related>
+    
+    <p>This policy will be rejected if the server response contains a
+    <code>Vary</code> header, and that header in turn contains a header
+    blacklisted by the administrator.</p>
+
+    <p>The <code>Vary</code> header is described in full in
+    <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.44">
+    RFC2616 section 14.44 Vary</a>.</p>
+    
+    <p>Some client provided headers, such as <code>User-Agent</code>,
+    can contain thousands or millions of combinations of values over a period
+    of time, and if the response is declared cacheable, a cache might attempt
+    to cache each of these responses separately, filling up the cache and
+    crowding out other entries in the cache. In this scenario, if so
+    configured, the policy will reject the response.</p>
+
+    <p>This policy is implemented by the <strong>POLICY_VARY</strong>
+    filter.</p>
+
+  </section>
+  
+  <section id="policyversion">
+    <title>Protocol Version Policy</title>
+    <related>
+      <modulelist>
+        <module>mod_policy</module>
+      </modulelist>
+      <directivelist>
+        <directive module="mod_policy">PolicyVersion</directive>
+      </directivelist>
+    </related>
+
+    <p>This policy will be rejected if the client request was made with a
+    version number lower than the version of HTTP specified.</p>
+
+    <p>This policy is typically used with restful applications where
+    control over the type of client is desired. This policy can be used
+    alongside the <code>POLICY_KEEPALIVE</code> filter to ensure that
+    HTTP/1.0 clients don't cause keepalive connections to be dropped.</p>
+
+    <p>Possible minimum versions that could be specified are:</p>
+
+    <ul><li><code>HTTP/1.1</code></li>
+    <li><code>HTTP/1.0</code></li>
+    <li><code>HTTP/0.9</code></li>
+    </ul>
+
+    <p>This policy is implemented by the <strong>POLICY_VERSON</strong>
+    filter.</p>
+
+  </section>
+</manualpage>
index d59b776d3cd5fff08f0d86a71060aba33358bb26..1b97cc5adfba91102ba416202e3ab00a32a4da45 100644 (file)
@@ -47,6 +47,7 @@
         <module>mod_substitute</module>
         <module>mod_xml2enc</module>
         <module>mod_proxy_html</module>
+        <module>mod_policy</module>
       </modulelist>
       <directivelist>
         <directive module="mod_filter">FilterChain</directive>
index 2859e97d093cbb91fdce0afbaa70ef7b4a7e4f5b..743355ce57f6667ecb185e1da9afabd2fe75c3c6 100644 (file)
@@ -58,6 +58,7 @@ Documentation</title>
     <page href="dso.html">Dynamic Shared Objects (DSO)</page>
     <page href="env.html">Environment Variables</page>
     <page href="logs.html">Log Files</page>
+    <page href="compliance.html">HTTP Protocol Compliance</page>
     <page href="urlmapping.html">Mapping URLs to the Filesystem</page>
     <page href="misc/perf-tuning.html">Performance Tuning</page>
     <page href="misc/security_tips.html">Security Tips</page>
index a26ed7b80e700ab6e7591b5a8eb26ca024585982..ce0b4bbe2a235a39736f4fa4888da0b7401c8ec3 100644 (file)
@@ -72,6 +72,7 @@
   <modulefile>mod_mime_magic.xml</modulefile>
   <modulefile>mod_negotiation.xml</modulefile>
   <modulefile>mod_nw_ssl.xml</modulefile>
+  <modulefile>mod_policy.xml</modulefile>
   <modulefile>mod_privileges.xml</modulefile>
   <modulefile>mod_proxy.xml</modulefile>
   <modulefile>mod_proxy_ajp.xml</modulefile>
diff --git a/docs/manual/mod/mod_policy.xml b/docs/manual/mod/mod_policy.xml
new file mode 100644 (file)
index 0000000..af2a7f7
--- /dev/null
@@ -0,0 +1,688 @@
+<?xml version="1.0"?>
+<!DOCTYPE modulesynopsis SYSTEM "../style/modulesynopsis.dtd">
+<?xml-stylesheet type="text/xsl" href="../style/manual.en.xsl"?>
+<!-- $LastChangedRevision: 1174747 $ -->
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<modulesynopsis metafile="mod_policy.xml.meta">
+
+<name>mod_policy</name>
+<description>HTTP protocol compliance enforcement.</description>
+<status>Extension</status>
+<sourcefile>mod_policy.c</sourcefile>
+<identifier>policy_module</identifier>
+
+<summary>
+    <p>The HTTP protocol recommends that clients should be "liberal in
+    what they accept", and servers "strict with what they send". In some
+    cases it can be difficult to detect when a server or an application
+    has been misconfigured, is serving uncacheable content or is behaving
+    suboptimally, as an HTTP client might be compensating for the server.
+    These problems can potentially lead to excessive bandwidth
+    consumption, or a server outage under load.</p>
+
+    <p>The <module>mod_policy</module> module consists of a set of
+    filters that test servers for HTTP protocol compliance. These
+    tests allow the server administrator to log violations of, or
+    outright reject responses where certain defined conditions exist.</p>
+
+    <p>This could be used as a way to set minimum HTTP protocol compliance
+    criteria for a restful application. Alternatively, a reverse proxy or
+    cache could be configured to protect itself from misconfigured origin
+    servers or unexpectedly uncacheable content, or as a mechanism to
+    detect configuration mistakes within the server itself.</p>
+
+</summary>
+<seealso><a href="../filter.html">Filters</a></seealso>
+
+<section id="actions">
+    <title>Actions</title>
+
+    <p>If a policy is violated, one of the following actions can be
+    taken:</p>
+
+    <dl>
+    <dt><strong>ignore</strong></dt>
+    <dd>The policy check will be ignored for the given URL space, even
+    if the filter is present.</dd>
+
+    <dt><strong>log</strong></dt>
+    <dd>The policy check will be executed, and if a violation is detected
+    a warning will be logged to the server error_log, and a
+    <code>Warning</code> header added to the response for the benefit of
+    the client.</dd>
+
+    <dt><strong>enforce</strong></dt>
+    <dd>The policy check will be executed, and if a violation is detected
+    an error will be logged to the server error_log, a
+    <code>Warning</code> header added to the response, and a <code>502
+    Bad Gateway</code> will be returned to the client. Optional links to
+    explanatory documentation can be added to each error message,
+    detailing the origin of each policy.</dd>
+
+    </dl>
+
+    <p>It is also possible to selectively disable all policies for a
+    given URL space, should the need arise, using the
+    <directive module="mod_policy">PolicyFilter</directive> directive.</p>
+
+    <p>Alternatively, the
+    <directive module="mod_policy">PolicyEnvironment</directive>
+    directive can be used to specify an environment variable, which if
+    present, will cause the policies to be selectively downgraded or
+    bypassed.</p>
+
+</section>
+
+<section id="tests">
+    <title>Policy Tests</title>
+
+    <p>The following policy filters are available:</p>
+
+    <dl>
+    <dt><strong><a href="../compliance.html#policytype">POLICY_TYPE</a>
+    </strong>: Enforce valid content types</dt>
+    <dd>Content types that are syntactically invalid or blank can be detected
+       and the request rejected. Types can be restricted to a specific list
+       containing optional wildcards ? and *.</dd>
+    
+    <dt><strong><a href="../compliance.html#policylength">POLICY_LENGTH</a>
+    </strong>: Enforce the presence of a Content-Length</dt>
+    <dd>The length of responses can be specified in one of three ways, by
+    specifying an explicit length in advance, using chunked encoding to set
+    the length, or by setting no length at all and terminating the request
+    when complete. The absence of a specific content length can affect the
+    cacheability of the response, and prevents the use of keepalive during
+    HTTP/1.0 requests. This policy enforces the presence of an explicit
+    content length on the response.</dd>
+
+    <dt><strong><a href="../compliance.html#policykeepalive">POLICY_KEEPALIVE
+    </a></strong>: Enforce the option to keepalive</dt>
+    <dd>Less restrictive than the POLICY_LENGTH test, this policy enforces the
+    possibility that the response can be kept alive. If the response doesn't
+    have a protocol defined zero length, and the response isn't already an
+    error, and the response has neither a Content-Length or is declared
+    HTTP/1.1 and lacks Content-Encoding: chunked, then this response will be
+    rejected.</dd>
+
+    <dt><strong><a href="../compliance.html#policyvary">POLICY_VARY</a>
+    </strong>: Enforce the absence of certain headers within Vary headers</dt>
+    <dd>If the Vary header contains any of the headers specified, this policy
+    will reject the request. The typical case is the presence of the User-Agent
+    within Vary, which is likely to cause a denial of service condition to a
+    cache.</dd>
+
+    <dt><strong><a href="../compliance.html#policyvalidation">
+    POLICY_VALIDATION</a></strong>: Enforce the presence of Etag and/or
+    Last-Modified</dt>
+    <dd>The ability for a cache to determine whether a cached entity can be
+    refreshed is dependent on whether a valid Etag and/or Last-Modified header
+    is present to revalidate against. The absence of both headers, or the
+    invalid syntax of a header will cause this policy to be rejected.</dd>
+
+    <dt><strong><a href="../compliance.html#policyconditional">
+    POLICY_CONDITIONAL</a></strong>: Enforce correct operation of conditional
+    requests</dt>
+    <dd>When conditional headers are present in the request, a server should
+    respond with a <code>304 Not Modified</code> or <code>412 Precondition
+    Failed</code> response where appropriate. A server may ignore conditional
+    headers, and this affects the efficiency of the HTTP caching mechanism.
+    This policy rejects requests where a conditional header is present, and
+    a 304 or 412 response code was expected, but a 2xx response was seen
+    instead.</dd>
+
+    <dt><strong><a href="../compliance.html#policynocache">POLICY_NOCACHE</a>
+    </strong>: Enforce cacheable responses</dt>
+    <dd>When a response is encountered that declares itself explicitly
+    uncacheable, the request is rejected. A response is considered
+    uncacheable if it specifies any of the following:
+    <ul><li><code>Cache-Control: no-cache</code></li>
+    <li><code>Pragma: no-cache</code></li>
+    <li><code>Cache-Control: no-store</code></li>
+    <li><code>Cache-Control: private</code></li>
+    </ul></dd>
+
+    <dt><strong><a href="../compliance.html#policymaxage">POLICY_MAXAGE</a>
+    </strong>: Enforce a minimum maxage</dt>
+    <dd>When a response is encountered where the freshness lifetime is less
+    than the given value, or the freshness lifetime is heuristic, the request
+    is rejected. A response is checked in the following order:
+    <ul><li>If <code>s-maxage</code> is present but too small; or</li>
+    <li>If <code>max-age</code> is present but too small; or</li>
+    <li>If <code>Expires</code> is present and invalid; or</li>
+    <li><code>Date</code> is present and invalid; or</li>
+    <li><code>Expires</code> minus Date is too small; or</li>
+    <li>No <code>s-maxage</code>, <code>maxage</code>, or
+    <code>Expires</code>/<code>Date</code> declared at all</li>
+    </ul></dd>
+
+    <dt><strong><a href="../compliance.html#policyversion">POLICY_VERSION</a>
+    </strong>: Enforce a minimum HTTP version within a request</dt>
+    <dd>When a request is encountered with an HTTP version number less than
+    the required minimum version, the request is rejected. The following
+    version numbers are recognised:
+    <ul><li><code>HTTP/1.1</code></li>
+    <li><code>HTTP/1.0</code></li>
+    <li><code>HTTP/0.9</code></li>
+    </ul></dd>
+
+    </dl>
+
+</section>
+
+<section id="example">
+    <title>Example Configuration</title>
+
+    <p>A typical configuration protecting a server serving static content
+    might be as follows:</p>
+
+    <example>
+    &lt;Location /&gt;<br />
+    <indent>
+      SetOutputFilter POLICY_TYPE;POLICY_LENGTH;POLICY_KEEPALIVE;POLICY_VARY;POLICY_VALIDATION; \<br />
+      <indent>
+        POLICY_CONDITIONAL;POLICY_NOCACHE;POLICY_MAXAGE;POLICY_VERSION<br />
+      </indent>
+      <br />
+      # content type must be present and valid, but can be anything<br />
+      PolicyType enforce */*<br />
+      <br />
+      # reject if no explicitly declared content length<br />
+      PolicyLength enforce<br />
+      <br />
+      # covered by the policy length filter<br />
+      PolicyKeepalive ignore<br />
+      <br />
+      # reject if User-Agent appears within Vary headers<br />
+      PolicyVary enforce User-Agent<br />
+      <br />
+      # we want to enforce validation<br />
+      PolicyValidation enforce<br />
+      <br />
+      # non-functional conditional responses should be rejected<br />
+      PolicyConditional enforce<br />
+      <br />
+      # no-cache responses should be rejected<br />
+      PolicyNocache enforce<br />
+      <br />
+      # maxage must be at least a day<br />
+      PolicyMaxage enforce 86400<br />
+      <br />
+      # request version can be anything<br />
+      PolicyVersion ignore HTTP/1.1<br />
+    </indent>
+    &lt;/Location&gt;<br />
+    <br />
+    # suppress policy protection for server-status<br />
+    &lt;Location /server-status&gt;<br />
+    <indent>
+      PolicyFilter off<br />
+    </indent>
+    &lt;/Location&gt;<br />
+    </example>
+
+</section>
+
+<directivesynopsis>
+
+<name>PolicyFilter</name>
+<description>Enable or disable policies for the given URL space.</description>
+<syntax>PolicyFilter <var>on|off</var></syntax>
+<default>on</default>
+<contextlist><context>server config</context><context>virtual host</context>
+<context>directory</context></contextlist>
+<compatibility>PolicyFilter is only available in Apache 2.5.0 and
+later.</compatibility>
+
+<usage>
+    <p>Master switch to enable or disable policies for a given URL space.</p>
+
+    <example><title>Example</title>
+    # enabled by default<br />
+    &lt;Location /&gt;<br />
+    <indent>
+      PolicyFilter on<br />
+    </indent>
+    &lt;/Location&gt;<br />
+    <br />
+    # suppress policy protection for server-status<br />
+    &lt;Location /server-status&gt;<br />
+    <indent>
+      PolicyFilter off<br />
+    </indent>
+    &lt;/Location&gt;<br />
+    </example>
+</usage>
+
+</directivesynopsis>
+
+<directivesynopsis>
+
+<name>PolicyEnvironment</name>
+<description>Override policies based on an environment variable.</description>
+<syntax>PolicyEnvironment <var>variable</var> <var>log-value</var> <var>ignore-value</var></syntax>
+<default>none</default>
+<contextlist><context>server config</context><context>virtual host</context>
+<context>directory</context></contextlist>
+<compatibility>PolicyEnvironment is only available in Apache 2.5.0 and
+later.</compatibility>
+
+<usage>
+    <p>Downgrade policies to logging only or ignored based on the presence
+    of an environment variable. If the given variable is present and equal
+    to the log-value, enforced policies will be logged instead. If the given
+    variable is present and equal to the ignore-value, all policies will
+    be ignored.</p>
+
+    <example><title>Example</title>
+    # downgrade if POLICY_CONTROL was present<br />
+    PolicyEnvironment POLICY_CONTROL log ignore<br />
+    </example>
+</usage>
+
+</directivesynopsis>
+
+<directivesynopsis>
+
+<name>PolicyConditional</name>
+<description>Enable the conditional request policy.</description>
+<syntax>PolicyConditional <var>ignore|log|enforce</var></syntax>
+<default>ignore</default>
+<contextlist><context>server config</context><context>virtual host</context>
+<context>directory</context></contextlist>
+<compatibility>PolicyConditional is only available in Apache 2.5.0 and
+later.</compatibility>
+
+<usage>
+    <p>When logged or enforced, a response that should have been conditional
+    but wasn't will be rejected.</p>
+
+    <example><title>Example</title>
+    # non-functional conditional responses should be rejected<br />
+    PolicyConditional enforce<br />
+    </example>
+</usage>
+
+</directivesynopsis>
+
+<directivesynopsis>
+
+<name>PolicyConditionalURL</name>
+<description>URL describing the conditional request policy.</description>
+<syntax>PolicyConditionalURL <var>url</var></syntax>
+<default>none</default>
+<contextlist><context>server config</context><context>virtual host</context>
+<context>directory</context></contextlist>
+<compatibility>PolicyConditionalURL is only available in Apache 2.5.0 and
+later.</compatibility>
+
+<usage>
+    <p>Specify the URL of the documentation describing the conditional
+    request policy, to appear within error messages.</p>
+</usage>
+
+</directivesynopsis>
+
+<directivesynopsis>
+
+<name>PolicyLength</name>
+<description>Enable the content length policy.</description>
+<syntax>PolicyLength <var>ignore|log|enforce</var></syntax>
+<default>ignore</default>
+<contextlist><context>server config</context><context>virtual host</context>
+<context>directory</context></contextlist>
+<compatibility>PolicyLength is only available in Apache 2.5.0 and
+later.</compatibility>
+
+<usage>
+    <p>When logged or enforced, a response that lacks an explicit
+    <code>Content-Length</code> header will be rejected.</p>
+
+    <example><title>Example</title>
+    # missing Content-Length header should be rejected<br />
+    PolicyLength enforce<br />
+    </example>
+</usage>
+
+</directivesynopsis>
+
+<directivesynopsis>
+
+<name>PolicyLengthURL</name>
+<description>URL describing the content length policy.</description>
+<syntax>PolicyLengthURL <var>url</var></syntax>
+<default>none</default>
+<contextlist><context>server config</context><context>virtual host</context>
+<context>directory</context></contextlist>
+<compatibility>PolicyLengthURL is only available in Apache 2.5.0 and
+later.</compatibility>
+
+<usage>
+    <p>Specify the URL of the documentation describing the content length
+    policy, to appear within error messages.</p>
+</usage>
+
+</directivesynopsis>
+
+<directivesynopsis>
+
+<name>PolicyKeepalive</name>
+<description>Enable the keepalive policy.</description>
+<syntax>PolicyKeepalive <var>ignore|log|enforce</var></syntax>
+<default>ignore</default>
+<contextlist><context>server config</context><context>virtual host</context>
+<context>directory</context></contextlist>
+<compatibility>PolicyKeepalive is only available in Apache 2.5.0 and
+later.</compatibility>
+
+<usage>
+    <p>When logged or enforced, a response that lacks both an explicit
+    <code>Content-Length</code> header and a <code>Transfer-Encoding</code>
+    of <code>chunked</code> will be rejected.</p>
+
+    <example><title>Example</title>
+    # missing Content-Length or Transfer-Encoding should be rejected<br />
+    PolicyKeepalive enforce<br />
+    </example>
+</usage>
+
+</directivesynopsis>
+
+<directivesynopsis>
+
+<name>PolicyKeepaliveURL</name>
+<description>URL describing the keepalive policy.</description>
+<syntax>PolicyKeepaliveURL <var>url</var></syntax>
+<default>none</default>
+<contextlist><context>server config</context><context>virtual host</context>
+<context>directory</context></contextlist>
+<compatibility>PolicyKeepaliveURL is only available in Apache 2.5.0 and
+later.</compatibility>
+
+<usage>
+    <p>Specify the URL of the documentation describing the keepalive
+    policy, to appear within error messages.</p>
+</usage>
+
+</directivesynopsis>
+
+<directivesynopsis>
+
+<name>PolicyType</name>
+<description>Enable the content type policy.</description>
+<syntax>PolicyType <var>ignore|log|enforce</var> <var>type</var> [ <var>type</var> [ ... ]]</syntax>
+<default>ignore</default>
+<contextlist><context>server config</context><context>virtual host</context>
+<context>directory</context></contextlist>
+<compatibility>PolicyType is only available in Apache 2.5.0 and
+later.</compatibility>
+
+<usage>
+    <p>When logged or enforced, a response that lacks a <code>Content-Type</code>
+    header, where the <code>Content-Type</code> header is malformed, or where the
+    header does not match the given pattern or patterns will be rejected.</p>
+
+    <example><title>Example</title>
+    # enforce json or XML<br />
+    PolicyType enforce application/json text/xml<br />
+    </example>
+
+    <example><title>Example</title>
+    # malformed content type should be rejected<br />
+    PolicyType enforce */*<br />
+    </example>
+
+</usage>
+
+</directivesynopsis>
+
+<directivesynopsis>
+
+<name>PolicyTypeURL</name>
+<description>URL describing the content type policy.</description>
+<syntax>PolicyTypeURL <var>url</var></syntax>
+<default>none</default>
+<contextlist><context>server config</context><context>virtual host</context>
+<context>directory</context></contextlist>
+<compatibility>PolicyTypeURL is only available in Apache 2.5.0 and
+later.</compatibility>
+
+<usage>
+    <p>Specify the URL of the documentation describing the content type
+    policy, to appear within error messages.</p>
+</usage>
+
+</directivesynopsis>
+
+<directivesynopsis>
+
+<name>PolicyVary</name>
+<description>Enable the Vary policy.</description>
+<syntax>PolicyVary <var>ignore|log|enforce</var> <var>header</var> [ <var>header</var> [ ... ]]</syntax>
+<default>ignore</default>
+<contextlist><context>server config</context><context>virtual host</context>
+<context>directory</context></contextlist>
+<compatibility>PolicyVary is only available in Apache 2.5.0 and
+later.</compatibility>
+
+<usage>
+    <p>When logged or enforced, a response that contains a <code>Vary</code>
+    header which in turn contains one of the headers listed, will be
+    rejected.</p>
+
+    <example><title>Example</title>
+    # reject reponses with "User-Agent" listed in the Vary header<br />
+    PolicyVary enforce User-Agent<br />
+    </example>
+
+</usage>
+
+</directivesynopsis>
+
+<directivesynopsis>
+
+<name>PolicyVaryURL</name>
+<description>URL describing the content type policy.</description>
+<syntax>PolicyVaryURL <var>url</var></syntax>
+<default>none</default>
+<contextlist><context>server config</context><context>virtual host</context>
+<context>directory</context></contextlist>
+<compatibility>PolicyVaryURL is only available in Apache 2.5.0 and
+later.</compatibility>
+
+<usage>
+    <p>Specify the URL of the documentation describing the vary policy, to
+    appear within error messages.</p>
+</usage>
+
+</directivesynopsis>
+
+<directivesynopsis>
+
+<name>PolicyValidation</name>
+<description>Enable the validation policy.</description>
+<syntax>PolicyValidation <var>ignore|log|enforce</var></syntax>
+<default>ignore</default>
+<contextlist><context>server config</context><context>virtual host</context>
+<context>directory</context></contextlist>
+<compatibility>PolicyValidation is only available in Apache 2.5.0 and
+later.</compatibility>
+
+<usage>
+    <p>When logged or enforced, a response that lacks either a valid
+    <code>ETag</code> header or a <code>Last-Modified</code> header, or where
+    either header is syntactically incorrect, will be rejected.</p>
+
+    <example><title>Example</title>
+    # no ETag or Last-Modified will be rejected<br />
+    PolicyValidation enforce<br />
+    </example>
+
+</usage>
+
+</directivesynopsis>
+
+<directivesynopsis>
+
+<name>PolicyValidationURL</name>
+<description>URL describing the content type policy.</description>
+<syntax>PolicyValidationURL <var>url</var></syntax>
+<default>none</default>
+<contextlist><context>server config</context><context>virtual host</context>
+<context>directory</context></contextlist>
+<compatibility>PolicyValidationURL is only available in Apache 2.5.0 and
+later.</compatibility>
+
+<usage>
+    <p>Specify the URL of the documentation describing the validation policy, to
+    appear within error messages.</p>
+</usage>
+
+</directivesynopsis>
+
+<directivesynopsis>
+
+<name>PolicyNocache</name>
+<description>Enable the caching no-cache policy.</description>
+<syntax>PolicyNocache <var>ignore|log|enforce</var></syntax>
+<default>ignore</default>
+<contextlist><context>server config</context><context>virtual host</context>
+<context>directory</context></contextlist>
+<compatibility>PolicyNocache is only available in Apache 2.5.0 and
+later.</compatibility>
+
+<usage>
+    <p>When logged or enforced, a response that defines itself uncacheable
+    using the <code>Cache-Control</code> or <code>Pragma</code> headers will
+    be rejected.</p>
+
+    <example><title>Example</title>
+    # Cache-Control: no-cache will be rejected<br />
+    PolicyNocache enforce<br />
+    </example>
+
+</usage>
+
+</directivesynopsis>
+
+<directivesynopsis>
+
+<name>PolicyNocacheURL</name>
+<description>URL describing the caching no-cache policy.</description>
+<syntax>PolicyNocacheURL <var>url</var></syntax>
+<default>none</default>
+<contextlist><context>server config</context><context>virtual host</context>
+<context>directory</context></contextlist>
+<compatibility>PolicyNocacheURL is only available in Apache 2.5.0 and
+later.</compatibility>
+
+<usage>
+    <p>Specify the URL of the documentation describing the caching no-cache
+    policy, to appear within error messages.</p>
+</usage>
+
+</directivesynopsis>
+
+<directivesynopsis>
+
+<name>PolicyMaxage</name>
+<description>Enable the caching minimum max-age policy.</description>
+<syntax>PolicyMaxage <var>ignore|log|enforce</var> <var>age</var></syntax>
+<default>ignore</default>
+<contextlist><context>server config</context><context>virtual host</context>
+<context>directory</context></contextlist>
+<compatibility>PolicyMaxage is only available in Apache 2.5.0 and
+later.</compatibility>
+
+<usage>
+    <p>When logged or enforced, a response that lacks an explicit freshness
+    lifetime defined with <code>max-age</code>, <code>s-maxage</code> or an
+    <code>Expires</code> header, or where the explicit freshness lifetime is
+    smaller than the given value, will be rejected.</p>
+
+    <example><title>Example</title>
+    # reject responses with a freshness lifetime shorter than a day<br />
+    PolicyMaxage enforce 86400<br />
+    </example>
+
+</usage>
+
+</directivesynopsis>
+
+<directivesynopsis>
+
+<name>PolicyMaxageURL</name>
+<description>URL describing the caching minimum freshness lifetime policy.</description>
+<syntax>PolicyMaxageURL <var>url</var></syntax>
+<default>none</default>
+<contextlist><context>server config</context><context>virtual host</context>
+<context>directory</context></contextlist>
+<compatibility>PolicyMaxageURL is only available in Apache 2.5.0 and
+later.</compatibility>
+
+<usage>
+    <p>Specify the URL of the documentation describing the caching minimum
+    freshness lifetime policy, to appear within error messages.</p>
+</usage>
+
+</directivesynopsis>
+
+<directivesynopsis>
+
+<name>PolicyVersion</name>
+<description>Enable the version policy.</description>
+<syntax>PolicyVersion <var>ignore|log|enforce</var> <var>HTTP/0.9|HTTP/1.0|HTTP/1.1</var></syntax>
+<default>ignore</default>
+<contextlist><context>server config</context><context>virtual host</context>
+<context>directory</context></contextlist>
+<compatibility>PolicyVersion is only available in Apache 2.5.0 and
+later.</compatibility>
+
+<usage>
+    <p>When logged or enforced, a request with a version lower than specified
+    will be rejected.</p>
+
+    <example><title>Example</title>
+    # reject requests with an HTTP version older than HTTP/1.1<br />
+    PolicyVersion enforce HTTP/1.1<br />
+    </example>
+
+</usage>
+
+</directivesynopsis>
+
+<directivesynopsis>
+
+<name>PolicyVersionURL</name>
+<description>URL describing the minimum request HTTP version policy.</description>
+<syntax>PolicyVersionURL <var>url</var></syntax>
+<default>none</default>
+<contextlist><context>server config</context><context>virtual host</context>
+<context>directory</context></contextlist>
+<compatibility>PolicyVersionURL is only available in Apache 2.5.0 and
+later.</compatibility>
+
+<usage>
+    <p>Specify the URL of the documentation describing the minimum request
+    HTTP version policy, to appear within error messages.</p>
+</usage>
+
+</directivesynopsis>
+
+</modulesynopsis>