You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Richard Kaye <R....@bham.ac.uk> on 2007/06/21 17:04:09 UTC

using mod_jk: how to set content-type

Hi 

I am using Tomcat5.5, Apache2.2 and mod_jk1.2
and a third-part servlet which I can't re-program or
configure.

I need to sniff the HTTP "User-Agent" and/or "Accept"
fields and change the content-type 
(currently "text/html;charset=UTF-8") that the
servlet returns based on these.

using mod_headers and mod_setenvif, I currently 
have (in my apache2 config) something like:

    SetEnvIf User-Agent Whatever DETECTED1
    SetEnvIf Accept Somethingelse DETECTED2
    JkMount /servletname/* ajp13_worker
    <LocationMatch /servletname/* >
        Header set Content-Type "text/xml" env=DETECTED1
        Header set Content-Type "application/xml" env=DETECTED2
    </LocationMatch>

Unfortunately, it doesn't work. Specifically, I always get the
document served as "Content-Type: text/html;charset=UTF-8" 
and not "Content-Type: text/xml" as expected. From googling a bit
I have learnt that the mod_headers module won't set the Content-Type
header, because this one is set internally by apache at a later stage.
But I couldn't find a workaround or alternative that does what I want.

Help please!

And many thanks...

Richard


---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: using mod_jk: how to set content-type

Posted by Richard Kaye <R....@bham.ac.uk>.
Yes, I understood Johnny's point about other uses for a filter
even though it was somewhat off-topic.  He is quite right about
what I am trying to do.

I've looked at it and can write a filter and get this going 
to solve my particular problem.  I can't yet see how to write 
a reasonably powerful generic filter that would be configurable 
and applicable in a wide range of situations. I'm sure it would 
be useful.

R



On Thu, 2007-06-21 at 20:34 +0200, Johnny Kewl wrote:
> I'm agreeing with you, but just wondering why Richard wants to take a
> 3rd 
> party servlet that is clearly pumping out html, and make it look like 
> XML.... and then concluding that it will probably be badly formed XML
> (or 
> XHTML)... because HTML is close, but not XML.
> 


---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: using mod_jk: how to set content-type

Posted by Johnny Kewl <jo...@kewlstuff.co.za>.
----- Original Message ----- 
From: "Gregor Schneider" <rc...@googlemail.com>

> On 6/21/07, Johnny Kewl <jo...@kewlstuff.co.za> wrote:
>> You know I just had another thought.... yes it happens sometimes.
>
> Wrong. It does ALWAYS happen:

Ha ha... no its my warped sense of humor... sometimes I have thoughts... you 
know little eurika's ;)... ok, only I get it ;)

I'm agreeing with you, but just wondering why Richard wants to take a 3rd 
party servlet that is clearly pumping out html, and make it look like 
XML.... and then concluding that it will probably be badly formed XML (or 
XHTML)... because HTML is close, but not XML.

And therefore... yes you right, a filter is a better bet, because if parsing 
headers is already difficult in JK, and as you say, impossible, then how 
they going to create well formed XML, before it gets to whereever its 
going.... and I'm guessing it will be input to an XSLT engine, so they can 
present another HTML page, with the extracted data from the original page.

Think my reply was to Richard....

> Apache httpd (2.x) in conjunction with mod_jk does not touch any
> headers passed from mod_jk, thus there's no possibility to change
> them, not with mod_headers or any other module, I've tried them all. A
> filter in Tomcat is the only option I found.
>
> The reason is definately not any issue with XHTML-parsing.
>
> Gregor
> ---
> what's puzzlin' you, is the nature of my game
> gpgp-fp: 79A84FA526807026795E4209D3B3FE028B3170B2
> gpgp-key available @ http://pgpkeys.pca.dfn.de:11371
>
> ---------------------------------------------------------------------
> To start a new topic, e-mail: users@tomcat.apache.org
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>
> 


---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: using mod_jk: how to set content-type

Posted by Gregor Schneider <rc...@googlemail.com>.
On 6/21/07, Johnny Kewl <jo...@kewlstuff.co.za> wrote:
> You know I just had another thought.... yes it happens sometimes.

Wrong. It does ALWAYS happen:

Apache httpd (2.x) in conjunction with mod_jk does not touch any
headers passed from mod_jk, thus there's no possibility to change
them, not with mod_headers or any other module, I've tried them all. A
filter in Tomcat is the only option I found.

The reason is definately not any issue with XHTML-parsing.

Gregor
---
what's puzzlin' you, is the nature of my game
gpgp-fp: 79A84FA526807026795E4209D3B3FE028B3170B2
gpgp-key available @ http://pgpkeys.pca.dfn.de:11371

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: using mod_jk: how to set content-type

Posted by Johnny Kewl <jo...@kewlstuff.co.za>.
You know I just had another thought.... yes it happens sometimes.
I have a feeling you doing html parsing, and just wanted to say that it 
depends very much on how well that 3rd party servlet does XHTML... probably 
badly ie little <br> all over the place which will make the XML parser you 
using throw it out.

If you use a filter.... you can even fix that, ie make sure its perfect XML.


----- Original Message ----- 
From: "Richard Kaye" <R....@bham.ac.uk>
To: "Tomcat Users List" <us...@tomcat.apache.org>
Sent: Thursday, June 21, 2007 5:04 PM
Subject: using mod_jk: how to set content-type


> Hi
>
> I am using Tomcat5.5, Apache2.2 and mod_jk1.2
> and a third-part servlet which I can't re-program or
> configure.
>
> I need to sniff the HTTP "User-Agent" and/or "Accept"
> fields and change the content-type
> (currently "text/html;charset=UTF-8") that the
> servlet returns based on these.
>
> using mod_headers and mod_setenvif, I currently
> have (in my apache2 config) something like:
>
>    SetEnvIf User-Agent Whatever DETECTED1
>    SetEnvIf Accept Somethingelse DETECTED2
>    JkMount /servletname/* ajp13_worker
>    <LocationMatch /servletname/* >
>        Header set Content-Type "text/xml" env=DETECTED1
>        Header set Content-Type "application/xml" env=DETECTED2
>    </LocationMatch>
>
> Unfortunately, it doesn't work. Specifically, I always get the
> document served as "Content-Type: text/html;charset=UTF-8"
> and not "Content-Type: text/xml" as expected. From googling a bit
> I have learnt that the mod_headers module won't set the Content-Type
> header, because this one is set internally by apache at a later stage.
> But I couldn't find a workaround or alternative that does what I want.
>
> Help please!
>
> And many thanks...
>
> Richard
>
>
> ---------------------------------------------------------------------
> To start a new topic, e-mail: users@tomcat.apache.org
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>
> 


---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: using mod_jk: how to set content-type

Posted by Johnny Kewl <jo...@kewlstuff.co.za>.
Dont know Apache in that detail, possibly a guru maybe able to fix the way 
you attempting, but I think it should be relatively easy to add a filter to 
tomcat to do that.... there you can intercept both request and response.  ie 
intercept the request, if browser let it go, if XSLT engine, pretent to be 
XML.  Very easy I think.


----- Original Message ----- 
From: "Richard Kaye" <R....@bham.ac.uk>
To: "Tomcat Users List" <us...@tomcat.apache.org>
Sent: Thursday, June 21, 2007 5:04 PM
Subject: using mod_jk: how to set content-type


> Hi
>
> I am using Tomcat5.5, Apache2.2 and mod_jk1.2
> and a third-part servlet which I can't re-program or
> configure.
>
> I need to sniff the HTTP "User-Agent" and/or "Accept"
> fields and change the content-type
> (currently "text/html;charset=UTF-8") that the
> servlet returns based on these.
>
> using mod_headers and mod_setenvif, I currently
> have (in my apache2 config) something like:
>
>    SetEnvIf User-Agent Whatever DETECTED1
>    SetEnvIf Accept Somethingelse DETECTED2
>    JkMount /servletname/* ajp13_worker
>    <LocationMatch /servletname/* >
>        Header set Content-Type "text/xml" env=DETECTED1
>        Header set Content-Type "application/xml" env=DETECTED2
>    </LocationMatch>
>
> Unfortunately, it doesn't work. Specifically, I always get the
> document served as "Content-Type: text/html;charset=UTF-8"
> and not "Content-Type: text/xml" as expected. From googling a bit
> I have learnt that the mod_headers module won't set the Content-Type
> header, because this one is set internally by apache at a later stage.
> But I couldn't find a workaround or alternative that does what I want.
>
> Help please!
>
> And many thanks...
>
> Richard
>
>
> ---------------------------------------------------------------------
> To start a new topic, e-mail: users@tomcat.apache.org
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>
> 


---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: using mod_jk: how to set content-type

Posted by Richard Kaye <R....@bham.ac.uk>.
Thanks for the quick reply, Rainer. Yes a servlet filter
makes sense, though not as easy as a one-liner httpd 
directive.

I guess my immediate response is surprise that (since
this must be a common problem with so many poorly 
written web-clients doing content-negotiation so badly 
out in the big-wide-web) that there aren't any stock 
servlet filters already written that I can use "out of 
the box".  Does anyone know of any?

I will try the experiment of writing a servlet filter 
(it will do me good to learn all this, and I can imagine
other useful things I might do) and if I get something 
that might be useful for others I will let you know.

Richard


On Thu, 2007-06-21 at 17:14 +0200, Rainer Jung wrote:
> I had a similar problem with mod_prox and mod_headers for Apache httpd 
> 2.2 today, and I would expect, that changing the headers with mod_header 
> does not work.
> 
> I see no easy way (but maybe others out there). You could hack
> 
> ajp_unmarshal_response() in common/jk_ajp_common.c.
> 
> Alternative: experiment with a servlet filter for Tomcat. You can always 
> add filters to webapps without changing or even having the webapp code 
> itself.
> 
> Regards,
> 
> Rainer
> 
> Richard Kaye wrote:
> > Hi 
> > 
> > I am using Tomcat5.5, Apache2.2 and mod_jk1.2
> > and a third-part servlet which I can't re-program or
> > configure.
> > 
> > I need to sniff the HTTP "User-Agent" and/or "Accept"
> > fields and change the content-type 
> > (currently "text/html;charset=UTF-8") that the
> > servlet returns based on these.
> > 
> > using mod_headers and mod_setenvif, I currently 
> > have (in my apache2 config) something like:
> > 
> >     SetEnvIf User-Agent Whatever DETECTED1
> >     SetEnvIf Accept Somethingelse DETECTED2
> >     JkMount /servletname/* ajp13_worker
> >     <LocationMatch /servletname/* >
> >         Header set Content-Type "text/xml" env=DETECTED1
> >         Header set Content-Type "application/xml" env=DETECTED2
> >     </LocationMatch>
> > 
> > Unfortunately, it doesn't work. Specifically, I always get the
> > document served as "Content-Type: text/html;charset=UTF-8" 
> > and not "Content-Type: text/xml" as expected. From googling a bit
> > I have learnt that the mod_headers module won't set the Content-Type
> > header, because this one is set internally by apache at a later stage.
> > But I couldn't find a workaround or alternative that does what I want.
> > 
> > Help please!
> > 
> > And many thanks...
> > 
> > Richard
> 
> ---------------------------------------------------------------------
> To start a new topic, e-mail: users@tomcat.apache.org
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
> 


---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: using mod_jk: how to set content-type

Posted by Gregor Schneider <rc...@googlemail.com>.
Had a smiliar problem here.

When using mod_jk, apache does not touch the headers created by Tomcat.

Solution:

I wrote a filter that changed the headers after returning from Tomcat
and installed this filter into Tomcat.

Servlets and filtering (Servlet-Spec 2.3):

http://java.sun.com/products/servlet/Filters.html

My sample-code (setting an Expires-Header):

=============[snip]=======================
package com.cr.manuals.filter;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class for Servlet: HeaderFilter
 *
 */
 public class HeaderFilter implements javax.servlet.Filter {
	
	 private static String PARAM_ADD_TO_CURRENT_MONTH = "ADD_TO_CURRENT_MONTH";
	 private FilterConfig filterConfig = null;
	 private int months2Add = 0;
	 /* (non-Java-doc)
	  * @see javax.servlet.http.HttpServlet#HttpServlet()
	 */
	 public HeaderFilter() {
		 super();
	 }   	 	  	  	

	/**
	* init() : init() method called when the filter is instantiated.
	* This filter is instantiated the first time j_security_check is
	* invoked for the application (When a protected servlet in the
	* application is accessed).
	*/
	public void init(FilterConfig aFilterConfig) throws ServletException {
		filterConfig = aFilterConfig;
		months2Add = Integer.parseInt(filterConfig.getInitParameter(PARAM_ADD_TO_CURRENT_MONTH));
	}

	/**
	* destroy() : destroy() method called when the filter is taken
	* out of service.
	*/
	public void destroy() {
		filterConfig = null;
	}

	/**
	* doFilter() : doFilter() method called before the servlet to
	* which this filteris mapped is invoked. Since this filter is
	* mapped to j_security_check,this method is called before
	* j_security_check action is posted.
	*/
	public void doFilter(ServletRequest aRequest, ServletResponse aResponse,
						FilterChain chain) throws java.io.IOException, ServletException {

	      //System.out.println ("******** filter *******");
	
		  HttpServletRequest request = (HttpServletRequest)aRequest;
	      HttpServletResponse response = (HttpServletResponse)aResponse;
	      // call next filter in the chain : let j_security_check authenticate
	      // user
	      response.setHeader("Expires", createExpiresHeader(months2Add));
	      chain.doFilter(request, response);
	
	}
	/**
	 * Create a String in the format EEE, d MMM yyyy HH:mm:ss z"
	 * Example: Fri, 4 Aug 2006 09:07:44 CEST
	 * The value of the init-parama ADD_TO_CURRENT_MONTH is added to the
	 * month-field of the current date
 	 * @return
	 */
	private String createExpiresHeader(int someMonths2Add) {
		SimpleDateFormat sdf = new SimpleDateFormat("EEE, d MMM yyyy
HH:mm:ss z", Locale.US);
		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.MONTH, someMonths2Add);
		long millis = cal.getTimeInMillis();
		Date d = new Date(millis);
		return sdf.format(d);
	}
}
=============[snap]=======================

