From: Jeffrey Keays <elided>
Content-Type: text/plain;
	charset=utf-8
Content-Transfer-Encoding: quoted-printable
Subject: Resin 4.0.19 Pro: url-rewriting & JSP code see different sessions?!
Date: Thu, 22 Sep 2011 19:28:59 +0900
X-Universally-Unique-Identifier: e3e44936-34d3-491f-bfa4-e2c06f2770a6
Message-Id: <3060A794-6A93-49EA-84DB-C24A1AD9E2B1@openwave.com>
To: oem@caucho.com
Mime-Version: 1.0 (Apple Message framework v1084)

Hello Caucho folks,

We have a large struts webapp and we are having a problem (that we never =
had on resin 3.x series previously) of the current session as of the =
return of the Action not being accessible to the JSP templates, causing =
them to render incorrectly, _BUT_ mysteriously still being available to =
url rewriting. (so if the user navigates back to the page a second time =
via a more circuitous route, it will render correctly the second time).  =
This is for the first page after login.

This requires=20

          <enable-cookies>false</enable-cookies>

and url rewriting left at default (i.e. on) in the session-config.

also, because this needs to support ancient cellphones that may not =
support redirects, doing a redirect may not be acceptable to the =
customer.  (BTW, doing a redirect works around it)

the action, login() invalidates the old session and starts a new one, =
copying all the attributes over to the new one (to prevent attacks where =
a bad guy has access to the pre-authentication session id) like this:

	// copy all the attributes out of the old session into local =
variables.
	session.invalidate();=20
	session =3D request.getSession();=20
	// copy all the attributes from the local variables back into =
the new session

However, even with that process turned off (we have a setting), and =
continuing to use the same session we still have the same problem.

I have put logging statements at the beginning and the end (first thing =
before returning the struts "SUCCESS" ActionForward) of the login() =
action, as well as into the JSP template to verify what is visible =
there.

For a sample invocation: here is the form that gets submitted to login()

> <form action=3D"/do/mdologin?l=3Dja-JP" method=3D"post">
> <input name=3D"sessionId" value=3D"aaa2XS2Lz-QCM99PrJqkt" =
type=3D"hidden">
> <div>
> <input name=3D"variant" value=3D"spinnet-standard-Blue" type=3D"hidden">=

> <input name=3D"locale" value=3D"ja-JP" type=3D"hidden">
> <input name=3D"directMessageView" type=3D"hidden">
> <input name=3D"uid" type=3D"hidden">
> <input name=3D"folder" type=3D"hidden">
> <input name=3D"remoteAccountUID" type=3D"hidden">
> <input name=3D"client" value=3D"mobile-html-c" type=3D"hidden">
> <input name=3D"login" value=3D"1" type=3D"hidden">
> </div>
> <div>
> =EF=BE=92=EF=BD=B0=EF=BE=99=EF=BD=B1=EF=BE=84=EF=BE=9E=EF=BE=9A=EF=BD=BD=

> <input istyle=3D"3" name=3D"account" size=3D"14" type=3D"text">
> <br>
> =EF=BE=8A=EF=BE=9F=EF=BD=BD=EF=BE=9C=EF=BD=B0=EF=BE=84=EF=BE=9E
> <input istyle=3D"3" name=3D"password" size=3D"14" type=3D"password">
> </div>
> <div>
> <input value=3D"=EF=BE=9B=EF=BD=B8=EF=BE=9E=EF=BD=B2=EF=BE=9D" =
type=3D"submit">
> </div>
> </form>

This is on initial view, we have a form tag that inserts "sessionId" =
automatically to forms to prevent a type of XSS attack.  On subsequent =
views, the "/do/mdologin" action interestingly gets url-rewritten to =
have a jsessionid that _differs_ from the one in the sessionId input =
(i.e. the one visible to our code using request.getSession())

posting that form, here are the log statements on entering login()

> on entry to login()
> request is HttpServletRequestImpl[HttpRequest[a, 2]]
> request.getSession() -> SessionImpl[aaaHwRSerRnffaE41Jqkt,]
> org.apache.struts.action.LOCALE =3D=3D en_US

