diff --git a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/ClientContainer.java b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/ClientContainer.java index b1014515a58..0e1bb7f1e72 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/ClientContainer.java +++ b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/ClientContainer.java @@ -114,6 +114,18 @@ public class ClientContainer extends ContainerLifeCycle implements WebSocketCont client.addManaged(client.getHttpClient()); } + /** + * Create a {@link javax.websocket.WebSocketContainer} using the supplied + * {@link HttpClient} for environments where you want to configure + * SSL/TLS or Proxy behaviors. + * + * @param httpClient the HttpClient instance to use + */ + public ClientContainer(final HttpClient httpClient) + { + this(new SimpleContainerScope(WebSocketPolicy.newClientPolicy()), httpClient); + } + /** * This is the entry point for ServerContainer, via ServletContext.getAttribute(ServerContainer.class.getName()) * diff --git a/jetty-websocket/javax-websocket-client-impl/src/test/java/examples/SecureClientContainerExample.java b/jetty-websocket/javax-websocket-client-impl/src/test/java/examples/SecureClientContainerExample.java new file mode 100644 index 00000000000..dbba5d2365c --- /dev/null +++ b/jetty-websocket/javax-websocket-client-impl/src/test/java/examples/SecureClientContainerExample.java @@ -0,0 +1,84 @@ +// +// ======================================================================== +// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package examples; + +import java.net.URI; +import java.util.concurrent.TimeUnit; +import javax.websocket.ClientEndpointConfig; +import javax.websocket.WebSocketContainer; + +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.util.component.LifeCycle; +import org.eclipse.jetty.util.ssl.SslContextFactory; +import org.eclipse.jetty.websocket.jsr356.ClientContainer; + +public class SecureClientContainerExample +{ + public static void main(String[] args) + { + WebSocketContainer client = null; + try + { + URI echoUri = URI.create("wss://echo.websocket.org"); + client = getConfiguredWebSocketContainer(); + + ClientEndpointConfig clientEndpointConfig = ClientEndpointConfig.Builder.create() + .configurator(new OriginServerConfigurator("https://websocket.org")) + .build(); + EchoEndpoint echoEndpoint = new EchoEndpoint(); + client.connectToServer(echoEndpoint, clientEndpointConfig, echoUri); + System.out.printf("Connecting to : %s%n", echoUri); + + // wait for closed socket connection. + echoEndpoint.awaitClose(5, TimeUnit.SECONDS); + } + catch (Throwable t) + { + t.printStackTrace(); + } + finally + { + /* Since javax.websocket clients have no defined LifeCycle we + * want to either close/stop the client, or exit the JVM + * via a System.exit(), otherwise the threads this client keeps + * open will prevent the JVM from terminating naturally. + * @see https://github.com/eclipse-ee4j/websocket-api/issues/212 + */ + LifeCycle.stop(client); + } + } + + /** + * Since javax.websocket does not have an API for configuring SSL, each implementation + * of javax.websocket has to come up with their own SSL configuration mechanism. + * + * @return the client WebSocketContainer + * @see javax.websocket issue #210 + */ + public static WebSocketContainer getConfiguredWebSocketContainer() throws Exception + { + SslContextFactory ssl = new SslContextFactory.Client(); + ssl.setExcludeCipherSuites(); // echo.websocket.org use WEAK cipher suites + HttpClient httpClient = new HttpClient(ssl); + ClientContainer clientContainer = new ClientContainer(httpClient); + clientContainer.getClient().addManaged(httpClient); // allow clientContainer to own httpClient (for start/stop lifecycle) + clientContainer.start(); + return clientContainer; + } +} diff --git a/jetty-websocket/javax-websocket-client-impl/src/test/java/examples/SecureWebSocketContainerExample.java b/jetty-websocket/javax-websocket-client-impl/src/test/java/examples/SecureWebSocketContainerExample.java index 50f2c3fecda..b736f10a2e4 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/test/java/examples/SecureWebSocketContainerExample.java +++ b/jetty-websocket/javax-websocket-client-impl/src/test/java/examples/SecureWebSocketContainerExample.java @@ -34,18 +34,11 @@ public class SecureWebSocketContainerExample { public static void main(String[] args) { - String destUri = "wss://echo.websocket.org"; - if (args.length > 0) - { - destUri = args[0]; - } - WebSocketContainer client = null; try { + URI echoUri = URI.create("wss://echo.websocket.org"); client = getConfiguredWebSocketContainer(); - URI echoUri = new URI(destUri); - ClientEndpointConfig clientEndpointConfig = ClientEndpointConfig.Builder.create() .configurator(new OriginServerConfigurator("https://websocket.org")) .build();