users@grizzly.java.net

Re: WSS Upgrade Failed with AsyncHttpClient and Grizzly WebSockets

From: Scott McClure <mccluresc_at_gmail.com>
Date: Fri, 26 Oct 2012 00:37:14 -0400

Thanks! I didn't realize that createHttpServer was starting the server as
well (especially funny because many of the Jersey/Grizzly samples start the
server explicitly). When I actually looked at the implementation, I found
it was much easier to just skip the "convenience" and construct the
NetworkListener in my code instead. It all works now! For reference, the
following snippet for constructing the server worked:

        public SimpleServer() throws Exception {
            HttpServer webServer;
            SSLContextConfigurator sslContext = new
SSLContextConfigurator();
            sslContext.setKeyStoreFile(keyStorePath);
            sslContext.setKeyStorePass(keyStorePass);
            webServer = new HttpServer();
            NetworkListener listener = new NetworkListener("grizzly",
"localhost", 443);
            listener.setSecure(true);
            listener.setSSLEngineConfig(new
SSLEngineConfigurator(sslContext).setClientMode(false).setNeedClientAuth(false));
            listener.registerAddOn(new WebSocketAddOn());
            webServer.addListener(listener);
            WebSocketEngine.getEngine().register(new StreamApplication());
            webServer.start();
        }

On Thu, Oct 25, 2012 at 7:22 PM, Ryan Lubke <ryan.lubke_at_oracle.com> wrote:

