[undertow-dev] How to access the http headers in Endpoint.onOpen ?

Stuart Douglas sdouglas at redhat.com
Thu Feb 9 16:55:37 EST 2017


I think you will need to take this up with the Websocket EG, I think
Undertow follows the spec as it is currently implemented, so I don't
really want to change it.

Stuart

On Fri, Feb 10, 2017 at 4:09 AM, Angelo Salvade
<angelo.salvade at gmail.com> 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
>
> _______________________________________________
> undertow-dev mailing list
> undertow-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/undertow-dev


More information about the undertow-dev mailing list