tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Hammon, Randy" <RHam...@Evolve.com>
Subject jsp:include: the bug and the fix
Date Wed, 28 Jun 2000 22:19:58 GMT
Hello,
this is my first message to the list. Hope I'm going about this in the right
way.

Here at Evolve we've encountered a jsp:include bug (we think it's a bug) in
the Tomcat 3.1 release.
Vance Maverick and myself downloaded the source code, did some debugging,
and Vance
found what we believe is the bug and the fix.

Scenario
------------
Given the following 2 jsp files and servlet( putting all three in a
directory
named /test and doing what you need so that Tomcat can find it) to invoke
them:

Outer.jsp
----------
html>
<head>
<title>Include test</title>
</head>
<body>
This is a test of forwarding and inclusion.  For some reason, it's not
working right for us with Tomcat.

<p>
<jsp:include page="/test/Inner.jsp" flush="true" />
</body>
</html>
----------

Inner.jsp
-----------
This is an inner file included via &lt;jsp:include&gt;.
----------

and the servlet to invoke them.

test.Test.java
----------------
package test;
import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.*;
/**
 *  Simplest possible test of problem configuration:
 *  servlet forwards request to JSP, JSP includes another.
 */
public class Test
    extends HttpServlet
{
    public void doGet(HttpServletRequest request,
                      HttpServletResponse response)
        throws ServletException, IOException
    {
        RequestDispatcher rd =
 
this.getServletContext().getRequestDispatcher("/test/Outer.jsp");
        rd.forward(request, response);
    }

}
----------------

If you run this scenario in the 3.1 Tomcat release, Outer.jsp will blow up
on the jsp:include line.
What appears to be happening is that the ContextManager creates a context
for Outer.jsp, then when it creates a context for
inner.jsp, it finds it already has a context from Outer.jsp and a context
path, /test, so it uses it, and some code thinks it's supposed to prepend
/test to the /test/Inner.jsp url in the jsp:include statement. We think that
it should NOT do this, since /test/Inner.jsp is an absolute 
path. Here's the code in class org.apache.tomcat.core.ContextManager, in the
method createRequest(Context ctx, String urlPath).  
The implementation looks like this:  

    Request createRequest( Context ctx, String urlPath ) {
	// assert urlPath!=null

	// deal with paths with parameters in it
	String contextPath=ctx.getPath();
	String origPath=urlPath;

	// BEGIN DEBUG STUFF
	System.err.println("contextPath = " + contextPath +
	                   ", origPath = " + origPath);
	// END DEBUG STUFF

	// append context path
	if( !"".equals(contextPath) && !"/".equals(contextPath)) {

	// BEGIN HERE IS THE CODE WE THINK IS WRONG
	    if( urlPath.startsWith("/" ) )
		urlPath=contextPath + urlPath;
	    else
		urlPath=contextPath + "/" + urlPath;
	// END HERE IS THE CODE WE THINK IS WRONG

	} else {
	    // root context
	    if( !urlPath.startsWith("/" ) )
		urlPath= "/" + urlPath;
	}

	if( debug >4 ) log("createRequest " + origPath + " " + urlPath  );
	return createRequest( urlPath );
    }

The code surrounded by //HERE IS THE CODE WE THINK IS WRONG 
is our debug code.  For Outer.jsp, we see
	contextPath = , origPath = /test/Outer.jsp
and for Inner.jsp, we see
	contextPath = /test, origPath = /test/Inner.jsp
In themselves, we think these values are fine.  The context really is
different: in one case we're coming from the servlet, in the other from
/test/Outer.jsp.  However, the logic surrounded by
//HERE IS THE CODE WE THINK IS WRONG means that an origPath beginning with a
slash, such as /test/Inner.jsp, won't be interpreted as absolute: no urlPath
will ever cause this method to throw away the contextPath and start from
"root". When we replaced the logic with

	// END DEBUG STUFF
	// append context path
	if( !"".equals(contextPath) && !"/".equals(contextPath)) {

	// BEGIN HERE IS THE FIX
	    if( urlPath.startsWith("/" ) )
		{} // leave it alone, it's absolute
	    else
		urlPath=contextPath + "/" + urlPath;
	// BEGIN HERE IS THE FIX

It then worked in our application as we think it should.

If this is a correct fix, what is the procedure for getting into Tomcat?
Also, are there any regression tests for us to run (it works for our
product which uses lots of dynamic jsp includes (jsp:include)? Finally, what
are the rules about using our fix with Tomcat?


Thanks,
-Randy Hammon
Engineer and TranceMaster

Evolve Software
615 Battery St.
San Francisco, CA 94111
415-445-5116

Mime
View raw message