You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by Sebastian Bub <bu...@novedia.de> on 2002/04/01 21:05:24 UTC

Redirect problem using Struts in WebSphere 4.0.x

Hi,

Don has had a problem with redirecting using WebSphere 4.0.2
http://www.mail-archive.com/struts-user@jakarta.apache.org/msg24852.html
where the contextRoot-name was added twice to the url.

We have had the same trouble (WebSphere Advanced Server Edition 4.0.x and
Advanced Single Server Edition 4.0.x). To me, it is a little bit funny
because I thought that they are using a Tomcat base.

Anyway, I tracked this error far down and in my opinion it is a struts bug
because someone depended on the knowledge of implementation of the method
response.encodeRedirectURL within Tomcat.

Within the method processActionForward (in class
org.apache.struts.action.ActionServlet (older struts-version) or from the
nightly build of today in class org.apache.struts.action.RequestProcessor)
there is the following call
response.sendRedirect(response.encodeRedirectURL(path));
which returns different values within different application servers.

If you look into the documentation of Interface
javax.servlet.http.HttpServletResponse.encodeRedirectURL(java.lang.String
url)
the method takes a String parameter named url. Within the method
processActionForward a variable named path is given. So, actually it is a
little bit dirty of the interface to take a String instead of an
java.net.URL.

In my opinion, WebSphere is handling the "path" correctly. Actually, it is
trying to be more helpful (which causes the error) than it needs to be
(adding the contextRoot to the path) where the following lines within
processActionForward do not correspond to WebSphere implementation:
if (forward.getRedirect()) {
  if (path.startsWith("/")) {
    if (forward.getContextRelative()) {
      path = request.getContextPath() + path;
    ...

Therefore I have patched the above line:

response.sendRedirect(response.encodeRedirectURL(toAbsolute(request,
path)));


The implementation of toAbsolute is partly copied from Tomcat sources and
now it is NOT really nice (because of my https-hack), but the functionality
of the URL-constructor is really nice and the java.net.URL class does not
handle https (you can do it better if you want to, but during this state of
url handling no one cares about the actual protocol). One more thing: I did
not give the implementation of replaceStr but I am sure you can imagine
what it is doing:

private String toAbsolute(HttpServletRequest request, String path){
	String requrl = javax.servlet.http.HttpUtils.getRequestURL
(request).toString();
	String respurl = null;
	URL url = null;
	boolean needsHttpsToggle = false;

	try {
		// class URL does not handle https, but functionality of
building absolute
		// URL is really nice, therefore we toggle to http
		if(requrl != null && "https://".regionMatches(true, 0,
requrl, 0, 8)){
			requrl = Utils.replaceStr(requrl, requrl.substring
(0, 8), "http://");
			needsHttpsToggle = true;
		}
		url = new URL(new URL(requrl), path);
		respurl = url.toString();
		if(needsHttpsToggle)  // if needed, toggle back to https
			respurl = Utils.replaceStr(respurl,
respurl.substring(0, 7), "https://");
		if (debug >= 1)
			log("PATCH DEBUG: build absolute URL for
processActionForward");
	} catch (java.net.MalformedURLException e2) {
		respurl = path;       // Give up
		log("PATCH DEBUG: PATCH DID NOT WORK -- build absolute URL
FAILED for processActionForward");
	}
	return respurl;
}



I have looked into the constructor of java.net.URL and I have played a
little with the constructor
URL url = new URL(new URL(argv[0]), argv[1]);
System.out.println(url.toString());

and in my opinion it always acts correct:
http://www.bla.de /tra/tru.html
--> http://www.bla.de/tra/tru.html

http://www.bla.de/uuu/aa.html /tra/tru.html
--> http://www.bla.de/tra/tru.html

http://www.bla.de/uuu/aa.html tru.html
--> http://www.bla.de/uuu/tru.html

http://www.bla.de/aa.html http://huddel.com/tru.html
--> http://huddel.com/tru.html

I hope it helps, Sebastian





--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>