Jetty 8.1.1 Websocket client handshake


Tomer Epstein

I am using Jetty 8.1.1 Websocket client api.
I need to use ("Sec-WebSocket-Protocol", "xsCrossfire")and update the title("Authorization", "Basic TLVWQMZqRr2hasYnZoI=")

WebSocketClientFactory factory = new WebSocketClientFactory();
factory.start();
client = factory.newWebSocketClient();
client.getCookies().put("Sec-WebSocket-Protocol", "xsCrossfire");
client.getCookies().put("Authorization", "Basic TLVWQMZqRr2hasYnZoI=");
Future<Connection> conn = client.open(uri, (WebSocket) this);
System.out.printf("Connecting to : %s%n", uri);

The requirement looks like:

Host: iltlvl262:8000\r\n
Upgrade: websocket\r\n
Connection: Upgrade\r\n
Sec-WebSocket-Version: 13\r\n
Sec-WebSocket-Key: FHKTsICO2vqGCxXVwLkH4Q==\r\n
Cookie: Sec-WebSocket-Protocol=xsCrossfire\r\n
Cookie: Authorization="Basic TLVWQMZqRr2hasYnZoI="\r\n

Expected requirements:

Host: iltlvl262:8000\r\n
Upgrade: websocket\r\n
Connection: Upgrade\r\n
Sec-WebSocket-Version: 13\r\n
Sec-WebSocket-Key: FHKTsICO2vqGCxXVwLkH4Q==\r\n
Sec-WebSocket-Protocol: xsCrossfire\r\n
Authorization: "Basic TLVWQMZqRr2hasYnZoI="\r\n

How to properly implement handshake in version 8.1.1?

Joakim Erdfelt

Some good news and some bad news.

One, the good news:

To set Sec-WebSocket-Protocolthe title, use the following.

client.setProtocol("xsCrossfire");

before useclient.open()

Next, the bad news:

With Jetty 8.x, you cannot set arbitrary non-websocket headers. This is due to how early experimental drafts of WebSocket were written. You are simply not allowed to set arbitrary headers as per the earlier spec draft, so the Jetty 8.x-era implementation just doesn't allow it.

However, things changed with the finalization of RFC6455 (the official WebSocket specification) , all of which were incorporated into the Jetty 9.x codebase. 100% RFC6455 compliant . (Note: Jetty 8 is 100% RFC6455 compliant on the server side. Jetty8 is also 100% compliant on the RFC6455 protocol used by the server and client. However, functionally, Jetty 8 is only partially compliant on the client and API point of view. )

The decision for Jetty 7 and Jetty 8 is to keep old experimental drafts for those early adopters and older browsers (Safari 5.x) who are still using them. This decision prevents us from allowing behavior that was expressly prohibited in the old experimental draft.

Starting with Jetty 9.x, all old experimental drafts of websockets have been removed, leaving only support for RFC6455 , which allows Jetty to open up more features that were previously not allowed. This includes arbitrary headers on WebSocketClient.

Jetty 9.1 WebSocket Client Example

import java.io.IOException;
import java.net.URI;
import java.util.concurrent.Future;

import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.WebSocketAdapter;
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
import org.eclipse.jetty.websocket.client.WebSocketClient;

public class ExampleClient
{
    public static class ExampleSocket extends WebSocketAdapter
    {
        @Override
        public void onWebSocketText(String message)
        {
            try
            {
                // echo the message
                getRemote().sendString(message);
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args)
    {
        try
        {
            new ExampleClient().demo();
        }
        catch (Throwable t)
        {
            t.printStackTrace(System.err);
        }
    }

    public void demo() throws Exception
    {
        WebSocketClient client = new WebSocketClient();
        try
        {
            client.start();
            ClientUpgradeRequest request = new ClientUpgradeRequest();
            request.setSubProtocols("xsCrossfire");
            request.setHeader("Authorization","Basic TLVWQMZqRr2hasYnZoI=");

            URI wsUri = URI.create("ws://iltlvl262:8000/echo");

            ExampleSocket socket = new ExampleSocket();
            Future<Session> future = client.connect(socket,wsUri,request);

            future.get(); // wait for connect

            socket.getRemote().sendString("hello"); // send message
        }
        finally
        {
            client.stop();
        }
    }
}

Also note that as of Jetty 9.1, the (JSR-356) API is even fully supported.javax.websocket

Same example using javax.websocket on Jetty 9.1

import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.websocket.ClientEndpoint;
import javax.websocket.ContainerProvider;
import javax.websocket.OnMessage;
import javax.websocket.Session;
import javax.websocket.WebSocketContainer;

public class ExampleClient
{
    @ClientEndpoint(subprotocols = { "xsCrossfire" }, 
                    configurator = ExampleClient.Configurator.class)
    public static class ExampleSocket
    {
        @OnMessage
        public String onMessage(String msg)
        {
            return msg; // echo
        }
    }

    public static class Configurator 
           extends javax.websocket.ClientEndpointConfig.Configurator
    {
        @Override
        public void beforeRequest(Map<String, List<String>> headers)
        {
            List<String> authvalues = new ArrayList<>();
            authvalues.add("Basic TLVWQMZqRr2hasYnZoI=");
            headers.put("Authorization", authvalues);
            super.beforeRequest(headers);
        }
    }

    public static void main(String[] args)
    {
        try
        {
            new ExampleClient().demo();
        }
        catch (Throwable t)
        {
            t.printStackTrace(System.err);
        }
    }

