CentOS – Apache 2.2.15 mod_proxy encoding URL (for JBOSS7 or Tomcat)

Scenario

It’s common practice to use a HTTP server (such as Apache) as a frontend to a Java servlet container (e.g. Tomcat) and Java application servers (e.g. JBOSS7) which make use of them.

The issue

If your application (which talks to Apache+JBOSS7) sends URLs with encoded characters (such as slashes and pluses), you will receive 404s and 50xs.

If you investigate the logs (of both Apache and JBOSS7), you’ll notice that the URL that Apache receives:

AAMkADIwYzdlZTU5LWQ3MjUtNDA2OS1iNjBjLWRmYTYwMGI1YjVkOQBGAAAAAADsB2JbdyewTqR9Iko9qiuTBwDC45nmayJARpBboI%2FVRD%2BxAAAAdo0nAADC45nmayJARpBboI%2FVRD%2BxAAAAd8YhAAA%3D

is not the same as the URL that your application server receives:

AAMkADIwYzdlZTU5LWQ3MjUtNDA2OS1iNjBjLWRmYTYwMGI1YjVkOQBGAAAAAADsB2JbdyewTqR9Iko9qiuTBwDC45nmayJARpBboI/VRD+xAAAAdo0nAADC45nmayJARpBboI/VRD+xAAAAd8YhAAA=

In fact, you will notice that some characters are being decoded.

Breakdown – Issue 1

By default, Apache will not accept URLs with encoded forward-slashes (/) (which are encoded as %2F).

Breakdown – Fix for Issue 1

Apache needs to be told to allow encoded slashes as part of the URL, or it will return a 404. To allow the encoded slashes, you can use the following directive:

AllowEncodedSlashes On

If you wish to know more about this, see the relevant Apache documentation: http://httpd.apache.org/docs/2.2/mod/core.html#allowencodedslashes

Breakdown – Issue 2

Apache will now accept encoded slashes as part of the URL, but you may still experience Apache decoding other characters (such as pluses, which are encoded as %2B), which results in 50xs errors.

Breakdown – Fix for Issue 2

To stop Apache decoding other characters, you can use the “nocanon” keyword. Append “nocanon” onto your ProxyPass directive, like so:

ProxyPass / http://localhost:8080/ nocannon

For more information see the relevant Apache documentation: http://httpd.apache.org/docs/2.2/mod/mod_proxy.html#proxypass — but to summarise it:
“The optional nocanon keyword suppresses [the canonicalization of the URL], and passes the URL path “raw” to the backend. “.