Generally, we discourage wholesale URI alterations that try to hide or change entire context roots as they often become unmanageable and conflict with the operation of the application. However, the general consensus is that offloading is good for performance and throughput.
There are a few ways to compensate for the generated plugin-cfg.xml, in order of preference.
*.do
.
Note that the RewriteRule directives are kept as simple as possible, but in practice can contain regular expressions and backreferences to alter an entire class of URIs.
*.jsp
and is not context-root relative, so we need to alter the URI to include so the plug-in will recognize and handle the request.
WebSphere Resource | Link in HTML |
---|---|
/app1/SignIn.do | /ProjectA/SignIn |
The link as written won't be recognized by the WebSphere Plug-in, because it doesn't match any pattern in plugin-cfg.xml. When fileServingEnabled=true in the WAR (or in all cases with Liberty), only the context root is listed in plugin-cfg.xml. With fileServingEnabled=false, individual servlets and URI patterns are added, the simplest of which is *.jsp.
We can add a configuration snippet like the following to either add the extension or prefix with the context root (or both)
RewriteEngine on
RewriteRule /ProjectA/SignIn /app1/SignIn.jsp [PT]
Alias
directive isn't effective here, because that only maps a URI to a filename on the IHS system and doesn't change the URI in the request. If it was used, IHS would be trying to find /servlet/members/ProjectA/V3/SignIn.do under the Document Root.
Filesystem Resource | Link in HTML | resource requested by browser |
---|---|---|
/var/www/myapp-unpacked/.../foo.css | foo.css | /context-root/foo.css |
/var/www/myapp-unpacked/.../example.jsp | example.jsp | /context-root/example.jsp |
This links as written will be recognized by the WebSphere plug-in and passed to WebSphere Application Server, so we add the following directives to the IHS configuration to make sure it's served out of the filesystem.
# Make /context-root/ work for local files
Alias /context-root/ /var/www/myapp-unpacked/
# Allow access to /var/www/myapp-unpacked/
<Directory /var/www/myapp-unpacked/>
Order deny,allow
</Directory>
# Tell the WAS Plugin to defer to Apache
SetEnvIf Request_URI ^/context-root/.*\.css skipwas=1
# Invent a new prefix, /static/ for unpacked content
Alias /static /var/www/myapp-unpacked/
# Allo access
Alias /static /var/www/myapp-unpacked/
<Directory /var/www/myapp-unpakced/>
Order deny,allow
</Directory>
# remove the context root, hiding it from the WebSphere Plugin
RewriteEngine on
RewriteRule ^/context-root/(.*\.(?:css|jpg|gif|js|jpeg)$) /static/$1 [PT]
# Example to serve the source code for the example JSP, even though it matches *.jsp even with fileServingEnabled=false
RewriteRule ^/context-root/example.jsp /static/example.jsp [PT]
WebSphere Resource | Typo |
---|---|
/servlet/already.do | /servlet/allready.do |
We change the URI that will be seen by the WebSphere plug-in as follows:
RewriteEngine on RewriteRule ^/servlet/allready.do$ /servlet/already.do [PT]
Redirect /servlet/allready.do /servlet/already.do
One motivation for this aside from freeing up WebSphere threads is that only URLs served out of the IHS filesystem can be protected with .htaccess files, WebSphere resources must be protected with <Location> containers explicitly in httpd.conf.
The WAR file has been pushed to the IHS server in the /tmp directory.
The original access log entry which shows the plug-in handling the response: 127.0.0.1 - (mod_was_ap20_http.c/-2/handler) - [01/Dec/2006:14:57:51 -0500] "GET /SillyNew/theme/blue.css HTTP/1.1" 200 9049 After enabling config change as illustrated above, IHS has attempted to serve the file from its own filesystem: 127.0.0.1 - (mod_auth.c/401/check_user_id) - [01/Dec/2006:15:10:13 -0500] "GET /SillyNew/theme/blue.css HTTP/1.0" 401 466 After enabling above and sending the proper userid/password 127.0.0.1 - (core.c/0/handler) user1 [01/Dec/2006:15:11:15 -0500] "GET /SillyNew/theme/blue.css HTTP/1.0" 200 9049
RequestHeader
directive to change the Host headerRequestHeader
can be used to influence the plug-in while it's deciding whether or not to handle the request, by specifying the "early" flag (2.2.x only). Previous versions of this FAQ incorrectly said this doesn't work. It works reliably at least on IHS 7.0 and later, with the big caveat that it cannot be tied to a subset of requests -- it affects the entire virtual host. Don't try to put it in <Location>, or combine it with mod_rewrite [E= or SetEnvIf, the timing does not work. You must use the "early" flag.
.htaccess files are only processed by IHS after a request has been mapped to a local file, therefore .htaccess files cannot be the mechanism used to prevent the plug-in from handling a URL.
In some more complicated configurations, multiple mod_rewrite rules may potentially operate on the same incoming URL. In addition to the PassThrough flag (PT), the Last (L) flag is often used to end rewriting with the current rule. Flags are combined by separating them with commas as in the following:
# Transparently rewrite anything matching *.do under /servlet/app1 and stop rewrite processing (L=Last flag) RewriteRule /servlet/app1/(.*\.do) /servlet/$1.jsp [PT,L] RewriteRule ...
If your app is deployed to /ourapp, and you only host 1 application, and you want to hide /ourapp from the browser completely, you can add the /ourapp prefix to each request internally.
RewriteEngine on RewriteRule ^(?!/ourapp)(.*) /ourapp$1 [PT]
It's not possible to use mod_dir to to map e.g. / to /index.jsp because of checking done by mod_dir
when querying the DirectoryIndex
filenames through an internal subrequest.
If you want your mod_rewrite directives, and they overlap with a resource the Plugin is responsible for, then these rewrite rules should be in <VirtualHost> context. They should not be in <Directory> context nor in .htaccess files. This is a requirement because the WebSphere Plugin acts in a phase of Apache Processing that maps the request outside of the filesystem, and rewrite rules in these latter contexts would simply be not applicable.
In practice, this is not a troublesome limitation, because it agrees with best practice for mod_rewrite.
There may be some configurations which exploit this behavior to serve things such as images out of the filesystem instead of from WebSphere using an Alias directive -- upgraders will find they must replace this Alias directive with an equivalent RewriteRule directive.
Incorrect: Alias /servlet/images/ /images/ Correct : RewriteRule /servlet/images/(.*) /images/$1 [PT]
The WAS plugin does not match /* to // which may be exploited in Apache 2.0 / IHS 6.1 and earlier to cause a request to be skipped by the WAS Plug-in.
In Apache 2.2 / IHS 7.0 and later, a leading sequence of slashes in a URL is collapsed to a single slash, so it is not possible to send a URL down to the Plugin and retain a leading "//".
Provide feedback on the IBM HTTP Server forum on IBM developerWorks.