As you have discovered, this isn't spelled out in the JSR356 spec. The JSR356 spec is very simple/naive, it doesn't cover a lot of moderate to advanced concepts.
We follow the modifyHandshake and user properties as outlined in this stackoverflow answer ... http://stackoverflow.com/questions/17936440/accessing-httpsession-from-httpservletrequest-in-a-web-socket-serverendpoint/17994303#17994303 Of note, it appears that Apache Tomcat also follows this behavior. Joakim Erdfelt / [email protected] On Thu, Feb 9, 2017 at 10:07 AM, Angelo Salvade <[email protected]> wrote: > Hi > > If I understand the Java API for WebSocket Spec (JSR 356) correctly, > the only way to access the http headers and the http session is by > the parameter 'HandshakeRequest request' of > ServerEndpointConfig.Configurator.modifyHandshake > with the methods HandshakeRequest.getHeaders and > HandshakeRequest.getHttpSession. > > From there, the only way to pass this data to Endpoint.onOpen seems to > be by EndpointConfig.getUserProperties > because 'EndpointConfig config' is a parameter of Endpoint.onOpen. > > The problem is, that according to the documentation, EndpointConfig is > shared with all sessions and therefore this won't work. > See also https://java.net/jira/browse/WEBSOCKET_SPEC-218 and > https://java.net/jira/browse/WEBSOCKET_SPEC-235. > However, I did some testing with Undertow and Jetty. > > Please have a look at the following test code: > > static ServerEndpointConfig.Configurator SERVER_CONFIGURATOR = new > ServerEndpointConfig.Configurator() { > @Override public <T> T getEndpointInstance(Class<T> endpointClass) { > return endpointClass.cast(new Endpoint() { > @Override public void onOpen(Session session, > EndpointConfig config) { > System.out.printf( > "onOpen - config: %s, session: %s%n", > > config.getUserProperties().keySet().stream().filter(k -> > k.startsWith("Header")).collect(Collectors.toSet()), > > session.getUserProperties().keySet().stream().filter(k -> > k.startsWith("Header")).collect(Collectors.toSet()) > ); > } > @Override public void onClose(Session session, CloseReason > closeReason) { > } > @Override public void onError(Session session, Throwable > throwable) { > } > }); > } > @Override public void modifyHandshake(ServerEndpointConfig sec, > HandshakeRequest request, HandshakeResponse response) { > sec.getUserProperties().putAll(request.getHeaders()); > } > @Override public String getNegotiatedSubprotocol(List<String> > supported, List<String> requested) { > return ""; > } > @Override public List<Extension> > getNegotiatedExtensions(List<Extension> installed, List<Extension> > requested) { > return new ArrayList<>(); > } > @Override public boolean checkOrigin(String originHeaderValue) { > return true; > } > }; > > static void clientConnect(WebSocketContainer container) throws Exception { > for (String header : Arrays.asList("Header1", "Header2")) { > container.connectToServer( > new Endpoint() { > @Override public void onOpen(Session session, > EndpointConfig config) { > } > }, > ClientEndpointConfig.Builder.create().configurator(new > ClientEndpointConfig.Configurator() { > @Override public void beforeRequest(Map<String, > List<String>> headers) { > headers.put(header, Collections.singletonList("foo")); > } > }).build(), > URI.create("ws://localhost:" + PORT + PATH) > ); > TimeUnit.SECONDS.sleep(1L); > } > } > > You'll find the source code in the attachments and under: > https://github.com/softappeal/yass/blob/master/java/test/ch/ > softappeal/yass/transport/ws/test/up/UserPropertiesTest.java > https://github.com/softappeal/yass/blob/master/java/test/ch/ > softappeal/yass/transport/ws/test/up/UndertowUserPropertiesTest.java > https://github.com/softappeal/yass/blob/master/java/test/ch/ > softappeal/yass/transport/ws/test/up/JettyUserPropertiesTest.java > > These are the outputs of the tests: > > UndertowUserPropertiesTest (io.undertow:undertow- > websockets-jsr:1.4.8.Final) > onOpen - config: [Header1], session: [Header1] > onOpen - config: [Header1, Header2], session: [Header1, Header2] > > JettyUserPropertiesTest > (org.eclipse.jetty.websocket:javax-websocket-server-impl:9.4.1.v20170120) > onOpen - config: [Header1], session: [Header1] > onOpen - config: [Header2], session: [Header2] > > So the questions are: > > Jetty and Undertow seem to copy EndpointConfig.getUserProperties to > Session.getUserProperties. > Is this behaviour guaranteed? Where does it say so in the spec? > > Jetty seems to make a new EndpointConfig.getUserProperties for each > session. > This seems NOT to be according to the spec. > This behaviour would be THE SOLUTION to my problem. > > Undertow seems to share EndpointConfig.getUserProperties over all > sessions. > This seems to be according to the spec. > But so it's not possible to pass the headers to Endpoint.onOpen. > > So can we say the WebSocket API should behave like Jetty? > > Regards, > Angelo > > _______________________________________________ > jetty-users mailing list > [email protected] > To change your delivery options, retrieve your password, or unsubscribe > from this list, visit > https://dev.eclipse.org/mailman/listinfo/jetty-users >
_______________________________________________ jetty-users mailing list [email protected] To change your delivery options, retrieve your password, or unsubscribe from this list, visit https://dev.eclipse.org/mailman/listinfo/jetty-users
