vmassol 01/07/04 02:17:48
Modified: cactus/src/framework/servlet22/org/apache/commons/cactus/server
HttpServletRequestWrapper.java
cactus/src/framework/servlet23/org/apache/commons/cactus/server
HttpServletRequestWrapper.java
cactus/src/framework/share/org/apache/commons/cactus
ServletURL.java
cactus/src/sample/share/org/apache/commons/cactus/sample/unit
TestServletTestCase2.java TestServletTestCase4.java
Log:
Really corrected the bug with HttpServletRequestWrapper.getRequestDispatcher() in
order to handle relative paths and take into account the simulation URL (if any used).
Also done a bit of refactoring in the ServletURL class.
Revision Changes Path
1.3 +153 -19
jakarta-commons/cactus/src/framework/servlet22/org/apache/commons/cactus/server/HttpServletRequestWrapper.java
Index: HttpServletRequestWrapper.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/cactus/src/framework/servlet22/org/apache/commons/cactus/server/HttpServletRequestWrapper.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- HttpServletRequestWrapper.java 2001/07/03 12:12:58 1.2
+++ HttpServletRequestWrapper.java 2001/07/04 09:17:21 1.3
@@ -62,6 +62,7 @@
import javax.servlet.http.*;
import org.apache.commons.cactus.*;
+import org.apache.commons.cactus.util.log.*;
/**
* Encapsulation class for the Servlet 2.2 API <code>HttpServletRequest</code>.
@@ -89,6 +90,12 @@
private ServletURL m_URL;
/**
+ * The logger
+ */
+ private static Log m_Logger =
+ LogService.getInstance().getLog(HttpServletRequestWrapper.class.getName());
+
+ /**
* Construct an <code>HttpServletRequest</code> instance that delegates
* it's method calls to the request object passed as parameter and that
* uses the URL passed as parameter to simulate a URL from which the request
@@ -129,10 +136,19 @@
*/
public String getContextPath()
{
+ m_Logger.entry("getContextPath()");
+
+ String result = m_Request.getContextPath();
+
if (m_URL != null) {
- return m_URL.getContextPath();
+ if (m_URL.getContextPath() != null) {
+ result = m_URL.getContextPath();
+ m_Logger.debug("Using simulated context : [" + result + "]");
+ }
}
- return m_Request.getContextPath();
+
+ m_Logger.exit("getContextPath");
+ return result;
}
public String getScheme()
@@ -146,10 +162,17 @@
*/
public String getPathInfo()
{
+ m_Logger.entry("getPathInfo()");
+
+ String result = m_Request.getPathInfo();
+
if (m_URL != null) {
- return m_URL.getPathInfo();
+ result = m_URL.getPathInfo();
+ m_Logger.debug("Using simulated PathInfo : [" + result + "]");
}
- return m_Request.getPathInfo();
+
+ m_Logger.exit("getPathInfo");
+ return result;
}
public String getAuthType()
@@ -163,10 +186,19 @@
*/
public String getServerName()
{
+ m_Logger.entry("getServerName()");
+
+ String result = m_Request.getServerName();
+
if (m_URL != null) {
- return m_URL.getURL().getHost();
+ if (m_URL.getServerName() != null) {
+ result = m_URL.getHost();
+ m_Logger.debug("Using simulated server name : [" + result + "]");
+ }
}
- return m_Request.getServerName();
+
+ m_Logger.exit("getServerName");
+ return result;
}
public String getRealPath(String thePath)
@@ -206,13 +238,17 @@
*/
public int getServerPort()
{
+ m_Logger.entry("getServerPort()");
+
+ int result = m_Request.getServerPort();
+
if (m_URL != null) {
- if (m_URL.getURL().getPort() == -1) {
- return 80;
- }
- return m_URL.getURL().getPort();
+ result = (m_URL.getPort() == -1) ? 80 : m_URL.getPort();
+ m_Logger.debug("Using simulated server port : [" + result + "]");
}
- return m_Request.getServerPort();
+
+ m_Logger.exit("getServerPort");
+ return result;
}
public BufferedReader getReader() throws IOException
@@ -231,10 +267,21 @@
*/
public String getRequestURI()
{
+ m_Logger.entry("getRequestURI()");
+
+ String result = m_Request.getRequestURI();
+
if (m_URL != null) {
- return m_URL.getURL().getFile();
+
+ result = getContextPath() +
+ ((getServletPath() == null) ? "" : getServletPath()) +
+ ((getPathInfo() == null) ? "" : getPathInfo());
+
+ m_Logger.debug("Using simulated request URI : [" + result + "]");
}
- return m_Request.getRequestURI();
+
+ m_Logger.exit("getRequestURI");
+ return result;
}
public String[] getParameterValues(String theName)
@@ -273,10 +320,17 @@
*/
public String getServletPath()
{
+ m_Logger.entry("getServletPath()");
+
+ String result = m_Request.getServletPath();
+
if (m_URL != null) {
- return m_URL.getServletPath();
+ result = m_URL.getServletPath();
+ m_Logger.debug("Using simulated servlet path : [" + result + "]");
}
- return m_Request.getServletPath();
+
+ m_Logger.exit("getServletPath");
+ return result;
}
public boolean isRequestedSessionIdFromCookie()
@@ -350,10 +404,17 @@
*/
public String getQueryString()
{
+ m_Logger.entry("getQueryString()");
+
+ String result = m_Request.getQueryString();
+
if (m_URL != null) {
- return m_URL.getQueryString();
+ result = m_URL.getQueryString();
+ m_Logger.debug("Using simulated query string : [" + result + "]");
}
- return m_Request.getQueryString();
+
+ m_Logger.exit("getQueryString");
+ return result;
}
public long getDateHeader(String theName)
@@ -394,9 +455,82 @@
* mechanism introduced by Servlet 2.3 Filters].
*/
public RequestDispatcher getRequestDispatcher(String thePath)
+ {
+ m_Logger.entry("getRequestDispatcher([" + thePath + "])");
+
+ // I hate it, but we have to write some logic here ! Ideally we
+ // shouldn't have to do this as it is supposed to be done by the servlet
+ // engine. However as we are simulating the request URL, we have to
+ // provide it ... This is where we can see the limitation of Cactus
+ // (it has to mock some parts of the servlet engine) !
+
+ if (thePath == null) {
+ m_Logger.exit("getRequestDispatcher");
+ return null;
+ }
+
+ RequestDispatcher dispatcher = null;
+ String fullPath;
+
+ // The spec says that the path can be relative, in which case it will
+ // be relative to the request. So for relative paths, we need to take
+ // into account the simulated URL (ServletURL).
+ if (thePath.startsWith("/")) {
+
+ fullPath = thePath;
+
+ } else {
+
+ String pI = getPathInfo();
+ if (pI == null) {
+ fullPath = catPath(getServletPath(), thePath);
+ } else {
+ fullPath = catPath(getServletPath() + pI, thePath);
+ }
+
+ if (fullPath == null) {
+ m_Logger.exit("getRequestDispatcher");
+ return null;
+ }
+ }
+
+ m_Logger.debug("Computed full path : [" + fullPath + "]");
+
+ dispatcher = new RequestDispatcherWrapper(
+ m_Request.getRequestDispatcher(fullPath));
+
+ m_Logger.exit("getRequestDispatcher");
+ return dispatcher;
+ }
+
+ /**
+ * Will concatenate 2 paths, dealing with ..
+ * ( /a/b/c + d = /a/b/d, /a/b/c + ../d = /a/d ). Code borrowed from
+ * Tomcat 3.2.2 !
+ *
+ * @return null if error occurs
+ */
+ private String catPath(String lookupPath, String path)
{
- return new RequestDispatcherWrapper(
- m_Request.getRequestDispatcher(thePath));
+ // Cut off the last slash and everything beyond
+ int index = lookupPath.lastIndexOf("/");
+ lookupPath = lookupPath.substring(0, index);
+
+ // Deal with .. by chopping dirs off the lookup path
+ while (path.startsWith("../")) {
+ if (lookupPath.length() > 0) {
+ index = lookupPath.lastIndexOf("/");
+ lookupPath = lookupPath.substring(0, index);
+ } else {
+ // More ..'s than dirs, return null
+ return null;
+ }
+
+ index = path.indexOf("../") + 3;
+ path = path.substring(index);
+ }
+
+ return lookupPath + "/" + path;
}
public Cookie[] getCookies()
1.3 +114 -19
jakarta-commons/cactus/src/framework/servlet23/org/apache/commons/cactus/server/HttpServletRequestWrapper.java
Index: HttpServletRequestWrapper.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/cactus/src/framework/servlet23/org/apache/commons/cactus/server/HttpServletRequestWrapper.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- HttpServletRequestWrapper.java 2001/07/03 12:13:05 1.2
+++ HttpServletRequestWrapper.java 2001/07/04 09:17:30 1.3
@@ -62,6 +62,7 @@
import javax.servlet.http.*;
import org.apache.commons.cactus.*;
+import org.apache.commons.cactus.util.log.*;
/**
* Encapsulation class for the Servlet 2.3 API <code>HttpServletRequest</code>.
@@ -88,6 +89,12 @@
private ServletURL m_URL;
/**
+ * The logger
+ */
+ private static Log m_Logger =
+ LogService.getInstance().getLog(HttpServletRequestWrapper.class.getName());
+
+ /**
* Construct an <code>HttpServletRequest</code> instance that delegates
* it's method calls to the request object passed as parameter and that
* uses the URL passed as parameter to simulate a URL from which the request
@@ -152,10 +159,17 @@
*/
public String getServletPath()
{
+ m_Logger.entry("getServletPath()");
+
+ String result = m_Request.getServletPath();
+
if (m_URL != null) {
- return m_URL.getServletPath();
+ result = m_URL.getServletPath();
+ m_Logger.debug("Using simulated servlet path : [" + result + "]");
}
- return m_Request.getServletPath();
+
+ m_Logger.exit("getServletPath");
+ return result;
}
public String getRequestedSessionId()
@@ -174,10 +188,21 @@
*/
public String getRequestURI()
{
+ m_Logger.entry("getRequestURI()");
+
+ String result = m_Request.getRequestURI();
+
if (m_URL != null) {
- return m_URL.getURL().getFile();
+
+ result = getContextPath() +
+ ((getServletPath() == null) ? "" : getServletPath()) +
+ ((getPathInfo() == null) ? "" : getPathInfo());
+
+ m_Logger.debug("Using simulated request URI : [" + result + "]");
}
- return m_Request.getRequestURI();
+
+ m_Logger.exit("getRequestURI");
+ return result;
}
public String getRemoteUser()
@@ -191,10 +216,17 @@
*/
public String getQueryString()
{
+ m_Logger.entry("getQueryString()");
+
+ String result = m_Request.getQueryString();
+
if (m_URL != null) {
- return m_URL.getQueryString();
+ result = m_URL.getQueryString();
+ m_Logger.debug("Using simulated query string : [" + result + "]");
}
- return m_Request.getQueryString();
+
+ m_Logger.exit("getQueryString");
+ return result;
}
public String getPathTranslated()
@@ -208,10 +240,17 @@
*/
public String getPathInfo()
{
+ m_Logger.entry("getPathInfo()");
+
+ String result = m_Request.getPathInfo();
+
if (m_URL != null) {
- return m_URL.getPathInfo();
+ result = m_URL.getPathInfo();
+ m_Logger.debug("Using simulated PathInfo : [" + result + "]");
}
- return m_Request.getPathInfo();
+
+ m_Logger.exit("getPathInfo");
+ return result;
}
public String getMethod()
@@ -255,10 +294,19 @@
*/
public String getContextPath()
{
+ m_Logger.entry("getContextPath()");
+
+ String result = m_Request.getContextPath();
+
if (m_URL != null) {
- return m_URL.getContextPath();
+ if (m_URL.getContextPath() != null) {
+ result = m_URL.getContextPath();
+ m_Logger.debug("Using simulated context : [" + result + "]");
+ }
}
- return m_Request.getContextPath();
+
+ m_Logger.exit("getContextPath");
+ return result;
}
public String getAuthType()
@@ -293,13 +341,17 @@
*/
public int getServerPort()
{
+ m_Logger.entry("getServerPort()");
+
+ int result = m_Request.getServerPort();
+
if (m_URL != null) {
- if (m_URL.getURL().getPort() == -1) {
- return 80;
- }
- return m_URL.getURL().getPort();
+ result = (m_URL.getPort() == -1) ? 80 : m_URL.getPort();
+ m_Logger.debug("Using simulated server port : [" + result + "]");
}
- return m_Request.getServerPort();
+
+ m_Logger.exit("getServerPort");
+ return result;
}
/**
@@ -308,10 +360,19 @@
*/
public String getServerName()
{
+ m_Logger.entry("getServerName()");
+
+ String result = m_Request.getServerName();
+
if (m_URL != null) {
- return m_URL.getURL().getHost();
+ if (m_URL.getServerName() != null) {
+ result = m_URL.getHost();
+ m_Logger.debug("Using simulated server name : [" + result + "]");
+ }
}
- return m_Request.getServerName();
+
+ m_Logger.exit("getServerName");
+ return result;
}
public String getScheme()
@@ -328,8 +389,42 @@
*/
public RequestDispatcher getRequestDispatcher(String thePath)
{
- return new RequestDispatcherWrapper(
- m_Request.getRequestDispatcher(thePath));
+ m_Logger.entry("getRequestDispatcher([" + thePath + "])");
+
+ // I hate it, but we have to write some logic here ! Ideally we
+ // shouldn't have to do this as it is supposed to be done by the servlet
+ // engine. However as we are simulating the request URL, we have to
+ // provide it ... This is where we can see the limitation of Cactus
+ // (it has to mock some parts of the servlet engine) !
+
+ if (thePath == null) {
+ m_Logger.exit("getRequestDispatcher");
+ return null;
+ }
+
+ RequestDispatcher dispatcher = null;
+ String fullPath;
+
+ // The spec says that the path can be relative, in which case it will
+ // be relative to the request. So for relative paths, we need to take
+ // into account the simulated URL (ServletURL).
+ if (thePath.startsWith("/")) {
+
+ fullPath = thePath;
+
+ } else {
+
+ fullPath = getServletPath() + "/../" + thePath;
+
+ }
+
+ m_Logger.debug("Computed full path : [" + fullPath + "]");
+
+ dispatcher = new RequestDispatcherWrapper(
+ m_Request.getRequestDispatcher(fullPath));
+
+ m_Logger.exit("getRequestDispatcher");
+ return dispatcher;
}
public String getRemoteHost()
1.2 +58 -38
jakarta-commons/cactus/src/framework/share/org/apache/commons/cactus/ServletURL.java
Index: ServletURL.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/cactus/src/framework/share/org/apache/commons/cactus/ServletURL.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ServletURL.java 2001/04/09 11:52:36 1.1
+++ ServletURL.java 2001/07/04 09:17:37 1.2
@@ -62,6 +62,7 @@
import javax.servlet.http.*;
import junit.framework.*;
+import org.apache.commons.cactus.util.log.*;
/**
* Simulate an HTTP URL by breaking it into its different parts :<br>
@@ -145,10 +146,10 @@
private String m_URL_QueryString;
/**
- * The full URL (useful later because we can benefit from the all
- * methods of the <code>URL</code> class.
+ * The logger
*/
- private URL m_FullURL;
+ private static Log m_Logger =
+ LogService.getInstance().getLog(ServletURL.class.getName());
/**
* Creates the URL to simulate.
@@ -156,11 +157,15 @@
* @param theServerName the server name (and port) in the URL to simulate,
* i.e. this is the name that will be returned by the
* <code>HttpServletRequest.getServerName()</code> and
- * <code>HttpServletRequest.getServerPort()</code>.
+ * <code>HttpServletRequest.getServerPort()</code>. Can
+ * be null. If null, then the server name and port from
+ * the Servlet Redirector will be returned.
* @param theContextPath the webapp context path in the URL to simulate,
* i.e. this is the name that will be returned by the
* <code>HttpServletRequest.getContextPath()</code>.
- * Can be null. Format: "/" + name or an empty string
+ * Can be null. If null, then the context from the
+ * Servlet Redirector will be returned.
+ * Format: "/" + name or an empty string
* for the default context.
* @param theServletPath the servlet path in the URL to simulate,
* i.e. this is the name that will be returned by the
@@ -178,53 +183,57 @@
public ServletURL(String theServerName, String theContextPath, String
theServletPath,
String thePathInfo, String theQueryString)
{
- if (theServerName == null) {
- throw new AssertionFailedError("Bad URL. The server name cannot be
null");
- }
-
m_URL_ServerName = theServerName;
- m_URL_ContextPath = (theContextPath == null) ? "" : theContextPath;
+ m_URL_ContextPath = theContextPath;
m_URL_ServletPath = theServletPath;
m_URL_PathInfo = thePathInfo;
m_URL_QueryString = theQueryString;
-
- // create a full URL
- String fullURL = "http://" + m_URL_ServerName;
- if (m_URL_ContextPath.length() != 0) {
- fullURL = fullURL + m_URL_ContextPath;
- }
- if ((m_URL_ServletPath != null) && (m_URL_ServletPath.length() != 0)) {
- fullURL = fullURL + m_URL_ServletPath;
- }
- if ((m_URL_PathInfo != null) && (m_URL_PathInfo.length() != 0)) {
- fullURL = fullURL + m_URL_PathInfo;
- }
-
- try {
- m_FullURL = new URL(fullURL);
- } catch (MalformedURLException e) {
- throw new AssertionFailedError("Bad URL [" + fullURL + "]");
- }
-
}
/**
- * @return the full URL as a <code>URL</code> object.
+ * @return the simulated URL server name (including the port number)
*/
- public URL getURL()
+ public String getServerName()
{
- return m_FullURL;
+ return m_URL_ServerName;
}
/**
- * @return the simulated URL server name (including the port number)
+ * @return the simulated URL server name (excluding the port number)
*/
- public String getServerName()
+ public String getHost()
{
+ int pos = m_URL_ServerName.indexOf(":");
+ if (pos > 0) {
+ return m_URL_ServerName.substring(0, pos + 1);
+ }
+
return m_URL_ServerName;
}
/**
+ * @return the port number or -1 if none has been defined or it is a bad
+ * port
+ */
+ public int getPort()
+ {
+ int pos = m_URL_ServerName.indexOf(":");
+ int result;
+
+ if (pos < 0) {
+ return -1;
+ }
+
+ try {
+ result = Integer.parseInt(m_URL_ServerName.substring(pos + 1));
+ } catch (NumberFormatException e) {
+ return -1;
+ }
+
+ return result;
+ }
+
+ /**
* @return the simulated URL context path
*/
public String getContextPath()
@@ -288,17 +297,28 @@
*/
public static ServletURL loadFromRequest(HttpServletRequest theRequest)
{
+ m_Logger.entry("loadFromRequest(...)");
+
String serverName = theRequest.getParameter(URL_SERVER_NAME_PARAM);
+ m_Logger.debug("serverName = [" + serverName + "]");
+
String contextPath = theRequest.getParameter(URL_CONTEXT_PATH_PARAM);
+ m_Logger.debug("contextPath = [" + contextPath + "]");
+
String servletPath = theRequest.getParameter(URL_SERVLET_PATH_PARAM);
+ m_Logger.debug("servletPath = [" + servletPath + "]");
+
String pathInfo = theRequest.getParameter(URL_PATH_INFO_PARAM);
+ m_Logger.debug("pathInfo = [" + pathInfo + "]");
+
String queryString = theRequest.getParameter(URL_QUERY_STRING_PARAM);
+ m_Logger.debug("queryString = [" + queryString + "]");
- if (serverName != null) {
- return new ServletURL(serverName, contextPath, servletPath, pathInfo,
queryString);
- }
+ ServletURL url = new ServletURL(serverName, contextPath,
+ servletPath, pathInfo, queryString);
- return null;
+ m_Logger.entry("loadFromRequest(...)");
+ return url;
}
}
1.6 +55 -3
jakarta-commons/cactus/src/sample/share/org/apache/commons/cactus/sample/unit/TestServletTestCase2.java
Index: TestServletTestCase2.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/cactus/src/sample/share/org/apache/commons/cactus/sample/unit/TestServletTestCase2.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- TestServletTestCase2.java 2001/07/03 12:13:12 1.5
+++ TestServletTestCase2.java 2001/07/04 09:17:42 1.6
@@ -395,13 +395,65 @@
//-------------------------------------------------------------------------
/**
- * Verify that request.getRequestDispatcher() works properly and can include
- * another page.
+ * Verify that request.getRequestDispatcher() works properly with an
+ * absolute path
*/
- public void testGetRequestDispatcherFromRequest() throws ServletException,
IOException
+ public void testGetRequestDispatcherFromRequest1() throws ServletException,
IOException
{
RequestDispatcher rd = request.getRequestDispatcher("/test/test.jsp");
rd.include(request, response);
+ }
+
+ /**
+ * Verify that request.getRequestDispatcher() works properly with an
+ * absolute path
+ *
+ * @param theConnection the HTTP connection that was used to call the
+ * server redirector. It contains the returned HTTP
+ * response.
+ */
+ public void endGetRequestDispatcherFromRequest1(HttpURLConnection
theConnection) throws IOException
+ {
+ String result = AssertUtils.getResponseAsString(theConnection);
+ assert("Page not found, got [" + result + "]", result.indexOf("Hello !") >
0);
+ }
+
+ //-------------------------------------------------------------------------
+
+ /**
+ * Verify that request.getRequestDispatcher() works properly with a
+ * relative path.
+ *
+ * @param theRequest the request object that serves to initialize the
+ * HTTP connection to the server redirector.
+ */
+ public void beginGetRequestDispatcherFromRequest2(ServletTestRequest theRequest)
+ {
+ theRequest.setURL(null, "/test", "/anything.jsp", null, null);
+ }
+
+ /**
+ * Verify that request.getRequestDispatcher() works properly with a
+ * relative path.
+ */
+ public void testGetRequestDispatcherFromRequest2() throws ServletException,
IOException
+ {
+ RequestDispatcher rd = request.getRequestDispatcher("test/test.jsp");
+ rd.include(request, response);
+ }
+
+ /**
+ * Verify that request.getRequestDispatcher() works properly with a
+ * relative path.
+ *
+ * @param theConnection the HTTP connection that was used to call the
+ * server redirector. It contains the returned HTTP
+ * response.
+ */
+ public void endGetRequestDispatcherFromRequest2(HttpURLConnection
theConnection) throws IOException
+ {
+ String result = AssertUtils.getResponseAsString(theConnection);
+ assert("Page not found, got [" + result + "]", result.indexOf("Hello !") >
0);
}
}
1.3 +2 -2
jakarta-commons/cactus/src/sample/share/org/apache/commons/cactus/sample/unit/TestServletTestCase4.java
Index: TestServletTestCase4.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/cactus/src/sample/share/org/apache/commons/cactus/sample/unit/TestServletTestCase4.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- TestServletTestCase4.java 2001/06/28 21:27:00 1.2
+++ TestServletTestCase4.java 2001/07/04 09:17:43 1.3
@@ -111,14 +111,14 @@
/**
* Verify that we can simulate the basic parts of the URL : server name,
- * default server port of 80, no servlet context, URI.
+ * default server port of 80, root servlet context, URI.
*
* @param theRequest the request object that serves to initialize the
* HTTP connection to the server redirector.
*/
public void beginSimulatedURLBasics(ServletTestRequest theRequest)
{
- theRequest.setURL("jakarta.apache.org", null, "/test/test.jsp", null, null);
+ theRequest.setURL("jakarta.apache.org", "", "/test/test.jsp", null, null);
}
/**