and at the end of login(), immediately prior to returning the "success" =
actionforward:

> before bottom return mapping.findForward(SUCCESS)
> request is HttpServletRequestImpl[HttpRequest[a, 2]]
> request.getSession() -> SessionImpl[aaaHwRSerRnffaE41Jqkt,]
> LOGIN_ID =3D=3D test01@openwave.com
> accountStatusCheckedTime =3D=3D 1316685307000
> com.openwave.paf.rswitch.client =3D=3D mobile-html-c
> com.openwave.paf.rswitch.locale =3D=3D ja-JP
> com.openwave.paf.rswitch.variant =3D=3D x-standard-DarkRed
> org.apache.struts.action.LOCALE =3D=3D en_US
> user =3D=3D Subject:
>   	Principal: test01
>   	Private Credential: {maillogin=3Dtest01}                    =20
> we_account =3D=3D {<elided>}
> we_cos =3D=3D {<elided>}
> we_mail =3D=3D {<elided>}

However in the JSP template I put this code:

> <%
>   StringWriter sw =3D new StringWriter();
>   PrintWriter pw =3D new PrintWriter(sw);
>  =20
>   pw.println("pageContext is " + pageContext);
>   pw.println("request is " + request);
>   pw.println("session is " + session);
>   pw.println("request.getSession() -> " + request.getSession());
>   pw.println("session.isNew() -> " + session.isNew());
>   pw.println("session contains: ");
>   Enumeration e =3D session.getAttributeNames();
>   while (e.hasMoreElements()) {
>       String name =3D (String) e.nextElement();
>       pw.println("\t." + name + " =3D=3D " + =
session.getAttribute(name));
>   }
> %>
>=20
> <wap:pre>
>   <%=3D sw.toString() %>
> </wap:pre>

which rendered as:

> <pre>
> pageContext is com.caucho.jsp.PageContextImpl@233aa44
> request is =
IncludeRequest[/variants/spinnet/lcommon/mobile/mainmenu/content.jsp,Forwa=
rdRequest[/variants/spinnet/lcommon/mobile/layouts/layout.jsp,ForwardReque=
st[/do/mmainmenu,HttpServletRequestImpl[HttpRequest[a, 2]]]]]
> session is SessionImpl[aaaqgA1FT9DTo6YE2Jqkt,]
> request.getSession() -> SessionImpl[aaaqgA1FT9DTo6YE2Jqkt,]
> session.isNew() -> true
> session contains:
> </pre>


which explains why the JSP template content did not render correctly, =
however, links that _did_ render  got url-rewritten ;jsessionid=3D =
additions like so:

> <li>
> <a href=3D"/do/addresses/mfilters;jsessionid=3DaaaHwRSerRnffaE41Jqkt" =
accesskey=3D"2">
> =EF=BD=B1=EF=BE=84=EF=BE=9E=EF=BE=9A=EF=BD=BD=E5=B8=B3
> </a>
> </li>
> <li>
> <a href=3D"/do/logout;jsessionid=3DaaaHwRSerRnffaE41Jqkt" =
accesskey=3D"3">
> =EF=BE=9B=EF=BD=B8=EF=BE=9E=EF=BD=B1=EF=BD=B3=EF=BE=84
> </a>
> </li>

i.e. the "real" session.  Unsurprisingly clicking on these links leads =
to working pages including the first one that rendered wrongly the first =
time.

This weirdness of the same session not being available from JSP =
pageContexts as is available to URL rewriting seems to be new in Resin =
4, as this app worked fine in Resin 3.x.  Does this look like a Bug to =
you?  Or is it a changed spec?

	--Jeffrey Keays
	Senior Consultant
	Nihon Openwave Systems K.K.
	Shinjuku, Tokyo
	Japan

P.S. A coworker looked through in a debugger to see where =
request.getSession() became null, and he was able to come up with this:

