Reputation: 51
I want to write my own "ServletContainerInitializer" that adds my local filter to the ServletContext. And I also want to manage ordering of ServletContainerInitializer invocation so that my local filter will get register and hit by the request before the websocket upgrade filter.
I want to know how to initialize my local ServletContainerInitializer ?
Upvotes: 2
Views: 1583
Reputation: 49515
First, ServletContextInitializer
are not ordered, that feature is not part of the Servlet spec. You can't accomplish that part of your question. (maybe in a future version of the Servlet spec)
Next, filtering on WebSocket Upgrade requests is highly discouraged, and a cause for a large number of problems in WebSocket. You have to be very careful to not do any of the following.
In short, the only safe things you can do are
As all other accesses on the request or response objects will change the state of the request and prevent an upgrade.
The fact that Jetty has a WebSocketUpgradeFilter is just our choice on implementation for the JSR-356 (aka javax.websocket) spec. It is added by a server side ServletContextInitializer
and is forced to be first, always.
In practice you should work with the expectation that upgrades occur before the Servlet processing (and this includes filters), as this is how the spec is written. There are open bugs against the spec about how interactions with filters and whatnot should be treated, but those are currently unanswered and loosely scheduled for a future version of the javax.websocket spec.
Future versions of Jetty will likely change from using a filter to using something internal that cooperates at the path mapping level, merging the logic from the Servlet spec and the WebSocket spec into a single new set of rules.
Since this question comes up often, i've ticked the community wiki flag.
The number one reason this gets asked is because there is some authentication or authorization logic built into a filter on your project.
If this is the case, you have 2 options.
Refactor out the authentication and/or authorization logic into a standalone classs, unassociated with your filter.
Build a new Filter
and a new ServerEndpointConfig.Configurator
that uses this now common logic to accomplish the end results you need. Note that you do not have access to the entire HttpServletRequest
object when under a potential WebSocket upgrade, you only have access to the HandshakeRequest
object contents. (you can see the restrictions now)
Use the Servlet spec, and containers properly and implement / configure Security at the container level, which will always execute before websocket or servlets or filters. Thus dropping your security based Filters entirely.
Upvotes: 1