Bug 21924

Summary: <c:import> with relative URL ignores content encoding of resource
Product: Taglibs Reporter: Willis Boyce <wboyce>
Component: Standard TaglibAssignee: Tomcat Developers Mailing List <dev>
Status: RESOLVED INVALID    
Severity: normal    
Priority: P3    
Version: unspecified   
Target Milestone: ---   
Hardware: PC   
OS: other   

Description Willis Boyce 2003-07-28 05:26:55 UTC
I belive that I have found a bug in the <c:import> tag in Standard 1.0.3.  
Feel free to tell me that I'm wrong, but please explain why.

I have a web application with JSPs that include other JSPs using the 
<c:import> tag.  I am using Orion 2.0.2 as my application server.

I deploy this application on two web sites, one of which is in English and the 
other of which is in Korean.  For historical reasons, I need to serve the 
pages on the English site using ISO-8859-1.  However, I serve the pages on the 
Korean site using UTF-8.  In order to faciliate serving the pages using ISO-
8859-1 on the English site and using UTF-8 on the Korean site, none of the JSP 
pages specify a content type or a charset.  Instead, I specify the default 
charset in the Orion configuration.  Setting the default charset in the Orion 
configuration causes Orion to use that charset when creating Writer and Reader 
instances, enabling my application to both send pages to the browser and 
receive request parameters from the browser using the specified charset.

Here is what happens when Orion is configured to use UTF-8 as the default 
charset and I attempt to import a relative JSP page using <c:import 
url="/the/relative/page.jsp">.  Because the page is local, <c:import> follows 
some shortcut logic that avoids the creation of a URL and handles the import 
by passing a response wrapper to the local request dispatcher.  Calling the 
request dispatcher passes control to Orion.  A few cycles later, Orion calls 
getOutputStream on the response wrapper and wraps the output stream in a 
Writer that uses UTF-8.  The imported JSP writes to this Writer.  Once the 
imported JSP returns, <c:import> invokes getString on the response wrapper.  
If Orion had called getWriter on the response wrapper, then no character/byte 
translation would have taken place, and the encoding of the Writer would have 
been irrelevant.  But since Orion called getOutputStream on the response 
wrapper, the wrapper only has access to the bytes written to the stream, and 
the getString method must decode them back into characters in order to 
construct a String to return.  Here is where things go wrong.  Although the 
characters from the imported JSP were encoded using UTF-8, because the 
<c:import> tag has no charEncoding attribute, the getString method decodes 
them as ISO-8859-1, and of course, they are incorrect.

This behavior seems inconsistent with the way that <c:import> would work if it 
did not use the request dispatcher.  If I wrote <c:import 
url="http://www.myserver.com/the/relative/page.jsp">, then <c:import> would 
note the content encoding of the resource and instantiate an appropriate 
Reader.  I think that it would make sense for the response wrapper that 
<c:import> passes to the response wrapper to pay attention to any calls to its 
setContentType method and use that information when decoding the bytes from 
the output stream.
Comment 1 Felipe Leme 2003-08-22 05:05:48 UTC
>Although the 
>characters from the imported JSP were encoded using UTF-8, because the 
><c:import> tag has no charEncoding attribute, the getString method decodes 
>them as ISO-8859-1, and of course, they are incorrect.

Hi Wills,

Sorry if I didn't understand correctly your problem, but have you tried to set
the charEncoding attribute to UTF-8? If so, did it work this way?

Felipe
Comment 2 Pierre Delisle 2004-01-14 21:18:58 UTC
My head hurts, but I finally think I understand your problem :-)

Orion uses the OutputStream of c:import's ResponseWrapper and you'd
like the following two things to happen:

   1. calling setContentType() on the ResponseWrapper should not be ignored
   2. getString() on the ResponseWrapper should take into consideration
      the contentType that may have been set by (1).

However, the JSTL spec is quite clear in section 7.4 that 
relative URLs in the same context are processed in the
same way as the include action of the JSP spec.

And the JSP spec clearly states that:

  An included page cannot change the response status code or set headers. 
  This precludes invoking methods like setCookie. Attempts to invoke 
  these methods will be ignored.

A quick look at Jasper in Tomcat shows that the ResponseWrapper used
in a <jsp:include> action even throws an exception if getOutputStream()
is called. We should probably do that as well in JSTL for <c:import> 
of a relative URL to be consistent with <jsp:include>.

At any rate, I don't think there is anything we can do for the problem
you've stated in this bug report. If you think otherwise, we'll be
happy to consider your counter arguments.