In Magnolia we currently have issues handling path parameters such as JSESSIONID. Path parameters are part of the URL and are preceded by a semicolon. The semicolon is a reserved character in URLs.
After MAGNOLIA-3716 - Getting issue details... STATUS we started seeing JSESSIONID appearing more often. We're now asking the servlet container to encode the redirect url before returning it, it will include the JSESSIONID if it thinks its needed.
Jetty has always included the JSESSIONID path parameter in the return from HttpServletRequest.getRequestURI(), as of version 6.0.33 Tomcat does too. See https://issues.apache.org/bugzilla/show_bug.cgi?id=51833 Arguably this is the correct behaviour. It is up to the web application to parse the returned uri and strip path parameters from it.
In Magnolia we're not doing this, which leads to a number of problems.
Problems
Mime types are not set correctly
In ContentTypeFilter we use the extension to lookup the correct mime type. However the extension we're looking for is jpg;JSESSIONID=123.
This was reported in MAGNOLIA-3841 - Getting issue details... STATUS
ServletDispatchingFilter fails to map requests
When the URI contains a JSESSIONID ServletDispatchingFilter does not match it to the servlet.
It uses the uri in AggregationState if a WebContext is present, otherwise it takes it from getRequestURI(). See Mapping.findMatcher().
This is the cause of MAGNOLIA-4911 - Getting issue details... STATUS It was however fixed by using the Servlet 3.0 feature tracking-mode=cookie, this needs to be reverted, see MAGNOLIA-5356 - Getting issue details... STATUS
Page rendering fails with 404
When a JSESSIONID is present in the URI AggregatorFilter can't find the content because its looking for a node having it in its name.
Note that this only happens when not using an extension, this is because URI2RepositoryMapping#getHandle strips of the extension and with it the path parameters.
http://demopublic.magnolia-cms.com/demo-project;jsessionid=EE3DB6042B1B57AD55C2633428F44496
Proposed fix
We should always strip the path parameters from the return of HttpServletRequst.getRequestURI() and HttpServletRequest.getRequestURL(). This should be added in ServletUtil.getRequestURI(), ServletUtil.getOriginalRequestURI(), ServletUtil.getRequestURL(), and ServletUtil.getOriginalRequestURL(). These are used by ContentTypeFilter when it populates AggregationState, so the AggregationState is then correct. This fixes all three problems listed above.
We should also use ServletUtil.getRequestURI() in Mapping.findMatcher(), see above.
In AdminCentral we're using semicolons in the URI, as a separator between sub app and parameters. However this is in the fragment part and the fix described does not break this. For instance http://demo.magnolia-cms.com/.magnolia/admincentral#app:contacts:detail;/vvangogh:edit
Other identified problems that need to be addressed
These come from the use of getRequestURI and getRequestURL, problems stemming from the JSESSIONID being in aggregation state are not listed since those would go away with the proposed fix.
- info.magnolia.cms.filters.InstallFilter#doFilter
- returns HTTP 500 when given http://localhost:8080/.magnolia/installer/start;JSESSIONID=123
- info.magnolia.dam.DamDownloadServlet#process
- goes into a redirect loop when asking for an asset where the node name does not match the file name stored on the asset
- after renaming /demo-features/stage/component/940x320_demo01 to /demo-features/stage/component/940x320_demo01-xx
- access http://localhost:8080/dam/demo-features/stage/component/940x320_demo01-xx;JSESSIONID=123
- goes into a redirect loop when asking for an asset where the node name does not match the file name stored on the asset
- info.magnolia.cms.filters.ContextFilter#doFilter
- puts the JSESSIONID into MDC
- info.magnolia.voting.voters.BasePatternVoter#resolveURIFromValue
- when its subclasses URIPatternVoter and URIRegexVoter are used with HttpServletRequest they will not match if a JSESSIONID is present
- info.magnolia.context.RequestAttributeStrategy#getAttribute
- querying for "requestURI" will return the URI with JSESSIONID
- info.magnolia.cms.security.auth.callback.RedirectClientCallback#handle
- risk of a redirect loop if requestURI has JSESSIONID
- info.magnolia.module.admininterface.AdminTreeMVCServlet
- fails with: "No tree handler for [resources;JSESSIONID=123] found"
- info.magnolia.cms.filters.RangeSupportFilter#wrapResponse anon#isRequestValid
- will generate an etag that includes the JSESSIONID
We should also investigate what effect it has on cache keys, see:
- info.magnolia.module.cache.executor.Store#makeCachedEntry
- info.magnolia.module.cache.filter.CachedRedirect
- info.magnolia.module.cache.filter.CachedError
- info.magnolia.module.cache.filter.InMemoryCachedEntry
- info.magnolia.module.cache.filter.DelegatingBlobCachedEntry
1 Comment
Marcel Stör
If it'd be ok that Magnolia always requires (session) cookies to be enabled then maybe this should be considered: http://boncey.org/2007_1_8_purging_jsessionid