Attaching a patch that adjusts the DOMResponseWriter so that all the relevant URLs used by the bridge are run through the ExternalContext.getResourceURL method. This is done without using any configuration parameter because it will only be done when required - its irrelevant whether or not we are in synchronous mode. I have not applied this patch to the trunk yet because it doesn't quite work yet.
After setting the Tomcat context to not use cookies for jsessionid and applying this patch, I ran Auction Monitor. The initial behaviour is that:
1) The initial page loads and the page is built with the bridge configuration URI values having the jsessionid properly encoded.
2) The first receive-updates request is made to the server and includes the jsessionid:
http://localhost:8080/auctionMonitor/block/receive-updates;jsessionid=3D38C0FCF3D632CD190D70366E14FDBC
3) The response from that request contains the new times as expected but also includes a new script update for the configuration values of the bridge. This includes new values for the URLs that don't included the encoded jsessionid:
<update address="LsZblvYjadH6yftBebmHmg:1:configuration-script" tag="script"><attribute name="id"><Unable to render embedded object: File (1:configuration-script]]></attribute><attribute name="type"><) not found.[CDATA[text/javascript]]></attribute><content><![CDATA[window.disposeViewsURI = '/push-server/block/dispose-views';
var container = 'LsZblvYjadH6yftBebmHmg:1:configuration-script'.asElement().parentNode;
container.bridge = new Ice.Community.Application({optimizedJSListenerCleanup: false,session: 'LsZblvYjadH6yftBebmHmg',view: 1,synchronous: false,connectionLostRedirectURI: null,sessionExpiredRedirectURI: null,serverErrorRetryTimeouts: [1000,2000,4000], connection: {blockUI: false,context: '/auctionMonitor/', sendReceiveUpdatesURI: '/auctionMonitor/block/send-receive-updates',pingURI: '/auctionMonitor/block/ping',receiveUpdatesURI: '/auctionMonitor/block/receive-updates',receiveUpdatedViewsURI: '/push-server/block/receive-updated-views',heartbeat:
{interval: 50000,timeout: 30000,retries: 3}
,timeout: 60000},messages: {sessionExpired: 'User Session Expired',connectionLost: 'Network Connection Interrupted',serverError: 'Server Internal Error',description: 'To reconnect click the Reload button on the browser or click the button below',buttonText: 'Reload'}}, container);]]></content></update>
4) The next receive-updates request is then sent out without the jsessionid:
http://localhost:8080/auctionMonitor/block/receive-updates
5) This causes a <session-expired/> update and the Session Expired dialog is shown.
So the current problem is that during some processing a diff is detected in the JavaScript configuration, likely because the jsessionid is not being encoded, and sending this update back. It's unclear why the jsessionid is not being encoded. It's likely somewhere in Tomcat's algorithm for how it determines why a URL gets a encoded.
It turns out that simply adding a configuration parameter is not going to solve the problem. To properly do URL rewriting (encode the jsessionid parameter in the URL), you are supposed to use the HttpServletResponse.encodeURL method. This is exposed in the JSF via ExternalContext,encodeResourceURL. Each URL that needs to have the jsessionid written on to it should be run through this method. The JavaDoc for HttpServletResponse.encodeURL states that, to be robust, all URLs emitted by the servlet or framework should be run through this method. The container (e.g. Tomcat) is responsible for deciding whether or not to add the jsessionid. So the first step is to properly use the encodeResourceURL method for those URLs that the bridge uses to make various requests.
Typically, the container detects whether or not to actually do the URL rewriting. The main scenario would be when the client has cookies disabled. However, it's possible that the container also has a switch for adjusting how the jsessionid is passed back and forth. For example, with Tomcat, you can specify as part of the Context configuration that cookies should not be used for jsessionid communication:
<Context cookies="false">
This allows you to leave cookies enabled in the client, but still use URL rewriting for passing the jsessionid.