boolean secure = false;
String scheme = path.getScheme();
if (!("ws".equalsIgnoreCase(scheme) ||
"wss".equalsIgnoreCase(scheme))) {
throw new DeploymentException(sm.getString(
"wsWebSocketContainer.pathWrongScheme", scheme));
}
String host = path.getHost();
if (host == null) {
throw new DeploymentException(
sm.getString("wsWebSocketContainer.pathNoHost"));
}
int port = path.getPort();
Map<String,List<String>> reqHeaders = createRequestHeaders(host, port,
clientEndpointConfiguration.getPreferredSubprotocols(),
clientEndpointConfiguration.getExtensions());
clientEndpointConfiguration.getConfigurator().
beforeRequest(reqHeaders);
ByteBuffer request = createRequest(path, reqHeaders);
SocketAddress sa;
if (port == -1) {
if ("ws".equalsIgnoreCase(scheme)) {
sa = new InetSocketAddress(host, 80);
} else if ("wss".equalsIgnoreCase(scheme)) {
sa = new InetSocketAddress(host, 443);
secure = true;
} else {
throw new DeploymentException(
sm.getString("wsWebSocketContainer.invalidScheme"));
}
} else {
if ("wss".equalsIgnoreCase(scheme)) {
secure = true;
}
sa = new InetSocketAddress(host, port);
}
AsynchronousSocketChannel socketChannel;
try {
socketChannel =
AsynchronousSocketChannel.open(asynchronousChannelGroup);
} catch (IOException ioe) {
throw new DeploymentException(sm.getString(
"wsWebSocketContainer.asynchronousSocketChannelFail"), ioe);
}
Future<Void> fConnect = socketChannel.connect(sa);
AsyncChannelWrapper channel;
if (secure) {
SSLEngine sslEngine = createSSLEngine(
clientEndpointConfiguration.getUserProperties());
channel = new AsyncChannelWrapperSecure(socketChannel, sslEngine);
} else {
channel = new AsyncChannelWrapperNonSecure(socketChannel);
}
// Get the connection timeout
long timeout = IO_TIMEOUT_MS_DEFAULT;
String timeoutValue = (String) clientEndpointConfiguration.getUserProperties().get(
IO_TIMEOUT_MS_PROPERTY);
if (timeoutValue != null) {
timeout = Long.valueOf(timeoutValue).intValue();
}
ByteBuffer response;
String subProtocol;
try {
fConnect.get(timeout, TimeUnit.MILLISECONDS);
Future<Void> fHandshake = channel.handshake();
fHandshake.get(timeout, TimeUnit.MILLISECONDS);
int toWrite = request.limit();
Future<Integer> fWrite = channel.write(request);
Integer thisWrite = fWrite.get(timeout, TimeUnit.MILLISECONDS);
toWrite -= thisWrite.intValue();
while (toWrite > 0) {
fWrite = channel.write(request);
thisWrite = fWrite.get(timeout, TimeUnit.MILLISECONDS);
toWrite -= thisWrite.intValue();
}
// Same size as the WsFrame input buffer
response = ByteBuffer.allocate(maxBinaryMessageBufferSize);
HandshakeResponse handshakeResponse =
processResponse(response, channel, timeout);
clientEndpointConfiguration.getConfigurator().
afterResponse(handshakeResponse);
// Sub-protocol
// Header names are always stored in lower case
List<String> values = handshakeResponse.getHeaders().get(
Constants.WS_PROTOCOL_HEADER_NAME_LOWER);
if (values == null || values.size() == 0) {
subProtocol = null;
} else if (values.size() == 1) {
subProtocol = values.get(0);
} else {
throw new DeploymentException(
sm.getString("Sec-WebSocket-Protocol"));
}
} catch (ExecutionException | InterruptedException | SSLException |
EOFException | TimeoutException e) {
throw new DeploymentException(
sm.getString("wsWebSocketContainer.httpRequestFailed"), e);
}
// Switch to WebSocket
WsRemoteEndpointImplClient wsRemoteEndpointClient =