ICEfaces
  1. ICEfaces
  2. ICE-3427

Navigation to a page with white space in URI throws error

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.7.1
    • Fix Version/s: 1.7.2
    • Component/s: Framework
    • Labels:
      None
    • Environment:
      JSF 1.1

      Description

      Hi,
      I encountered a problem on redirect to an URI which contains white-space.
      This is the navigation rule in faces-confing.xml:

      <navigation-case>
            <from-outcome>naviga</from-outcome>
            <to-view-id>/name with space.iface</to-view-id>
            <redirect/>
       </navigation-case>

      And this is the stack-trace:

      java.lang.IllegalArgumentException
              java.net.URI.create(URI.java:842)
             
      com.icesoft.faces.context.BridgeExternalContext.redirect(BridgeExternalContext.java:324)
             
      com.sun.faces.application.NavigationHandlerImpl.handleNavigation(NavigationHandlerImpl.java:122)
             
      com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:89)
              javax.faces.component.UICommand.broadcast(UICommand.java:312)
              javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:267)
              javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:381)
             
      com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:75)
              com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:200)
              com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:90)
             
      com.icesoft.faces.webapp.http.core.JsfLifecycleExecutor.apply(JsfLifecycleExecutor.java:17)
             
      com.icesoft.faces.webapp.http.core.ReceiveSendUpdates.renderCycle(ReceiveSendUpdates.java:54)
             
      com.icesoft.faces.webapp.http.core.ReceiveSendUpdates.service(ReceiveSendUpdates.java:42)
             
      com.icesoft.faces.webapp.http.core.ViewBoundServer.service(ViewBoundServer.java:65)
             
      com.icesoft.faces.webapp.http.core.RequestVerifier.service(RequestVerifier.java:44)
             
      com.icesoft.faces.webapp.http.common.standard.PathDispatcherServer$Matcher.serviceOnMatch(PathDispatcherServer.java:50)
             
      com.icesoft.faces.webapp.http.common.standard.PathDispatcherServer.service(PathDispatcherServer.java:19)
             
      com.icesoft.faces.webapp.http.servlet.ThreadBlockingAdaptingServlet.service(ThreadBlockingAdaptingServlet.java:19)
             
      com.icesoft.faces.webapp.http.servlet.EnvironmentAdaptingServlet.service(EnvironmentAdaptingServlet.java:63)
             
      com.icesoft.faces.webapp.http.servlet.MainSessionBoundServlet.service(MainSessionBoundServlet.java:139)
             
      com.icesoft.faces.webapp.http.servlet.SessionDispatcher.service(SessionDispatcher.java:53)
             
      com.icesoft.faces.webapp.http.servlet.PathDispatcher$Matcher.serviceOnMatch(PathDispatcher.java:52)
             
      com.icesoft.faces.webapp.http.servlet.PathDispatcher.service(PathDispatcher.java:29)
             
      com.icesoft.faces.webapp.http.servlet.MainServlet.service(MainServlet.java:82)
              javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
             
      com.icesoft.faces.webapp.xmlhttp.BlockingServlet.service(BlockingServlet.java:46

      NOTE: This works fine with ICEfaces 1.5.3 and also in a standard JSF application.

        Activity

        Hide
        Arran Mccullough added a comment -

        according to JSF 1.1 specification, the view identifier is not defined as an URI, in fact RFC 2396 is never cited in the spefication document. I see that in ICEFaces implementation the viewId is translated into an URI in order to testing if it's an absolute address or not (look at com.icesoft.faces.context.BridgeExternalContext.redirect(String)), but the view-identifier string is sent to the ICEFaces javascript engine which runs on the browser without encoding it (exaclty like it is written in the navigation rule inside the faces-config.xml). I suppose that this is why you suggested me writing an already converted URI in the navigation rule.
        Using ICEFaces 1.5.3 and SUN JSF reference implementation, the view identifier is correctly handled and no errors occur.
        If you look at what happens in SUN JSF RI when a redirect occurs, you can see that view identifier string is NEVER used for the istantiation of java.net.URI class , but at the end of navigation handling, the HttpServletResponse is used for executing the redirect operation, as you can see in the method com.sun.faces.context.ExternalContextImpl.redirect(String):

        ((HttpServletResponse) response).sendRedirect(requestURI);

        In the attached WAR, you can see a navigation from "starpage.jsf" to "name with space.jsf".
        In the browser URL bar, you can see the translated URI according to RFC 2396, but this translation is made by HttpServletRequest, not by my application:

        http://localhost:8080/JSF_11_RI/name%20with%20spaces.jsf

        So, in my humble opinion, ICEFaces should check the view identifier string content before using it for instantiating a java.net.URI object. Besides, encondig URI according to RFC 2396 should be done by ICEFaces implementation, exactly like it happens using JSF SUN RI.

        Show
        Arran Mccullough added a comment - according to JSF 1.1 specification, the view identifier is not defined as an URI, in fact RFC 2396 is never cited in the spefication document. I see that in ICEFaces implementation the viewId is translated into an URI in order to testing if it's an absolute address or not (look at com.icesoft.faces.context.BridgeExternalContext.redirect(String)), but the view-identifier string is sent to the ICEFaces javascript engine which runs on the browser without encoding it (exaclty like it is written in the navigation rule inside the faces-config.xml). I suppose that this is why you suggested me writing an already converted URI in the navigation rule. Using ICEFaces 1.5.3 and SUN JSF reference implementation, the view identifier is correctly handled and no errors occur. If you look at what happens in SUN JSF RI when a redirect occurs, you can see that view identifier string is NEVER used for the istantiation of java.net.URI class , but at the end of navigation handling, the HttpServletResponse is used for executing the redirect operation, as you can see in the method com.sun.faces.context.ExternalContextImpl.redirect(String): ((HttpServletResponse) response).sendRedirect(requestURI); In the attached WAR, you can see a navigation from "starpage.jsf" to "name with space.jsf". In the browser URL bar, you can see the translated URI according to RFC 2396, but this translation is made by HttpServletRequest, not by my application: http://localhost:8080/JSF_11_RI/name%20with%20spaces.jsf So, in my humble opinion, ICEFaces should check the view identifier string content before using it for instantiating a java.net.URI object. Besides, encondig URI according to RFC 2396 should be done by ICEFaces implementation, exactly like it happens using JSF SUN RI.
        Hide
        Jack Van Ooststroom added a comment -

        According to URI's JavaDoc:

        • The single-argument constructor requires any illegal characters in its argument to be quoted and preserves any escaped octets and other characters that are present.
        • The multi-argument constructors quote illegal characters as required by the components in which they appear. The percent character ('%') is always quoted by these constructors. Any other characters are preserved.

        We were using URI.create(String) to create the URI which does not do any encoding for us. Switching to one of the multi-argument constructors seems to solve this issue. Marking this one as FIXED.

        Show
        Jack Van Ooststroom added a comment - According to URI's JavaDoc: The single-argument constructor requires any illegal characters in its argument to be quoted and preserves any escaped octets and other characters that are present. The multi-argument constructors quote illegal characters as required by the components in which they appear. The percent character ('%') is always quoted by these constructors. Any other characters are preserved. We were using URI.create(String) to create the URI which does not do any encoding for us. Switching to one of the multi-argument constructors seems to solve this issue. Marking this one as FIXED.
        Hide
        Jack Van Ooststroom added a comment -

        The ? in the URI gets encoded as well when a query is present.

        Show
        Jack Van Ooststroom added a comment - The ? in the URI gets encoded as well when a query is present.
        Hide
        Jack Van Ooststroom added a comment -

        The path and query are now used as separate parameters when creating the URI. Marking this one as FIXED once again...

        Show
        Jack Van Ooststroom added a comment - The path and query are now used as separate parameters when creating the URI. Marking this one as FIXED once again...

          People

          • Assignee:
            Unassigned
            Reporter:
            Arran Mccullough
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: