Bug 33693

Summary: <input:form> action parameter causes errors in WSRP portlets
Product: Taglibs Reporter: David Valeri <valeri_david>
Component: Input TaglibAssignee: Tomcat Developers Mailing List <dev>
Status: RESOLVED FIXED    
Severity: normal    
Priority: P2    
Version: nightly   
Target Milestone: ---   
Hardware: All   
OS: Windows XP   

Description David Valeri 2005-02-22 17:08:06 UTC
Using the <input:form> tag in a WSRP portlet interferes with URL rewriting and
renders the rewrite formatting invalid on the WSRP consumer.

The rewrite-encoded URL is passed to the HttpServletResponse.encodeURL() method
which interferes with the specially formatted URL.
Comment 1 David Valeri 2005-02-22 17:13:59 UTC
(In reply to comment #0)
> Using the <input:form> tag in a WSRP portlet interferes with URL rewriting and
> renders the rewrite formatting invalid on the WSRP consumer.

To clarify: renders the rewrite formatting on the action parameter invalid.

Apologies for the ambiguity.

Comment 2 Karl von Randow 2005-02-22 20:08:16 UTC
The action attribute on the form tag is passed through encodeURL() before 
being output on the page. Do you mean that you're already putting an 
encodedURL into the action attribute on the page, and that the double encoding 
is the problem?
Comment 3 David Valeri 2005-02-22 21:08:43 UTC
Here is the scenario under which the issue occurs.

A JSR-168 Portlet uses a JSP to render its output. The JSP employs the
<input:form> tag to assist in the generation of a prepopulated form. The form is
to submit back to the portlet that is displaying the form. In order to do so,
the form's action URL must be generated using the portlet taglib or from a
RenderResponse. In the event that the portlet is exposed through WSRP, the URL
is specially encoded to enable client side URL rewriting (See the OASIS WSRP 1.0
Specification for more details on URL rewriting). The special encoding is
provided by the portlet container and is provided in the output of the portlet
taglib or the RenderResponse.createActionURL() method. When this specially
encoded URL is sent through the HttpServletResponse.encodeURL() method, the
rewrite encoding is destroyed and the URL becomes invalid to the WSRP consumer
when it is invoked.

Since the portlet container is responsible for properly encoding the URL
(regardless of the use of WSRP), the HTTPServletResponse.endodeURL() has the
potential to interfere with an already valid URL. To avoid this issue the taglib
would need to check if the current request is indeed a render request for a
portlet. In short, it is indeed the double encoding that is causing the problem,
but the situation is unavoidable when creating URLs for a JSR-168 portlet.
Comment 4 Kris Schneider 2005-02-22 21:54:30 UTC
Maybe I'm missing something, but using <input:form> just doesn't make sense in
this instance. Portlet 1.0 implies Servlet 2.3 which supports JSP 1.2 which
supports JSTL 1.0. So, I assume you can do something like:

<%@ taglib prefix="c"       uri="http://java.sun.com/jstl/core" %>
<%@ taglib prefix="portlet" uri="http://java.sun.com/portlet"   %>

<portlet:actionURL var="formAction" portletMode="edit"/>

<form action="<c:out value="${formAction}" escapeXml="false"/>" ...>
  ...
</form>

As well as using JSTL to dynamically add other attributes to the <form> element
as needed...
Comment 5 Kris Schneider 2005-02-22 22:02:57 UTC
Ahem, it looks like the simple case (no params for <portlet:actionURL>) could
just be:

<%@ taglib prefix="portlet" uri="http://java.sun.com/portlet" %>

<form action="<portlet:actionURL portletMode="edit"/>" ...>
  ...
</form>

Anyway, you get the idea...
Comment 6 Karl von Randow 2005-02-23 01:55:32 UTC
I imagine that there are still benefits to using the input taglib. In terms of 
a possible solution:

I'm not sure if it's possible or wise to detect automatically whether the URL 
has been through the encoding process already. Perhaps the best alternative is 
to provide another attribute to the form tag to turn off encoding?
Comment 7 Karl von Randow 2007-04-22 01:12:18 UTC
I have added an encodeActionURL attribute to the form tag. This defaults to true but can be set to false to 
turn off the response.encodeURL(). Note that the action parameter now has HTML entities encoded inline 
with the rest of the taglib.