> The root of the problem is that the WebSocketAddon isn't actually being
> registered as Jersey is starting the server before handing back the server
> instance. AddOns currently aren't able to be dynamically registered. So
> for this, I would recommend logging an issue against Jersey to have an
> option
> to have server instances not being started automatically.
>
> The obvious thing to do then, as a workaround, is to stop the server, add
> the WebSocketAddon, and then start the server again, but it appears we're
> too aggressive with the listeners when the server is stopped. This is
> something we'll address for the next release.
>
> Here's a workaround that, while ugly, does get you moving forward:
>
>
>
> public SimpleServer() throws Exception {
> URI uri =
> UriBuilder.fromUri("https://localhost"<https://localhost>
> ).port(4443).build();
>
> HttpServer webServer;
> SSLContextConfigurator sslContext = new
> SSLContextConfigurator();
> sslContext.setKeyStoreFile(keyStorePath);
> sslContext.setKeyStorePass(keyStorePass);
> webServer =
> GrizzlyServerFactory.createHttpServer(uri, null, true,
> new
>
> SSLEngineConfigurator(sslContext).setClientMode(false)
>
> .setNeedClientAuth(false));
> NetworkListener l = webServer.getListener("grizzly");
> webServer.stop();
> webServer.addListener(l);
> // add the WebSocketFilter manually
> FilterChain c = l.getFilterChain();
> final int httpServerFilterIdx =
> c.indexOfType(HttpServerFilter.class);
>
> if (httpServerFilterIdx >= 0) {
> // Insert the WebSocketFilter right after HttpCodecFilter
> c.add(httpServerFilterIdx, new WebSocketFilter());
> }
> WebSocketEngine.getEngine().register(new
> EchoApplication());
> webServer.start();
> }
>
>
> mccluresc_at_gmail.com
> October 24, 2012 10:52 PM
> Hi,
>
> I am getting an HandshakeException ("Upgrade Failed") when I try to
> test WSS support with grizzly-websockets-2.2.16 and
> grizzly-http-client-1.2.
>
> My test-case is:
> import java.io.FileInputStream;
> import java.net.URI;
> import java.security.KeyStore;
> import java.util.concurrent.ExecutionException;
>
> import javax.net.ssl.SSLContext;
> import javax.net.ssl.TrustManagerFactory;
> import javax.ws.rs.core.UriBuilder;
>
> import org.glassfish.grizzly.http.server.HttpServer;
> import org.glassfish.grizzly.ssl.SSLContextConfigurator;
> import org.glassfish.grizzly.ssl.SSLEngineConfigurator;
> import org.glassfish.grizzly.websockets.HandshakeException;
> import org.glassfish.grizzly.websockets.WebSocketAddOn;
> import org.glassfish.grizzly.websockets.WebSocketEngine;
>
> import com.ning.http.client.AsyncHttpClient;
> import com.ning.http.client.AsyncHttpClientConfig;
> import com.ning.http.client.providers.grizzly.GrizzlyAsyncHttpProvider;
> import com.ning.http.client.websocket.DefaultWebSocketListener;
> import com.ning.http.client.websocket.WebSocket;
> import com.ning.http.client.websocket.WebSocketListener;
> import com.ning.http.client.websocket.WebSocketUpgradeHandler;
> import com.sun.jersey.api.container.grizzly2.GrizzlyServerFactory;
>
> public class WebSocketsTest {
> private static final String keyStorePath =
> WebSocketsTest.class.getResource("keystore").getFile();
> private static final String keyStorePass = "asdfgh";
> private static final String trustStorePath =
> WebSocketsTest.class.getResource("truststore").getFile();
> private static final String trustStorePass = "asdfgh";
>
> public static class SimpleServer {
> public SimpleServer() throws Exception {
> URI uri =
> UriBuilder.fromUri("https://localhost" <https://localhost>
> ).port(443).build();
> HttpServer webServer;
> SSLContextConfigurator sslContext = new
> SSLContextConfigurator();
> sslContext.setKeyStoreFile(keyStorePath);
> sslContext.setKeyStorePass(keyStorePass);
> webServer =
> GrizzlyServerFactory.createHttpServer(uri, null, true,
> new
> SSLEngineConfigurator(sslContext).setClientMode(false)
>
> .setNeedClientAuth(false));
> webServer.getListener("grizzly")
> .registerAddOn(new
> WebSocketAddOn());
> WebSocketEngine.getEngine().register(new
> StreamApplication());
> webServer.start();
> }
> }
>
> public static class SimpleClient {
> public SimpleClient() throws Exception {
> KeyStore trustStore =
> KeyStore.getInstance("JKS");
> trustStore.load(new
> FileInputStream(trustStorePath), trustStorePass.toCharArray());
> TrustManagerFactory tmf =
> TrustManagerFactory.getInstance("SunX509");
> tmf.init(trustStore);
> SSLContext context =
> SSLContext.getInstance("SSL");
> context.init(null, tmf.getTrustManagers(), null);
> AsyncHttpClientConfig config = new
> AsyncHttpClientConfig.Builder().setSSLContext(context).build();
> AsyncHttpClient c = new AsyncHttpClient(new
> GrizzlyAsyncHttpProvider(config), config);
> WebSocketListener listener = new
> DefaultWebSocketListener() {
> @Override
> public void onMessage(String message) {
> System.out.println("Received message: "
> + message);
> }
> };
> try {
> WebSocketUpgradeHandler handler = new
> WebSocketUpgradeHandler.Builder().addWebSocketListener(listener).build(
> );
> WebSocket socket =
> c.prepareGet("wss://localhost/test").execute(handler).get();
> socket.sendTextMessage("TEST");
> } catch (ExecutionException e) {
> if (e.getCause() instanceof
> HandshakeException) {
> HandshakeException handshake =
> (HandshakeException) e.getCause();
>
> System.out.println("HandshakeException with code: " +
> handshake.getCode() + " and message: " + handshake.getMessage());
> } else
> throw e;
> }
> }
> }
>
> public static void main(String[] args) throws Exception {
> SimpleServer s = new SimpleServer();
> SimpleClient c = new SimpleClient();
> }
> }
>
> My output is:
> Oct 25, 2012 1:47:29 AM
> org.glassfish.grizzly.http.server.NetworkListener start
> INFO: Started listener bound to [localhost:443]
> Oct 25, 2012 1:47:29 AM org.glassfish.grizzly.http.server.HttpServer
> start
> INFO: [HttpServer] Started.
> SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
> SLF4J: Defaulting to no-operation (NOP) logger implementation
> SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for
> further details.
> HandshakeException with code: 1002 and message: Upgrade failed
>
> Any suggestions? Thanks!
>
>