@URLMapping path values gets URL encoded in form's 'action' attribute

Splash Forums PrettyFaces Users @URLMapping path values gets URL encoded in form's 'action' attribute

This topic contains 5 replies, has 2 voices, and was last updated by  Vidar 11 years, 3 months ago.

Viewing 6 posts - 1 through 6 (of 6 total)
  • Author
    Posts
  • #17789

    Vidar
    Participant

    I have a application that should accept URLs with a dynamic number of ‘/’ as part of the URL. In the below example the pattern takes the entire URL path and injects into the “path”-attribute of the bean.

    This works great for picking up URLs like

    /<appname>/category/

    /<appname>/category/subcategory/

    /<appname>/category/subcategory/a/b/c/

    etc

    However the <h:form> “action”-attribute gets broken since the “path”-value gets URL encoded somewhere along the way.

    Question:

    How can I prevent the path-parameter from being URL encoded?

    (Using PrettyFaces 3.1.0)

    Bean that handles navigation:

    @Named("nav")
    @RequestScoped
    @URLMapping(id = "navigationBean", pattern = "/#{/.*/nav.path}/", viewId = "#{nav.getViewPath}", outbound=false)
    public class NavigationBean implements Serializable {
    private String path;

    @URLQueryParameter("page")
    private Long page;
    ...
    public String getViewPath() {
    // at this point "path" contains the URL path as expected, and I can use it ready data and to show the correct view (example of value returned "/faces/section.xhtml" or a 404-viewpath if needed)
    ...
    }
    }

    On the xhtml page I include a JSF2 custom component, that inserts a <h:form> with <h:commandLink>’s for allowing ajax paging of the page content.

    simple form with commandlink for next page

    <h:form>
    <h:commandLink>
    <span>Next page</span>
    <f:attribute name="page" value="#{nav.page+1}/>
    <f:ajax listener="#[nav.updatePageContent}" execute="@form" render="..."/>
    </h:commandLink>
    ...
    </h:form>

    Debugging and setting a breakpoint in the NavigationBean.getPath()-method I can see that the method is called and returns the original string value, however in the finished HTML output the path parameter has been URL encoded, which breaks all ajax requests.

    html output:

    <form enctype="application/x-www-form-urlencoded" action="/application/category%2Fsubcategory/?page=1" method="post" name="list:j_idt121" id="list:j_idt121">
    ...
    </form>

    In this example ‘/’ has been encoded to ‘%2F’ and any attempt to click the link gives a “400 Invalid URI: noSlash” error in FireBug using Firefox. (request never reaches the webapp)

    web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0">
    <display-name>testApp</display-name>
    <filter>
    <filter-name>Pretty Filter</filter-name>
    <filter-class>com.ocpsoft.pretty.PrettyFilter</filter-class>
    </filter>
    <filter-mapping>
    <filter-name>Pretty Filter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>ERROR</dispatcher>
    </filter-mapping>
    <servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>/faces/*</url-pattern>
    </servlet-mapping>
    <error-page>
    <error-code>404</error-code>
    <location>/404.jsp</location>
    </error-page>
    <context-param>
    <param-name>facelets.SKIP_COMMENTS</param-name>
    <param-value>true</param-value>
    </context-param>
    <context-param>
    <param-name>com.ocpsoft.pretty.BASE_PACKAGES</param-name>
    <param-value>no.tv2.play.beans</param-value>
    </context-param>
    </web-app>

    pretty-config.xml

    <pretty-config xmlns="http://ocpsoft.com/prettyfaces/3.1.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://ocpsoft.com/prettyfaces/3.1.0
    http://ocpsoft.com/xml/ns/prettyfaces/ocpsoft-pretty-faces-3.1.0.xsd">
    <!-- Begin RewriteRules -->
    <rewrite match="^/[^.?]*$" trailingSlash="append" redirect="permanent" outbound="false"/>
    </pretty-config>

    faces-config.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <faces-config<br />
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
    version="2.0">
    </faces-config>

    #20232

    Seems like this is a Tomcat security feature. Look here:

    http://tomcat.apache.org/security-6.html#Fixed_in_Apache_Tomcat_6.0.10

    As a workaround you could try this:

    -Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true

    #20233

    Just to clear some things up. I think that the escaping of slashes in your case is an issue we must definitely look at. But I also think that the fact that your requests are failing is a problem that has to do with the Tomcat security feature mentioned above. In theory escaped slashes in URLs should work, or am i mistaken?

    Does this system property setting work for you?

    #20236

    Vidar
    Participant

    Thanks for the quick replies.

    I’m running on Glassfish3 and couldn’t not find any updated Glassfish info for this after trying the above tomcat setting and similar suggestions without it having any effect.

    My, anything but pretty, workaround involves manually URL encoding the “path”-string in the get-method and in the setter do a double URL decode to get the original value back.

    At least its working and no security setting has been disabled.

    My getter and setter that PrettyFaces injects the page path into now looks like

    public void setPath(String pagePath) {
    try {
    // at this point any "/"-char looks like "%252F"
    pagePath = URLDecoder.decode(pagePath, "UTF-8"); // now the "/" looks like "%2F"
    pagePath = URLDecoder.decode(pagePath, "UTF-8"); // and we are back at "/"
    } catch (UnsupportedEncodingException e) {
    e.printStackTrace();
    }
    this.pagePath = pagePath;
    }

    public String getPath() {
    try {
    return URLEncoder.encode(pagePath, "UTF-8"); // encodes the "/" into "%2F"
    } catch (UnsupportedEncodingException e) {
    e.printStackTrace();
    }
    return pagePath;
    }

    the action attribute of a form now looks like

    <form enctype="application/x-www-form-urlencoded" action="/application/category%252Fsubcategory/?page=1" method="post" name="list:j_idt121" id="list:j_idt121">
    ...
    </form>

    “/” has now been encoded into “%252F” instead of “%2F”, and the URL is no longer causing any trouble reaching the web app.

    #20237

    Thank you for the detailed bug report. I’m glad to hear that you have a workaround so that this doesn’t completely break your app! :-)

    Could you open a ticket for this? So we have everything in the ticket system?

    http://code.google.com/p/prettyfaces/issues/list

    Thank you!

    #20238

    Vidar
    Participant
Viewing 6 posts - 1 through 6 (of 6 total)

The forum ‘PrettyFaces Users’ is closed to new topics and replies.

Comments are closed.