servlet icon indicating copy to clipboard operation
servlet copied to clipboard

Cross Context Dispatch

Open gregw opened this issue 4 years ago • 2 comments

Cross Context Dispatch is a surprisingly complex mechanism, with significant impacts on the complexity of handling session, security, async etc.

Containers are already allowed to disable ServletContext.getContext(String) and return null. We should go further and make it an optional feature in the specification so that a container can be considered compliant even if it never returns non null from getContext(String).

gregw avatar Jul 28 '21 02:07 gregw

On Mon, 26 Jul 2021 at 21:50, @markt-asf Mark Thomas [email protected] wrote: On 24/07/2021 03:18, @gregw Greg Wilkins wrote:

Mark et al,

If we have some months, then I'd very much like to deprecate/remove a few more things along the lines of my Less is More https://webtide.com/less-is-more-servlet-api/ blog. Specifically:

  • I would like to make cross context dispatch clearly an optional feature, so a container could still be compliant even if it never EVER returned non-null from ServletContext.getContext(String)

I generally agree that this adds a lot of complexity and that quite a few features have been added to the API over the years without fully defining the expected behaviour with a cross-context dispatch.

I'd be happy to see ServletContext.getContext(String) deprecated and then dropped from the API (as you suggest in your blog) but I see two potential issues with this.

  1. The Jakarta Platform specification. I suspect such a change would be problematic in the context of an EAR. Making it an optional feature addresses this concern. We'd need to work out the details and the TCK might need some tweaks but all of that should be doable.

  2. If the behaviour is optional then we still need to define the behaviour for all the cases that are currently problematic / ill-defined. If the behaviour still needs to be defined, we don't gain much by making it optional. There would still be benefits to container implementations that don't want to support cross-context. Clearly Jetty is one. Are there others? I'd say Tomcat is neutral on this. I don't recall any discussions in the Tomcat community around this topic.

gregw avatar Jul 28 '21 02:07 gregw

Currently jetty has good cross-context dispatch support. We think we have worked out solutions for most of the complexities. But generally it is a very seldom used feature and I think it is a mill stone around the neck of future innovation. If it became an optional feature, then we would give consideration to dropping it in future major releases as there would probably be some minor performance improvements for literally trillions of request - giving a good reason for it. We may then provide some limited support for it with more expensive mechanisms that only effect the applications that use it (taxation only with representation!).

I agree with your points 1. & 2. above, so we probably do need to start by defining all the behaviours affected by this. For the most part they are related to session life cycles and are illustrated by the following use-cases:

  • request to ContextA; getSession(true); forwards to ContextB; getSession(true) : two different sessions created both with same session ID and a single SetCookie header set.
  • request to ContextA; forwards to ContextB; getSession(true) ; returns to ContextA; getSession(true) : two different sessions created both with same session ID and a single SetCookie header set.
  • request to ContextA; include to ContextB; getSession(true) ; returns to ContextA; getSession(true) : two different sessions created both with same session ID and a single SetCookie header set (by the included request, which is not technically allowed to set response headers)
  • request to ContextA; flushBuffers(); include to ContextB; getSession(true) : ISE
  • request to ContextA; getSession(true); response sent; new request to ContextB with same session ID; getSession(true) : two different sessions created both with same session ID
  • request to ContextA; getSession(false).invalidate(); forwards to ContextB; getSession(true) : One session in contextB with a different session ID than was requested.
  • ContextA and ContextB are sharing a sessionID created by cross-context dispatch, but have different session idle times?
  • ContextA and ContextB are sharing a sessionID created by cross-context dispatch. Session is passivated in ContextA, request directly to ContextB invalidates the session: The session in ContextA is activated and then invalidated.

@janbartel can you expand on this list.

gregw avatar Jul 28 '21 02:07 gregw