Rainer Jung wrote:
On 31.12.2008 10:08, André Warnier wrote:
Juha Laiho wrote:
[...]
Thanks, Juha. That helps me think in another direction.
Maybe indeed in this case the mod_headers module does not get a chance
to modify the response headers, because it is added before the mod_jk
module, and mod_jk overrides it.
It is worth investigating anyway, since the other solutions I can see
are a lot heavier in my case (output filter or trying mod_proxy_ajp).
Apache 2 has hooks for modules, but also filters. The hooks allow to
interact with request processing at certain stages and the modules
decide, whether they allow other modules to be called in the same hook.
mod_headers is a filter, which allows to manipulate requests and
responses much like servlet filters during the reading and writing of
request resp. response. Thus you can use mod_headers to change headers
after they are returned by mod_jk.
Unfortunately the Content-Type header is a different beast. Inside
Apache it is not only a response header, but a more complex data type.
You can set a different Content-Type header with mod_headers, but since
the internal structure remains unchanged it will be overwritten again by
Apache.
As a result I see no way to change an existing character set in a
Content-Type header.
I have tried changing the Content-Type header in a servlet filter under
Tomcat. However, that also has the side-effect that the servlet then,
for its response, really uses the new character encoding specified in
the header, to produce its response.
That is not what I want here, because the problem is that the servlet
response is already correct (in the iso-8859-2 encoding), it is just
that the Content-Type header is incorrect and does not match the real
charset of the response. The underlying reason for all that stuff is
obscure and OT here, but that is really what happens.
See javax.servlet.ServletResponseWrapper. A filter can replace request
and/or response with a custom wrapper object. Whenever the servlet then
calls a method of the request or response object, your custom object is
called. Your custom response wrapper extends the standard one, which
itself lets all methods call through to the wrapped response. You can
then implement individual methods in a different way. You could for
instance overwrite setCharacterEncoding(java.lang.String charset) to set
something else, then demanded by the caller (e.g. iso-8859-2 instead of
iso-8859-1), and getCharacterEncoding() to return something different,
from what you actually set.
The filter can inspect e.g. the URL to decide, whether it should wrap
the response or not.
This mechanism can be used without any changes to the existing webapp
code, you only need to add your filter and wrapper to the webapp, and of
course add the filter to web.xml.
Thanks for your very clear response, Rainer.
This will save me a lot of time trying unworkable solutions, such as
trying mod_proxy_ajp instead of mod_jk.
I also tried a mod_perl connection output filter in the meantime (based
on Apache2::Filter::HTTPHeadersFixup), with no more success. Your
explanation above makes clear why.
To wrap us thus :
- with mod_headers or another Apache or mod_perl connection output
filter, one *can* modify response headers set by a Tomcat application
and returned through mod_jk (or whatever), but the Content-Type header
is a special case. It will also be in fact modified by the above, but
Apache will in the end override that modification and restore the
original Content-Type header, based on some internal information.
This has nothing to do with mod_jk itself, it is a generic Apache
mechanism for the Content-Type header in particular.
- the only viable solution in my case is thus to make sure that the
Tomcat servlet issues the correct Content-Type header in the first
place. If the servlet itself cannot be modified, then a servlet filter
wrapping the response in a javax.servlet.ServletResponseWrapper wrapper
would be the way to go. The wrapper should override the methods by
which the servlet sets and/or obtains the response encoding.
(In my case, the servlet has to "keep believing" that its response
output stream is iso-8859-1, otherwise it does the wrong charset
translations from its internal Unicode strings to the 8-bit response
stream.)
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org