> Daemon Thread [http://127.0.0.1:18143-4] (Suspended)=09
> 	=
com.caucho.server.http.HttpServletResponseImpl.encodeURL(java.lang.String)=
 line: 1330=09
> 		-> request.getSession(false) =3D=3D nulll           =20
> 	=09
> 	=
com.caucho.server.webapp.ForwardResponse(com.caucho.server.http.CauchoResp=
onseWrapper).encodeURL(java.lang.String) line: 281=09
> 	=
com.caucho.server.webapp.ForwardResponse(com.caucho.server.http.CauchoResp=
onseWrapper).encodeURL(java.lang.String) line: 281=09
> 	=
com.caucho.server.webapp.ForwardResponse(com.caucho.server.http.CauchoResp=
onseWrapper).encodeURL(java.lang.String) line: 281=09
> 	=
com.openwave.webedge.servlets.ContentLengthFilter$BufferedResponse(javax.s=
ervlet.http.HttpServletResponseWrapper).encodeURL(java.lang.String) =
line: 207=09
> 	=
com.caucho.server.http.ToCharResponseAdapter(com.caucho.server.http.Respon=
seWrapper).encodeURL(java.lang.String) line: 417=09
> 	=
com.caucho.server.webapp.IncludeResponse(com.caucho.server.http.CauchoResp=
onseWrapper).encodeURL(java.lang.String) line: 281=09
> 	=
org.apache.struts.util.RequestUtils.computeURL(javax.servlet.jsp.PageConte=
xt, java.lang.String, java.lang.String, java.lang.String, =
java.lang.String, java.util.Map, java.lang.String, boolean, boolean) =
line: 644=09
> 	    -> =
((javax.servlet.http.HttpServletRequest)pageContext.getRequest()).getSessi=
on(false) !=3D null
>=20
> 	=
org.apache.struts.util.RequestUtils.computeURL(javax.servlet.jsp.PageConte=
xt, java.lang.String, java.lang.String, java.lang.String, =
java.lang.String, java.util.Map, java.lang.String, boolean) line: 436=09
> 	=
com.openwave.webedge.taglibs.FormTagWithSessionId(com.openwave.paf.taglibs=
.mobile.struts.FormTag).getAction() line: 92=09
> 	=
com.openwave.webedge.taglibs.FormTagWithSessionId(com.openwave.paf.taglibs=
.mobile.FormTag).doStartTag() line: 77=09
> 	=
com.openwave.webedge.taglibs.FormTagWithSessionId(com.openwave.paf.taglibs=
.mobile.struts.FormTag).doStartTag() line: 65=09
> 	com.openwave.webedge.taglibs.FormTagWithSessionId.doStartTag() =
line: 45=09
> 	docroot/lcommon/mobile/login/content.jsp line: 23=09
> 	docroot/lcommon/mobile/login/content.jsp line: not available=09
> 	=
_jsp._docroot._lcommon._mobile._login._content__jsp(com.caucho.jsp.JavaPag=
e).service(javax.servlet.ServletRequest, javax.servlet.ServletResponse) =
line: 64=09
> 	=
_jsp._docroot._lcommon._mobile._login._content__jsp(com.caucho.jsp.Page).p=
ageservice(javax.servlet.http.HttpServletRequest, =
javax.servlet.http.HttpServletResponse) line: 542=09
> 	=
com.caucho.server.dispatch.PageFilterChain.doFilter(javax.servlet.ServletR=
equest, javax.servlet.ServletResponse) line: 194=09
> 	=
com.caucho.server.webapp.DispatchFilterChain.doFilter(javax.servlet.Servle=
tRequest, javax.servlet.ServletResponse) line: 126=09
> 	=
com.caucho.server.dispatch.SubInvocation(com.caucho.server.dispatch.Servle=
tInvocation).service(javax.servlet.ServletRequest, =
javax.servlet.ServletResponse) line: 287=09
> 	=
com.caucho.server.webapp.RequestDispatcherImpl.include(javax.servlet.Servl=
etRequest, javax.servlet.ServletResponse, java.lang.String) line: 440=09
> 	=
com.caucho.server.webapp.RequestDispatcherImpl.include(javax.servlet.Servl=
etRequest, javax.servlet.ServletResponse) line: 359=09
> 	com.caucho.jsp.PageContextImpl.include(java.lang.String, =
boolean) line: 1081=09
> 	com.caucho.jsp.PageContextImpl.include(java.lang.String) line: =
957=09
> 	=
com.openwave.paf.taglibs.struts.GetTag(com.openwave.paf.taglibs.struts.Ins=
ertTag).doInclude(java.lang.String) line: 59=09
> 	=
org.apache.struts.taglib.tiles.InsertTag$InsertHandler.doEndTag() line: =
881=09
> 	=
com.openwave.paf.taglibs.struts.GetTag(org.apache.struts.taglib.tiles.Inse=
rtTag).doEndTag() line: 473=09
> 	docroot/lcommon/mobile/layouts/layout.jsp line: 43=09
> 	docroot/lcommon/mobile/layouts/layout.jsp line: not available=09
> 	=
_jsp._docroot._lcommon._mobile._layouts._layout__jsp(com.caucho.jsp.JavaPa=
ge).service(javax.servlet.ServletRequest, javax.servlet.ServletResponse) =
line: 64=09
> 	=
_jsp._docroot._lcommon._mobile._layouts._layout__jsp(com.caucho.jsp.Page).=
pageservice(javax.servlet.http.HttpServletRequest, =
javax.servlet.http.HttpServletResponse) line: 551=09
> 	=
com.caucho.server.dispatch.PageFilterChain.doFilter(javax.servlet.ServletR=
equest, javax.servlet.ServletResponse) line: 194=09
> 	=
com.caucho.server.webapp.DispatchFilterChain.doFilter(javax.servlet.Servle=
tRequest, javax.servlet.ServletResponse) line: 126=09
> 	=
com.caucho.server.dispatch.SubInvocation(com.caucho.server.dispatch.Servle=
tInvocation).service(javax.servlet.ServletRequest, =
javax.servlet.ServletResponse) line: 287=09
> 	=
com.caucho.server.webapp.RequestDispatcherImpl.forward(javax.servlet.Servl=
etRequest, javax.servlet.ServletResponse, java.lang.String, =
com.caucho.server.dispatch.Invocation, javax.servlet.DispatcherType) =
line: 298=09
> 	=
com.caucho.server.webapp.RequestDispatcherImpl.forward(javax.servlet.Servl=
etRequest, javax.servlet.ServletResponse) line: 116=09
> 	=
com.openwave.paf.struts.ResourceTilesRequestProcessor(org.apache.struts.ac=
tion.RequestProcessor).doForward(java.lang.String, =
javax.servlet.http.HttpServletRequest, =
javax.servlet.http.HttpServletResponse) line: 1069=09
> 	=
com.openwave.paf.struts.ResourceTilesRequestProcessor(org.apache.struts.ti=
les.TilesRequestProcessor).doForward(java.lang.String, =
javax.servlet.http.HttpServletRequest, =
javax.servlet.http.HttpServletResponse) line: 274=09
> 	=
com.openwave.paf.struts.ResourceTilesRequestProcessor(com.openwave.paf.str=
uts.TilesRequestProcessor).doForward(java.lang.String, =
javax.servlet.http.HttpServletRequest, =
javax.servlet.http.HttpServletResponse) line: 141=09
> 	=
com.openwave.paf.struts.ResourceTilesRequestProcessor(org.apache.struts.ti=
les.TilesRequestProcessor).processTilesDefinition(java.lang.String, =
boolean, javax.servlet.http.HttpServletRequest, =
javax.servlet.http.HttpServletResponse) line: 254=09
> 	=
com.openwave.paf.struts.ResourceTilesRequestProcessor(org.apache.struts.ti=
les.TilesRequestProcessor).processForwardConfig(javax.servlet.http.HttpSer=
vletRequest, javax.servlet.http.HttpServletResponse, =
org.apache.struts.config.ForwardConfig) line: 309=09
> 	=
com.openwave.paf.struts.ResourceTilesRequestProcessor(org.apache.struts.ac=
tion.RequestProcessor).process(javax.servlet.http.HttpServletRequest, =
javax.servlet.http.HttpServletResponse) line: 279=09
> 	=
com.openwave.paf.struts.ResourceTilesRequestProcessor(com.openwave.paf.str=
uts.TilesRequestProcessor).process(javax.servlet.http.HttpServletRequest, =
javax.servlet.http.HttpServletResponse) line: 109=09
> 	=
com.openwave.paf.struts.ActionServlet.process(javax.servlet.http.HttpServl=
etRequest, javax.servlet.http.HttpServletResponse) line: 106=09
> 	=
com.openwave.paf.struts.ActionServlet(org.apache.struts.action.ActionServl=
et).doGet(javax.servlet.http.HttpServletRequest, =
javax.servlet.http.HttpServletResponse) line: 507=09
> 	=
com.openwave.paf.struts.ActionServlet(javax.servlet.http.HttpServlet).serv=
ice(javax.servlet.http.HttpServletRequest, =
javax.servlet.http.HttpServletResponse) line: 119=09
> 	=
com.openwave.paf.struts.ActionServlet(javax.servlet.http.HttpServlet).serv=
ice(javax.servlet.ServletRequest, javax.servlet.ServletResponse) line: =
96=09
> 	=
com.caucho.server.dispatch.ServletFilterChain.doFilter(javax.servlet.Servl=
etRequest, javax.servlet.ServletResponse) line: 109=09
> 	=
com.caucho.server.webapp.DispatchFilterChain.doFilter(javax.servlet.Servle=
tRequest, javax.servlet.ServletResponse) line: 126=09
> 	=
com.caucho.server.dispatch.SubInvocation(com.caucho.server.dispatch.Servle=
tInvocation).service(javax.servlet.ServletRequest, =
javax.servlet.ServletResponse) line: 287=09
> 	=
com.caucho.server.webapp.RequestDispatcherImpl.forward(javax.servlet.Servl=
etRequest, javax.servlet.ServletResponse, java.lang.String, =
com.caucho.server.dispatch.Invocation, javax.servlet.DispatcherType) =
line: 298=09
> 	=
com.caucho.server.webapp.RequestDispatcherImpl.forward(javax.servlet.Servl=
etRequest, javax.servlet.ServletResponse) line: 116=09
> 	=
com.openwave.webedge.servlets.AuthFilter.doFilter(javax.servlet.ServletReq=
uest, javax.servlet.ServletResponse, javax.servlet.FilterChain) line: =
376=09
> 	=
com.caucho.server.dispatch.FilterFilterChain.doFilter(javax.servlet.Servle=
tRequest, javax.servlet.ServletResponse) line: 89=09
> 	=
com.openwave.webedge.servlets.LoggingDataFilter.doFilter(javax.servlet.Ser=
vletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain) =
line: 79=09
> 	=
com.caucho.server.dispatch.FilterFilterChain.doFilter(javax.servlet.Servle=
tRequest, javax.servlet.ServletResponse) line: 89=09
> 	=
com.openwave.paf.filters.CloseFilter.doFilter(javax.servlet.ServletRequest=
, javax.servlet.ServletResponse, javax.servlet.FilterChain) line: 75=09
> 	=
com.caucho.server.dispatch.FilterFilterChain.doFilter(javax.servlet.Servle=
tRequest, javax.servlet.ServletResponse) line: 89=09
> 	=
com.openwave.webedge.servlets.MailboxLockFilter.doFilter(javax.servlet.Ser=
vletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain) =
line: 50=09
> 	=
com.caucho.server.dispatch.FilterFilterChain.doFilter(javax.servlet.Servle=
tRequest, javax.servlet.ServletResponse) line: 89=09
> 	=
com.openwave.paf.filters.AvailabilityFilter.doFilter(javax.servlet.Servlet=
Request, javax.servlet.ServletResponse, javax.servlet.FilterChain) line: =
140=09
> 	=
com.caucho.server.dispatch.FilterFilterChain.doFilter(javax.servlet.Servle=
tRequest, javax.servlet.ServletResponse) line: 89=09
> 	=
com.openwave.webedge.servlets.ContentLengthFilter.doFilter(javax.servlet.S=
ervletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain) =
line: 166=09
> 	=
com.caucho.server.dispatch.FilterFilterChain.doFilter(javax.servlet.Servle=
tRequest, javax.servlet.ServletResponse) line: 89=09
> 	=
com.openwave.paf.filters.BadParameterFilter.doFilter(javax.servlet.Servlet=
Request, javax.servlet.ServletResponse, javax.servlet.FilterChain) line: =
161=09
> 	=
com.caucho.server.dispatch.FilterFilterChain.doFilter(javax.servlet.Servle=
tRequest, javax.servlet.ServletResponse) line: 89=09
> 	=
com.openwave.paf.filters.RefererCheckFilter.doFilter(javax.servlet.Servlet=
Request, javax.servlet.ServletResponse, javax.servlet.FilterChain) line: =
239=09
> 	=
com.caucho.server.dispatch.FilterFilterChain.doFilter(javax.servlet.Servle=
tRequest, javax.servlet.ServletResponse) line: 89=09
> 	=
com.openwave.webedge.servlets.EncodingFilter.doFilter(javax.servlet.Servle=
tRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain) =
line: 133=09
> 	=
com.caucho.server.dispatch.FilterFilterChain.doFilter(javax.servlet.Servle=
tRequest, javax.servlet.ServletResponse) line: 89=09
> 	=
com.caucho.server.webapp.DispatchFilterChain.doFilter(javax.servlet.Servle=
tRequest, javax.servlet.ServletResponse) line: 126=09
> 	=
com.caucho.server.dispatch.SubInvocation(com.caucho.server.dispatch.Servle=
tInvocation).service(javax.servlet.ServletRequest, =
javax.servlet.ServletResponse) line: 287=09
> 	=
com.caucho.server.webapp.RequestDispatcherImpl.forward(javax.servlet.Servl=
etRequest, javax.servlet.ServletResponse, java.lang.String, =
com.caucho.server.dispatch.Invocation, javax.servlet.DispatcherType) =
line: 298=09
> 	=
com.caucho.server.webapp.RequestDispatcherImpl.dispatch(javax.servlet.Serv=
letRequest, javax.servlet.ServletResponse) line: 141=09
> 	=
com.caucho.server.dispatch.RewriteDispatchFilterChain.doFilter(javax.servl=
et.ServletRequest, javax.servlet.ServletResponse) line: 91=09
> 	=
com.caucho.server.webapp.WebAppFilterChain.doFilter(javax.servlet.ServletR=
equest, javax.servlet.ServletResponse) line: 156=09
> 	=
com.caucho.server.webapp.AccessLogFilterChain.doFilter(javax.servlet.Servl=
etRequest, javax.servlet.ServletResponse) line: 95=09
> 	=
com.caucho.server.dispatch.Invocation(com.caucho.server.dispatch.ServletIn=
vocation).service(javax.servlet.ServletRequest, =
javax.servlet.ServletResponse) line: 287=09
> 	com.caucho.server.http.HttpRequest.handleRequest() line: 802=09
> 	com.caucho.network.listen.TcpSocketLink.dispatchRequest() line: =
731=09
> 	com.caucho.network.listen.TcpSocketLink.handleRequest(boolean) =
line: 693=09
> 	=
com.caucho.network.listen.TcpSocketLink.handleRequestsImpl(boolean) =
line: 677=09
> 	com.caucho.network.listen.TcpSocketLink.handleRequests(boolean) =
line: 623=09
> 	com.caucho.network.listen.AcceptTask.doTask() line: 107=09
> 	=
com.caucho.network.listen.AcceptTask(com.caucho.network.listen.ConnectionR=
eadTask).runThread() line: 98=09
> 	=
com.caucho.network.listen.AcceptTask(com.caucho.network.listen.ConnectionR=
eadTask).run() line: 81=09
> 	com.caucho.network.listen.AcceptTask.run() line: 65=09
> 	com.caucho.env.thread.ResinThread.runTasks() line: 164=09
> 	com.caucho.env.thread.ResinThread.run() line: 130=09


