0

I'm having issues getting servlet forwarding to work when the request have been wrapped by a HttpServletRequestWrapper.

This is a server-side equinox application, running from within Eclipse using the embedded Jetty web server to provide the HttpService implementation.

To isolate the issue, the only thing my field does is to wrap the request and pass it forward:

public class TestFilter implements Filter {
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        chain.doFilter(new HttpServletRequestWrapper((HttpServletRequest)request), response);
    }
    ...
}

...and my servlet does nothing but trying to forward to a JSP:

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    RequestDispatcher dispatcher = request.getRequestDispatcher("/account.jsp");
    try {
        dispatcher.forward(request, response);

    } catch (Exception e) {
        e.printStackTrace();
    }

}

According to the servlet 2.3 spec, the request and response objects passed to the forward method can be either the original ones, or an instance of the provided wrappers. I need to pass a custom wrapper, but when I do that, the forward fails the following exception:

java.lang.StringIndexOutOfBoundsException: String index out of range: -1
    at java.lang.String.substring(Unknown Source)
    at org.eclipse.equinox.http.servlet.internal.ProxyServlet.service(ProxyServlet.java:64)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
    at org.eclipse.equinox.http.jetty.internal.HttpServerManager$InternalHttpServiceServlet.service(HttpServerManager.java:318)
    at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
    at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:390)
    at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
    at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
    at org.mortbay.jetty.servlet.Dispatcher.forward(Dispatcher.java:327)
    at org.mortbay.jetty.servlet.Dispatcher.forward(Dispatcher.java:126)
    at org.eclipse.equinox.http.servlet.internal.RequestDispatcherAdaptor.forward(RequestDispatcherAdaptor.java:30)
    at mypackage.internal.signup.PlatformSetupServlet.doPost(PlatformSetupServlet.java:53)
...

If I take the wrapper away and pass forward the original request the servlet forward succeeds.

This looks like a bug in the org.eclipse.equinox.http.servlet implementation, but I might be missing something.

Am I doing something wrong?

Thank you!!

Eduardo Born

Edy Bourne
  • 5,679
  • 13
  • 53
  • 101

2 Answers2

0

looks like the ProxyServlet is running into problems when parsing the Request's information.

Found the source of ProxyServlet:

http://kickjava.com/src/org/eclipse/equinox/http/servlet/internal/ProxyServlet.java.htm

Though it doesn't match exactly, you can see from the code that it's trying to extract path info from your request -- and it didn't find a "/", which it was expecting. You can try tweaking the path of the servlet maybe, just to test it out?

Renan
  • 827
  • 8
  • 16
0

This should be caused by the code in ProxyServlet.service method, passing -1 to substring. But the reason "forward" is breaking your code, is that "forward" doesn't create a whole new wrapper hierarchy. Instead, it finds and replaces the innermost request with the new forwarded one.

So the outer wrapper doesn't change, and if you ask it to return the queryString for instance, if it has a cached query string, it will return the same one, not the forwarded one.

I'm having an issue with this, which I'm trying to resolve. Will post here again if I ever succeed.

See this question that I just posted for a better description of what I mean: How to know when the request is forwarded in a RequestWrapper object

Community
  • 1
  • 1
Iravanchi
  • 5,139
  • 9
  • 40
  • 56