Hi Stuart
Thanks for the answer.
Just to be sure:
Does it mean you agree with my assumption, that according to the spec,
it won't be possible to pass headers safely (due to multi-threading)
to Endpoint.onOpen?
FYI:
I also posted this issue to the mailing list jetty-users.
They are telling Tomcat also seems to implement the Jetty behavior.
This is against the spec but would be a more useful implementation and
it would solve the problem.
Please see
Regards,
Angelo
On Thu, Feb 9, 2017 at 10:55 PM, Stuart Douglas <sdouglas(a)redhat.com> wrote:
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(a)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/ya...
>
https://github.com/softappeal/yass/blob/master/java/test/ch/softappeal/ya...
>
https://github.com/softappeal/yass/blob/master/java/test/ch/softappeal/ya...
>
> 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(a)lists.jboss.org
>
https://lists.jboss.org/mailman/listinfo/undertow-dev