    public void demo() throws Exception
    {
        WebSocketContainer client = ContainerProvider.getWebSocketContainer();

        ExampleSocket socket = new ExampleSocket();
        URI wsUri = URI.create("ws://iltlvl262:8000/echo");

        Session session = client.connectToServer(socket,wsUri);
        session.getAsyncRemote().sendText("Hello");
    }
}

Related


Jetty Websocket Client: Invalid UTF8

ian Any advice on how to fix this would be greatly appreciated. I am using jetty websocket (9.2.6.v20141205) client to connect to tomcat7 websocket server via apache2 proxy_wstunnel. I am getting the following error intermittently: org.eclipse.jetty.util.Utf8A

Jetty Websocket Client: Invalid UTF8

ian Any advice on how to fix this would be greatly appreciated. I am using jetty websocket (9.2.6.v20141205) client to connect to tomcat7 websocket server via apache2 proxy_wstunnel. I am getting the following error intermittently: org.eclipse.jetty.util.Utf8A

How to authenticate Websocket client in jetty?

Pradeep Agarwal I am using embedded Jetty on the server side which will accept http and websocket requests. I am using org.eclipse.jetty.security.authentication.FormAuthenticator to authenticate users. Once the user is logged in, my javascript code will open a

How to authenticate Websocket client in jetty?

Pradeep Agarwal I am using embedded Jetty on the server side which will accept http and websocket requests. I am using org.eclipse.jetty.security.authentication.FormAuthenticator to authenticate users. Once the user is logged in, my javascript code will open a

Handshake error with WebSocket python server and JS client

lb I'm trying to establish communication between a python script (which will do a lot of calculations on data that can't be done in javascript and send it as json) and a javascript client. My python server has the following code: import socket import sys from

Handshake error with WebSocket python server and JS client

lb I'm trying to establish communication between a python script (which will do a lot of calculations on data that can't be done in javascript and send it as json) and a javascript client. My python server has the following code: import socket import sys from

Handshake error with WebSocket python server and JS client

lb I'm trying to establish communication between a python script (which will do a lot of calculations on data that can't be done in javascript and send it as json) and a javascript client. My python server has the following code: import socket import sys from

Configure Jetty WebSocket client to use proxy

Gregory Borel I haven't found any solution yet. It seems Jettythat this feature is not supported yet. I may be wrong so please enlighten me. I have a very simple Javaclient that can connect to a Javaserver localhost:8080. I want to add a transparent proxy betw

Configure Jetty WebSocket client to use proxy

Gregory Borel I haven't found any solution yet. It seems Jettythat this feature is not supported yet. I may be wrong so please enlighten me. I have a very simple Javaclient that can connect to a Javaserver localhost:8080. I want to add a transparent proxy betw

Jetty Java Websocket client not connecting to server

Ravi I am using a Java Jetty client written as [websocket-client 9.3.8.RC0]. In our case, the Websocket server was a bit odd. It accepts requests in the format. wss://192.168.122.1:8443/status? -xsrf-=tokenValue The token value is received in the first login P

Configure Jetty WebSocket client to use proxy

Gregory Borel I haven't found any solution yet. It seems Jettythat this feature is not supported yet. I may be wrong so please enlighten me. I have a very simple Javaclient that can connect to a Javaserver localhost:8080. I want to add a transparent proxy betw

Configure Jetty WebSocket client to use proxy

Gregory Borel I haven't found any solution yet. It seems Jettythat this feature is not supported yet. I may be wrong so please enlighten me. I have a very simple Javaclient that can connect to a Javaserver localhost:8080. I want to add a transparent proxy betw

Websocket client sends [FIN, ACK] right after handshake

red black My project uses WebSocket protocol for communication. The server side is implemented Cin and for the client side I Qt 4.8.1use to build a simple browser to run HTML and JavaScript code. I have a question about Qt framework. Immediately after the hand

Websocket client sends [FIN, ACK] right after handshake

red black My project uses WebSocket protocol for communication. The server side is implemented Cin and for the client side I Qt 4.8.1use to build a simple browser to run HTML and JavaScript code. I have a question about Qt framework. Immediately after the hand

Websocket client sends [FIN, ACK] right after handshake

red black My project uses WebSocket protocol for communication. The server side is implemented Cin and for the client side I Qt 4.8.1use to build a simple browser to run HTML and JavaScript code. I have a question about Qt framework. Immediately after the hand

TLSv1 handshake failed

nablex: (Disclaimer: I'm definitely not a security expert or a Windows expert on this) Establish: Server on our side: Java 1.6 on Windows 2003 Server (bouncycastle added to security file) 3rd party client: Windows 2008 Server with talktalk All renegotiation sy

TLSv1 handshake failed

nablex: (Disclaimer: I'm definitely not a security expert or a Windows expert on this) Establish: Server on our side: Java 1.6 on Windows 2003 Server (bouncycastle added to security file) 3rd party client: Windows 2008 Server with talktalk All renegotiation sy

TLSv1 handshake failed

nablex: (Disclaimer: I'm definitely not a security expert or a Windows expert on this) Establish: Server on our side: Java 1.6 on Windows 2003 Server (bouncycastle added to security file) 3rd party client: Windows 2008 Server with talktalk All renegotiation sy

Jetty 9 WebSocket client issue when using secure connection

Alex I am writing a WebSocket client in a Java application using the Jetty 9.4.18 library. I'm new to WebSockets, so I started to test using the two example classes from the Jetty documentation, and then connect toecho.websocket.org When connecting without SSL