HTH

Gregor
-- 
what's puzzlin' you, is the nature of my game
gpgp-fp: 79A84FA526807026795E4209D3B3FE028B3170B2
gpgp-key available @ http://pgpkeys.pca.dfn.de:11371

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: using mod_jk: how to set content-type

Posted by Rainer Jung <ra...@kippdata.de>.
I had a similar problem with mod_prox and mod_headers for Apache httpd 
2.2 today, and I would expect, that changing the headers with mod_header 
does not work.

I see no easy way (but maybe others out there). You could hack

ajp_unmarshal_response() in common/jk_ajp_common.c.

Alternative: experiment with a servlet filter for Tomcat. You can always 
add filters to webapps without changing or even having the webapp code 
itself.

Regards,

Rainer

Richard Kaye wrote:
> Hi 
> 
> I am using Tomcat5.5, Apache2.2 and mod_jk1.2
> and a third-part servlet which I can't re-program or
> configure.
> 
> I need to sniff the HTTP "User-Agent" and/or "Accept"
> fields and change the content-type 
> (currently "text/html;charset=UTF-8") that the
> servlet returns based on these.
> 
> using mod_headers and mod_setenvif, I currently 
> have (in my apache2 config) something like:
> 
>     SetEnvIf User-Agent Whatever DETECTED1
>     SetEnvIf Accept Somethingelse DETECTED2
>     JkMount /servletname/* ajp13_worker
>     <LocationMatch /servletname/* >
>         Header set Content-Type "text/xml" env=DETECTED1
>         Header set Content-Type "application/xml" env=DETECTED2
>     </LocationMatch>
> 
> Unfortunately, it doesn't work. Specifically, I always get the
> document served as "Content-Type: text/html;charset=UTF-8" 
> and not "Content-Type: text/xml" as expected. From googling a bit
> I have learnt that the mod_headers module won't set the Content-Type
> header, because this one is set internally by apache at a later stage.
> But I couldn't find a workaround or alternative that does what I want.
> 
> Help please!
> 
> And many thanks...
> 
> Richard

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org