bottleneck testcase based on rubbos
[bottlenecks.git] / rubbos / app / tomcat-connectors-1.2.32-src / docs / generic_howto / proxy.html
1 <html><head><META http-equiv="Content-Type" content="text/html; charset=iso-8859-1"><title>The Apache Tomcat Connector - Generic HowTo - Reverse Proxy HowTo</title><meta name="author" value="Rainer Jung"><meta name="email" value="rjung@apache.org"><link href="../style.css" type="text/css" rel="stylesheet"></head><body bgcolor="#ffffff" text="#000000" link="#525D76" alink="#525D76" vlink="#525D76"><table border="0" width="100%" cellspacing="4"><!--PAGE HEADER--><tr><td colspan="2"><!--TOMCAT LOGO--><a href="http://tomcat.apache.org/"><img src="../images/tomcat.gif" align="left" alt="Apache Tomcat" border="0"></a><!--APACHE LOGO--><a href="http://www.apache.org/"><img src="http://www.apache.org/images/asf-logo.gif" align="right" alt="Apache Logo" border="0"></a></td></tr><!--HEADER SEPARATOR--><tr><td colspan="2"><hr noshade size="1"></td></tr><tr><!--LEFT SIDE NAVIGATION--><td width="20%" valign="top" nowrap="true"><p><strong>Links</strong></p><ul><li><a href="../index.html">Docs Home</a></li></ul><p><strong>Reference Guide</strong></p><ul><li><a href="../reference/workers.html">workers.properties</a></li><li><a href="../reference/uriworkermap.html">uriworkermap.properties</a></li><li><a href="../reference/status.html">Status Worker</a></li><li><a href="../reference/apache.html">Apache HTTP Server</a></li><li><a href="../reference/iis.html">IIS</a></li></ul><p><strong>Generic HowTo</strong></p><ul><li><a href="../generic_howto/quick.html">For the impatient</a></li><li><a href="../generic_howto/workers.html">All about workers</a></li><li><a href="../generic_howto/timeouts.html">Timeouts</a></li><li><a href="../generic_howto/loadbalancers.html">Load Balancing</a></li><li><a href="../generic_howto/proxy.html">Reverse Proxy</a></li></ul><p><strong>Webserver HowTo</strong></p><ul><li><a href="../webserver_howto/apache.html">Apache HTTP Server</a></li><li><a href="../webserver_howto/iis.html">IIS</a></li><li><a href="../webserver_howto/nes.html">Netscape/SunOne/Sun</a></li></ul><p><strong>AJP Protocol Reference</strong></p><ul><li><a href="../ajp/ajpv13a.html">AJPv13</a></li><li><a href="../ajp/ajpv13ext.html">AJPv13 Extension Proposal</a></li></ul><p><strong>Miscellaneous Documentation</strong></p><ul><li><a href="../miscellaneous/faq.html">Frequently asked questions</a></li><li><a href="../miscellaneous/changelog.html">Changelog</a></li><li><a href="http://issues.apache.org/bugzilla/buglist.cgi?query_format=advanced&amp;short_desc_type=allwordssubstr&amp;short_desc=&amp;product=Tomcat+Connectors&amp;long_desc_type=substring&amp;long_desc=&amp;bug_file_loc_type=allwordssubstr&amp;bug_file_loc=&amp;keywords_type=allwords&amp;keywords=&amp;bug_status=NEW&amp;bug_status=ASSIGNED&amp;bug_status=REOPENED&amp;emailassigned_to1=1&amp;emailtype1=substring&amp;email1=&amp;emailassigned_to2=1&amp;emailreporter2=1&amp;emailcc2=1&amp;emailtype2=substring&amp;email2=&amp;bugidtype=include&amp;bug_id=&amp;votes=&amp;chfieldfrom=&amp;chfieldto=Now&amp;chfieldvalue=&amp;cmdtype=doit&amp;order=Reuse+same+sort+as+last+time&amp;field0-0-0=noop&amp;type0-0-0=noop&amp;value0-0-0=">Current Tomcat Connectors bugs</a></li><li><a href="../miscellaneous/doccontrib.html">Contribute documentation</a></li><li><a href="../miscellaneous/jkstatustasks.html">JK Status Ant Tasks</a></li><li><a href="../miscellaneous/reporttools.html">Reporting Tools</a></li><li><a href="http://tomcat.apache.org/connectors-doc-archive/jk2/index.html">Old JK/JK2 documentation</a></li></ul><p><strong>News</strong></p><ul><li><a href="../news/20110701.html">2011</a></li><li><a href="../news/20100101.html">2010</a></li><li><a href="../news/20090301.html">2009</a></li><li><a href="../news/20081001.html">2008</a></li><li><a href="../news/20070301.html">2007</a></li><li><a href="../news/20060101.html">2006</a></li><li><a href="../news/20050101.html">2005</a></li><li><a href="../news/20041100.html">2004</a></li></ul></td><!--RIGHT SIDE MAIN BODY--><td width="80%" valign="top" align="left"><table border="0" width="100%" cellspacing="4"><tr><td align="left" valign="top"><h1>The Apache Tomcat Connector - Generic HowTo</h1><h2>Reverse Proxy HowTo</h2></td><td align="right" valign="top" nowrap="true"><small><a href="printer/proxy.html"><img src="../images/printer.gif" border="0" alt="Printer Friendly Version"><br>print-friendly<br>version
2                     </a></small></td></tr></table><table border="0" cellspacing="0" cellpadding="2" width="100%"><tr><td bgcolor="#525D76"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Introduction"><strong>Introduction</strong></a></font></td></tr><tr><td><blockquote> 
3 <br>
4 <p>The Apache module mod_jk and its ISAPI and NSAPI variants connect
5 a web server to a backend (typically Tomcat) using the AJP protocol.
6 The web server receives an HTTP(S) request and the module forwards
7 the request to the backend. This function is usually called a gateway
8 or a proxy, in the context of HTTP it is called a reverse proxy.
9 </p>
10 </blockquote></td></tr></table><table border="0" cellspacing="0" cellpadding="2" width="100%"><tr><td bgcolor="#525D76"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Typical Problems"><strong>Typical Problems</strong></a></font></td></tr><tr><td><blockquote>
11 <br>
12 <p>A reverse proxy is not totally transparent to the application on
13 the backend. For instance the host name and port the original client
14 (e.g. browser) needs to talk to belong to the web server and not to the
15 backend, so the reverse proxy talks to a different host name and port.
16 When the application on the backend returns content including
17 self-referential URLs using its own backend address and port, the
18 client will usually not be able to use these URLs.
19 </p>
20 <p>Another example is the client IP address, which for the web server is the
21 source IP of the incoming connection, whereas for the backend the
22 connection always comes from the web server. This can be a problem, when
23 the client IP is used by the backend application e.g. for security reasons.
24 </p>
25 </blockquote></td></tr></table><table border="0" cellspacing="0" cellpadding="2" width="100%"><tr><td bgcolor="#525D76"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="AJP as a Solution"><strong>AJP as a Solution</strong></a></font></td></tr><tr><td><blockquote>
26 <br>
27 <p>Most of these problems are automatically handled by the AJP protocol
28 and the AJP connectors of the backend. The AJP protocol transports
29 this communication metadata and the backend connector presents this
30 metadata whenever the application asks for it using Servlet API methods.
31 </p>
32 <p>The following list contains the communication metadata handled by AJP
33 and the ServletRequest/HttpServletRequest API calls which can be used to retrieve them:
34 <ul>
35 <li>local name: <b class="code">getLocalName()</b> and <b class="code">getLocalAddr</b>.
36 This is also equal to <b class="code">getServerName()</b>, unless a <b class="code">Host</b> header
37 is contained in the request. In this case the server name is taken from that header.
38 </li>
39 <li>local port: <b class="code">getLocalPort()</b>
40 This is also equal to <b class="code">getServerPort()</b>, unless a <b class="code">Host</b> header
41 is contained in the request. In this case the server port is taken from that header
42 if it contains an explicit port, or is equal to the default port of the scheme used.
43 </li>
44 <li>client address: <b class="code">getRemoteAddr()</b>
45 </li>
46 <li>client port: <b class="code">getRemotePort()</b>
47 The remote port was initially not supported. It is available when using mod_jk 1.2.32
48 with Apache or IIS (not for the NSAPI plugin) together with Tomcat version at least
49 5.5.28, 6.0.20 or 7.0.0. For older versions, <b class="code">getRemotePort()</b>
50 will incorrectly return 0 or -1. As a workaround you can forward the remote port by setting
51 <b class="code">JkEnvVar REMOTE_PORT</b> and then either using
52 <b class="code">request.getAttribute("REMOTE_PORT")</b> instead of <b class="code">getRemotePort()</b>
53 or wrapping the request using a filter and overriding <b class="code">getRemotePort()</b> with
54 <b class="code">request.getAttribute("REMOTE_PORT")</b>.
55 </li>
56 <li>client host: <b class="code">getRemoteHost()</b>
57 </li>
58 <li>authentication type: <b class="code">getAuthType()</b>
59 </li>
60 <li>remote user: <b class="code">getRemoteUser()</b>,
61 if <b class="code">tomcatAuthentication="false"</b>
62 </li>
63 <li>protocol: <b class="code">getProtocol()</b>
64 </li>
65 <li>HTTP method: <b class="code">getMethod()</b>
66 </li>
67 <li>URI: <b class="code">getRequestURI()</b>
68 </li>
69 <li>HTTPS used: <b class="code">isSecure()</b>, <b class="code">getScheme()</b>
70 </li>
71 <li>query string: <b class="code">getQueryString()</b>
72 </li>
73 </ul>
74 The following additional SSL-related data will be made available by Apache and forwarded by mod_jk only
75 if you set <b class="code">SSLOptions +StdEnvVars</b>. For the certificate information you also need
76 to set <b class="code">SSLOptions +ExportCertData</b>.
77 <ul>
78 <li>SSL cipher: <b class="code">getAttribute(javax.servlet.request.cipher_suite)</b>
79 </li>
80 <li>SSL key size: <b class="code">getAttribute(javax.servlet.request.key_size)</b>.
81 Can be disabled using <b class="code">JkOptions -ForwardKeySize</b>.
82 </li>
83 <li>SSL client certificate: <b class="code">getAttribute(javax.servlet.request.X509Certificate)</b>.
84 If you want the whole certificate chain, then you need to also set <b class="code">JkOptions ForwardSSLCertChain</b>.
85 It is likely, that in this case you also need to adjust the maximal AJP packet size
86 using the worker attribute <a href="../reference/workers.html">max_packet_size</a>.
87 </li>
88 <li>SSL session ID: <b class="code">getAttribute(javax.servlet.request.ssl_session)</b>.
89 This is for Tomcat, it has not yet been standardized.
90 </li>
91 </ul>
92 </p>
93 </blockquote></td></tr></table><table border="0" cellspacing="0" cellpadding="2" width="100%"><tr><td bgcolor="#525D76"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Fine Tuning"><strong>Fine Tuning</strong></a></font></td></tr><tr><td><blockquote>
94 <br>
95 <p>In some situations this is not enough though. Assume there is another
96 less clever reverse proxy in front of your web server, for instance an
97 HTTP load balancer or similar device which also serves as an SSL accelerator.
98 </p>
99 <p>Then you are sure that all your clients use HTTPS, but your web server doesn't
100 know about that. All it can see is requests coming from the accelerator using
101 plain HTTP.
102 </p>
103 <p>Another example would be a simple reverse proxy in front of your web server,
104 so that the client IP address that your web server sees is always the IP address
105 of this reverse proxy, and not of the original client. Often such reverse proxies
106 generate an additional HTTP header, like <b class="code">X-Forwareded-for</b> which
107 contains the original client IP address (or a list of IP addresses, if there are
108 more cascading reverse proxies in front). It would be nice, if we could use the
109 content of such a header as the client IP address to pass to the backend.
110 </p>
111 <p>So we might need to manipulate some of the data that AJP sends to the backend.
112 When using mod_jk inside Apache httpd you can use several httpd environment
113 variables to let mod_jk know, which data it should forward. These environment variables
114 can be set by the httpd directives SetEnv or SetEnvIf, but also in a very flexible
115 way using mod_rewrite (since httpd 2.x it can not only test against environment
116 variables, but also set them).
117 </p>
118 <p>The following list contains all environment variables mod_jk checks, before
119 sending data to the backend:
120 <ul>
121 <li>JK_LOCAL_NAME: the local name
122 </li>
123 <li>JK_LOCAL_PORT: the local port
124 </li>
125 <li>JK_REMOTE_HOST: the client host
126 </li>
127 <li>JK_REMOTE_ADDR: the client address
128 </li>
129 <li>JK_AUTH_TYPE: the authentication type
130 </li>
131 <li>JK_REMOTE_USER: the remote user
132 </li>
133 <li>HTTPS: On (case-insensitive) to indicate, that HTTPS is used
134 </li>
135 <li>SSL_CIPHER: the SSL cipher
136 </li>
137 <li>SSL_CIPHER_USEKEYSIZE: the SSL key size
138 </li>
139 <li>SSL_CLIENT_CERT: the SSL client certificate
140 </li>
141 <li>SSL_CLIENT_CERT_CHAIN_: prefix of variable names, containing
142 the client cerificate chain
143 </li>
144 <li>SSL_SESSION_ID: the SSL session ID
145 </li>
146 </ul>
147 </p>
148 <p>Remember: in general you don't need to set them. The module retrieves the data automatically
149 from the web server. Only in case you want to change this data, you can overwrite it by
150 using these variables.
151 </p>
152 <p>Some of these variables might also be used by other web server modules. All
153 variables whose name does not begin with "JK" are set directly by Apache httpd.
154 If you want to change the data, but do not want to negatively influence the behaviour
155 of other modules, you can change the names of all variables mod_jk uses to private ones.
156 For the details see the <a href="../reference/apache.html">Apache reference</a> page.
157 </p>
158 <p>All variables, that are not SSL-related have only been introduced in version 1.2.27.
159 </p>
160 <p>Finally there is a shortcut to forward the local IP of the web server as the remote IP.
161 This can be useful, e.g. when using the Tomcat remote address valve for allowing connections
162 only from registered Apache web servers. This feature is activated by setting
163 <b class="code">JkOptions ForwardLocalAddress</b>.
164 </p>
165 </blockquote></td></tr></table><table border="0" cellspacing="0" cellpadding="2" width="100%"><tr><td bgcolor="#525D76"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Tomcat AJP Connector Settings"><strong>Tomcat AJP Connector Settings</strong></a></font></td></tr><tr><td><blockquote>
166 <br>
167 <p>As an alternative to using the environment variables described in the previous section
168 (which do only exist when using Apache httpd), you can also configure Tomcat to overwrite
169 some of the communications data forwarded by mod_jk. The AJP connector in Tomcat's <b class="code">server.xml</b>
170 allows to set the <a href="http://tomcat.apache.org/tomcat-6.0-doc/config/ajp.html#Attributes">following properties</a>:
171 <ul>
172 <li>proxyName: server name as returned by <b class="code">getServerName()</b>
173 </li>
174 <li>proxyPort: server port as returned by <b class="code">getServerPort()</b>
175 </li>
176 <li>scheme: protocol scheme as returned by <b class="code">getScheme()</b>
177 </li>
178 <li>secure: set to "true", if you wish <b class="code">isSecure()</b> to return "true".
179 </li>
180 </ul>
181 Remember: in general you don't need to set those. AJP automatically handles all cases
182 where the web server running mod_jk knows the right data.
183 </p>
184 </blockquote></td></tr></table><table border="0" cellspacing="0" cellpadding="2" width="100%"><tr><td bgcolor="#525D76"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="URL Handling"><strong>URL Handling</strong></a></font></td></tr><tr><td><blockquote>
185 <br>
186 <table border="0" cellspacing="0" cellpadding="2" width="100%"><tr><td bgcolor="#828DA6"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="URL Rewriting"><strong>URL Rewriting</strong></a></font></td></tr><tr><td><blockquote>
187 <p>Sometimes one want to change path components of the URLs under which an application
188 is available. Especially if a web application is deployed as some context, say <b class="code">/myapp</b>,
189 marketing prefers short URLs, so want the application to be directly available under
190 <b class="code">http://www.mycompany.com/</b>. Although you can deploy the application as the so-called
191 ROOT context, which will be directly available at "/", admins often prefer not to use
192 the ROOT context, e.g. because only one application can be the root context (per host).
193 </p>
194 <p>The procedure to change the URLs in the reverse proxy is tedious, because often
195 an application produces self-referential URLs, which then include the path components
196 which you tried to hide to the outside world. Nevertheless, if you absolutely need to do it,
197 here are the steps.
198 </p>
199 <p>Case A: You need to make the application available at a simple URL, but it is OK, if
200 users proceed using the more complex URLs, as long as they don't have to type them in.
201 That's the easy case, and if this suffices to you, you're lucky. Use a simply RedirectMatch
202 for Apache httpd:
203 </p>
204 <div class="example"><pre>
205 RedirectMatch ^/$ http://www.mycompany.com/myapp/
206 </pre></div>
207 <p>Your application will then be available under <b class="code">http://www.mycompany.com/</b>,
208 and each visitor will be immediately redirected to the real URL
209 <b class="code">http://www.mycompany.com/myapp/</b>
210 </p>
211 <p>Case B: You need to hide path components for all requests going to the application.
212 Here's the recipe for the case, where you want to hide the first path component
213 <b class="code">/myapp</b>. More complex manipulations are left as an exercise to the reader.
214 First the solution for the case of Apache httpd:
215 </p>
216 <p>1. Use <a href="http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html"><b class="code">mod_rewrite</b></a>
217 to add <b class="code">/myapp</b> to all requests before forwarding to the backend:
218 </p>
219 <div class="example"><pre>
220 # Don't forget the PT flag! (pass through)
221 RewriteRule ^/(.*) http://www.mycompany.com/myapp/$1 [PT]
222 </pre></div>
223 <p>2. Use <a href="http://httpd.apache.org/docs/2.2/mod/mod_headers.html"><b class="code">mod_headers</b></a>
224 to rewrite any HTTP redirects your application might return. Such redirects typically contain
225 the path components you want to hide, because by the HTTP standard, redirects always need to include
226 the full URL, and your application is not aware of the fact, that your clients talk to it via
227 some shortened URL. An HTTP redirect is done with a special response header named <b class="code">Location</b>.
228 We rewrite the Location headers of our responses:
229 </p>
230 <div class="example"><pre>
231 # Keep protocol, server and port if present,
232 # but insert our webapp name before the rest of the URL
233 Header edit Location ^([^/]*//[^/]*)?/(.*)$ $1/myapp/$2 
234 </pre></div>
235 <p>3. Use <b class="code">mod_headers</b> again, to rewrite the paths contained in any cookies,
236 your application might set. Such cookie paths again might contain
237 the path components you want to hide.
238 A cookie is set with the HTTP response header named <b class="code">Set-Cookie</b>.
239 We rewrite the Set-Cookie headers of our responses:
240 </p>
241 <div class="example"><pre>
242 # Fix the cookie path
243 Header edit Set-Cookie "^(.*; Path=/)(.*)" $1/myapp/$2 
244 </pre></div>
245 <p>3. Some applications might contain hard coded absolute links.
246 In this case check, whether you find a configuration item for your web framework
247 to configure the base URL. If not, your only chance is to parse all response
248 content bodies and do search and replace. This is fragile and very resource intensive.
249 If you really need to do this, you can use
250 <a href="http://apache.webthing.com/mod_proxy_html/"><b class="code">mod_proxy_html</b></a>,
251 <a href="http://httpd.apache.org/docs/2.2/mod/mod_substitute.html"><b class="code">mod_substitute</b></a>
252 or <a href="http://blogs.sun.com/basant/entry/using_mod_sed_to_filter"><b class="code">mod_sed</b></a>
253 for this task.
254 </p>
255 <p>If you are using Microsoft IIS as a web server, the ISAPI plugin provides a way
256 of doing the first step with a builtin feature. You define a mapping file for simple prefix
257 changes like this:
258 </p>
259 <div class="example"><pre>
260 # Add a context prefix to all requests ...
261 /=/myapp/
262 # ... or change some prefix ...
263 /oldapp/=/myapp/
264 </pre></div>
265 <p>and then put the name of the file in the <b class="code">rewrite_rule_file</b> entry of the registry or your
266 <b class="code">isapi_redirect.properties</b> file. In you <b class="code">uriworkermap.properties</b> file, you
267 still need to map the URLs as they are before rewriting!
268 </p>
269 <p>More complex rewrites can be done using the same file, but with regular expressions. A leading
270 tilde sign '<b class="code">~</b>', indicates, that you are using a regular expression:
271 </p>
272 <div class="example"><pre>
273 # Use a regular expression rewrite
274 ~/oldapps([0-9]*)/=/newapps$1/
275 </pre></div>
276 <p>There is no support for Steps 2 (rewriting redirect responses) or 3 (rewriting cookie paths).
277 </p>
278 </blockquote></td></tr></table>
279 <table border="0" cellspacing="0" cellpadding="2" width="100%"><tr><td bgcolor="#828DA6"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="URL Encoding"><strong>URL Encoding</strong></a></font></td></tr><tr><td><blockquote>
280 <p>Some types of problems are triggered by the use of encoded URLs
281 (see <a href="http://en.wikipedia.org/wiki/Percent-encoding">percent encoding</a>).
282 For the same location there exist
283 a lot of different URLs which are equivalent. The reverse proxy needs to inspect the URL in order
284 to apply its own authentication rules and to decide, to which backend it should send the request
285 (or whether it should handle it itself). Therefore the request URL first is normalized:
286 percent encoded characters are decoded, <b class="code">/./</b> is replaced by <b class="code">/</b>,
287 <b class="code">/XXX/../</b> is replaced by <b class="code">/</b> and similar manipulations of the URL are done.
288 After that, the web server might apply rewrite rules to further change the URL in less obvious ways.
289 Finally there is no more way to put the resulting URL in an encoding, which is "similar" to
290 the one which was used for the original URL.
291 </p>
292 <p>
293 For historical reasons, there have been several alternatives, how mod_jk and the ISAPI
294 plugin encoded the resulting URL before sending it to the backend. They could be chosen via
295 <b class="code">JkOptions</b> (Apache httpd) or <b class="code">uri_select</b> (ISAPI). None of those historical
296 encodings are recommended, because they have either negative functionality implications or
297 pose a security risk. The default encoding since version 1.2.24 is <b class="code">ForwardURIProxy</b>
298 (Apache httpd) or <b class="code">proxy</b> (ISAPI) and it is strongly recommended to keep the default
299 and remove all old explicit settings.
300 </p>
301 </blockquote></td></tr></table>
302 </blockquote></td></tr></table><table border="0" cellspacing="0" cellpadding="2" width="100%"><tr><td bgcolor="#525D76"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Request Attributes"><strong>Request Attributes</strong></a></font></td></tr><tr><td><blockquote>
303 <br>
304 <p>
305 You can also add more attributes to any request you are forwarding when using Apache httpd.
306 For this use the <b class="code">JkEnvVar</b> directive (for details see the
307 <a href="../reference/apache.html">Apache reference</a> page). Such request attributes can be
308 retrieved on the Tomcat side via request.getAttribute(attributeName).
309 Note that their names will not be listed in request.getAttributeNames()!
310 </p>
311 </blockquote></td></tr></table></td></tr><!--FOOTER SEPARATOR--><tr><td colspan="2"><hr noshade size="1"></td></tr><!--PAGE FOOTER--><tr><td colspan="2"><div align="center"><font color="#525D76" size="-1"><em>
312         Copyright &copy; 1999-2011, Apache Software Foundation
313         </em></font></div></td></tr></table></body></html>