I would like to propose a programmatic way of initiating a handshake:
public interface ServerContainer {
// ..
boolean doHandshake(HandshakeRequest req, HandshakeResponse res, ServerEndpointConfigurator sec);
}
If HandhsakeRequest/Response had methods to expose the raw request/response:
public interface HandshakeRequest {
// ..
<T> T getRequest(T requestClass);
}
public interface HandshakeResponse {
// ..
<T> T getResponse(T responseClass);
}
then I believe (but could be wrong) the logic for doHandshake should be very straight forward:
boolean doHandshake(HandshakeRequest req, HandshakeResponse res, ServerEndpointConfigurator sec) {
HttpServletRequest servletRequest = request.getRequest(HttpServletRequest.class);
HttpServletResponse servletResponse = response.getResponse(HttpServletResponseclass);
// Check or set headers
// Check origin, subprotocols, and obtain endpoint instance via ServerEndpointConfigurator
// Create HttpUpgradeHandler and call servletRequest.upgrade(handler)
return true;
}
Why does this matter?
1) We already have a concrete proposal for programmatic deployment that will allow Servlet developers to use Servlet container lifecycle points. This continues the same theme by allowing Servlet developers to initiate the handshake from a Servlet or Filter. Scott Ferguson referred to it as the "launch websockets from a plain servlet" option in a recent discussion.
2) Virtually all pre-existing Servlet container WebSocket APIs including Tomcat, Jetty, Glassfish, and Resin have some such option. That's a good indication that having this option makes sense.
3) There are many Java products and frameworks installed as a single Servlet that serve as the "front controller" for all incoming requests at a specific URI space. This option would allow them to also integrate WebSocket handshakes directly into their processing without requiring a separate artifact, i.e. ServerEndpointConfigurator, which is more of an API than an SPI.
4) This completes the bridge between the Servlet and the WebSocket APIs without introducing a dependency. On one side the Servlet API offers the HttpServletRequest upgrade method. On the other WebSocket implementations *somehow* call it. It makes sense to have a public API on something that all implementations will have to do anyway.
I believe this is very important for JSR-356 adoption beyond just applications and should be simple enough to do. Or to look at it from the opposite side, are there any reasons not to have this?
Rossen