Bug 56831 - javax.faces.application.ViewExpiredException thrown for applications which contextRoot contains dash
Summary: javax.faces.application.ViewExpiredException thrown for applications which co...
Status: RESOLVED INVALID
Alias: None
Product: Tomcat 7
Classification: Unclassified
Component: Catalina (show other bugs)
Version: 7.0.55
Hardware: PC Linux
: P2 normal (vote)
Target Milestone: ---
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-08-08 14:28 UTC by Juraj Huska
Modified: 2014-08-12 11:50 UTC (History)
1 user (show)



Attachments
Maven project to reproduce the issue - its simplified RichFaces project to contain only JSF dependencies (14.82 KB, application/zip)
2014-08-08 14:28 UTC, Juraj Huska
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Juraj Huska 2014-08-08 14:28:24 UTC
Created attachment 31889 [details]
Maven project to reproduce the issue - its simplified RichFaces project to contain only JSF dependencies

When I deploy a JSF application (Mojarra 2.2.7), which .war name contains dash (deployed context root contains dash as well), javax.faces.application.ViewExpiredException is being in the first Ajax request from such application.

The same application works if its .war does not contain dash (the context root is without dash).

Another important thing to reproduce this is, that the error is thrown only when you get to the app via redirect. If the application is loaded directly, everything works. More info in steps to reproduce.

I have tried different Tomcat versions - 8.x, 7.0.30, etc. - still the same.
I have tried different JSF Mojarra versions, newer or older.

Here are the steps to reproduce:
1. download attached maven project
2. issue "mvn clean package" from its root directory
3. deploy simple-app.war to Tomcat
4. load localhost:8080 and then Tomcat Gui manager
5. click on the context root to load actual app
6. try to write something into input and see the ViewExpiredException
Comment 1 Juraj Huska 2014-08-08 14:32:03 UTC
FYI original issue report in RichFaces issue management:
https://issues.jboss.org/browse/RF-13731
Comment 2 Mark Thomas 2014-08-08 14:37:12 UTC
Some explanation of why you think this is a Tomcat bug would be helpful.
Comment 3 Juraj Huska 2014-08-11 11:09:38 UTC
Hello,

thanks for quick response. IMHO it is a Tomcat bug because it is the only servlet container/application container I am able to reproduce this issue on. It works on e.g. JBoss AS 7.1.1.Final or Wildfly 8.1.0.Final.

Additionally, I managed to reproduce it without Tomcat manager as well. The key to reproduce it is to access the JSF app (localhost:8080/simple-app) from a link with following code:

<a href="/simple%2Dapp">simple-app</a>

The issue is occurring only when href attribute contains dash as a URL encoded character.
Comment 4 Mark Thomas 2014-08-11 19:31:19 UTC
That you only see this bug on Tomcat could mean that Tomcat is following a strict interpretation of the spec whereas other containers are being more lenient. Given that you know the application far better than the Tomcat developers, it makies things a lot simpler if the bug is presented in the form:

- the attached app calls method X with parameters Y
- as per the Servlet/JSP/EL/WebSocket/HTTP/etc. spec, Tomcat should return A but instead returns B

rather than the Tomcat developers having to dig their way through an app they have no knowledge of to try and work out which API call (that might be returning a completely valid result) is causing the problem.

It isn't that we aren't going to look into this bug - I'm going to start on it now - but you could really help move things along by providing a more specific bug report than "The attached app throws an expception when I do this."
Comment 5 Mark Thomas 2014-08-11 20:08:01 UTC
I can confim that this is not a Tomcat bug.

The issue is triggered by HttpServletRequest.getContextPath() returning "/simple%2dapp" rather than "/simple-app". I have confirmed this by:
1. Confirming I can reproduce the issue using the provided steps.
2. Using a debugger, change the return value of getContextPath() from "/simple%2dapp" to "/simple-app" and confirming that the exception no longer occurs.

The Javadoc for getContextPath() [1] is clear. The container does NOT decode this method.

The simplest fix is probably for RichFaces to use ServletContext.getContextPath()

That you don't see this bug on other containers suggests that those containers are not following the specification for HttpServletRequest.getContextPath().

[1] http://docs.oracle.com/javaee/7/api/javax/servlet/http/HttpServletRequest.html#getContextPath%28%29
Comment 6 Konstantin Kolinko 2014-08-11 20:32:06 UTC
1) Guessing with a crystal ball I think ViewExpiredException means that you rely on cookies for session management and the session cookie has not been sent by the browser.

2) The RF-13731 issue mentioned that behaviour differs between browsers. (Firefox has the issue, Chrome does not).
Is that true? Why are you not mentioning it?


I am experimenting with the following configuration:
- current Tomcat 7.0.x (~7.0.55)
- Using the default examples webapp renamed to "ex-amples"
- Firefox 31.0
- I am using built-in Network tool in Firefox to inspect HTTP headers of requests and responses (Tools menu > Web development > Network).

The scenario is as following:
1. Access SessionExample page as
[1] http://localhost:8080/ex%2Damples/servlets/servlet/SessionExample

2. I observe the following:
1) Firefox displays the URL in address bar as
http://localhost:8080/ex-amples/servlets/servlet/SessionExample

2) Tomcat sends the following header:
Set-Cookie: JSESSIONID=727BF492DC0D245BD0AD2D749EB1BD6D; Path=/ex-amples/; HttpOnly

3. If I access [1] again in either of the following ways:
a) copy-pasting the above URL into the address bar
b) refreshing the page (pressing F5 key on keyboard or clicking green reload button in the address bar)
Firefox does not send Cookie header with the request.

4. If I go to address bar and press 'Enter' (Ctrl+L, Enter), Firefox uses '-' character in the request and sends Cookie header with the request.


1). The browser behaviour seems odd to me, but to properly judge it one has to look into applicable specifications and test with other browsers. It might be a browser bug. It might be different interpretation of a specification.

Does the behaviour differ between browsers?

2). A well-known recommendation for web application authors is to apply HttpServletResponse.encodeURL() to their URLs. That is to ensure that their applications that require sessions can operate with browsers that do not support cookies.
Comment 7 Juraj Huska 2014-08-12 11:50:13 UTC
Thanks for your input and guidance. My unhelpful issue description was caused by my lack of expertise. Now I have a bit bigger understanding what is going on, and I will dig in deeper and provide you some more information.