use of io.undertow.websockets.WebSocketExtension in project undertow by undertow-io.
the class ServerWebSocketContainer method connectToServer.
public Session connectToServer(final Endpoint endpointInstance, final ClientEndpointConfig config, WebSocketClient.ConnectionBuilder connectionBuilder) throws DeploymentException, IOException {
if (closed) {
throw new ClosedChannelException();
}
ClientEndpointConfig cec = config != null ? config : ClientEndpointConfig.Builder.create().build();
WebSocketClientNegotiation clientNegotiation = connectionBuilder.getClientNegotiation();
IoFuture<WebSocketChannel> session = connectionBuilder.connect();
Number timeout = (Number) cec.getUserProperties().get(TIMEOUT);
if (session.await(timeout == null ? DEFAULT_WEB_SOCKET_TIMEOUT_SECONDS : timeout.intValue(), TimeUnit.SECONDS) == IoFuture.Status.WAITING) {
//add a notifier to close the channel if the connection actually completes
session.cancel();
session.addNotifier(new IoFuture.HandlingNotifier<WebSocketChannel, Object>() {
@Override
public void handleDone(WebSocketChannel data, Object attachment) {
IoUtils.safeClose(data);
}
}, null);
throw JsrWebSocketMessages.MESSAGES.connectionTimedOut();
}
WebSocketChannel channel;
try {
channel = session.get();
} catch (UpgradeFailedException e) {
throw new DeploymentException(e.getMessage(), e);
}
EndpointSessionHandler sessionHandler = new EndpointSessionHandler(this);
final List<Extension> extensions = new ArrayList<>();
final Map<String, Extension> extMap = new HashMap<>();
for (Extension ext : cec.getExtensions()) {
extMap.put(ext.getName(), ext);
}
for (WebSocketExtension e : clientNegotiation.getSelectedExtensions()) {
Extension ext = extMap.get(e.getName());
if (ext == null) {
throw JsrWebSocketMessages.MESSAGES.extensionWasNotPresentInClientHandshake(e.getName(), clientNegotiation.getSupportedExtensions());
}
extensions.add(ExtensionImpl.create(e));
}
ConfiguredClientEndpoint configured = clientEndpoints.get(endpointInstance.getClass());
if (configured == null) {
synchronized (clientEndpoints) {
configured = clientEndpoints.get(endpointInstance.getClass());
if (configured == null) {
clientEndpoints.put(endpointInstance.getClass(), configured = new ConfiguredClientEndpoint());
}
}
}
EncodingFactory encodingFactory = EncodingFactory.createFactory(classIntrospecter, cec.getDecoders(), cec.getEncoders());
UndertowSession undertowSession = new UndertowSession(channel, connectionBuilder.getUri(), Collections.<String, String>emptyMap(), Collections.<String, List<String>>emptyMap(), sessionHandler, null, new ImmediateInstanceHandle<>(endpointInstance), cec, connectionBuilder.getUri().getQuery(), encodingFactory.createEncoding(cec), configured, clientNegotiation.getSelectedSubProtocol(), extensions, connectionBuilder);
endpointInstance.onOpen(undertowSession, cec);
channel.resumeReceives();
return undertowSession;
}
use of io.undertow.websockets.WebSocketExtension in project undertow by undertow-io.
the class ServerWebSocketContainer method connectToServerInternal.
private Session connectToServerInternal(final Endpoint endpointInstance, final ConfiguredClientEndpoint cec, WebSocketClient.ConnectionBuilder connectionBuilder) throws DeploymentException, IOException {
IoFuture<WebSocketChannel> session = connectionBuilder.connect();
Number timeout = (Number) cec.getConfig().getUserProperties().get(TIMEOUT);
IoFuture.Status result = session.await(timeout == null ? DEFAULT_WEB_SOCKET_TIMEOUT_SECONDS : timeout.intValue(), TimeUnit.SECONDS);
if (result == IoFuture.Status.WAITING) {
//add a notifier to close the channel if the connection actually completes
session.cancel();
session.addNotifier(new IoFuture.HandlingNotifier<WebSocketChannel, Object>() {
@Override
public void handleDone(WebSocketChannel data, Object attachment) {
IoUtils.safeClose(data);
}
}, null);
throw JsrWebSocketMessages.MESSAGES.connectionTimedOut();
}
WebSocketChannel channel;
try {
channel = session.get();
} catch (UpgradeFailedException e) {
throw new DeploymentException(e.getMessage(), e);
}
EndpointSessionHandler sessionHandler = new EndpointSessionHandler(this);
final List<Extension> extensions = new ArrayList<>();
final Map<String, Extension> extMap = new HashMap<>();
for (Extension ext : cec.getConfig().getExtensions()) {
extMap.put(ext.getName(), ext);
}
String subProtocol = null;
if (connectionBuilder.getClientNegotiation() != null) {
for (WebSocketExtension e : connectionBuilder.getClientNegotiation().getSelectedExtensions()) {
Extension ext = extMap.get(e.getName());
if (ext == null) {
throw JsrWebSocketMessages.MESSAGES.extensionWasNotPresentInClientHandshake(e.getName(), connectionBuilder.getClientNegotiation().getSupportedExtensions());
}
extensions.add(ExtensionImpl.create(e));
}
subProtocol = connectionBuilder.getClientNegotiation().getSelectedSubProtocol();
}
UndertowSession undertowSession = new UndertowSession(channel, connectionBuilder.getUri(), Collections.<String, String>emptyMap(), Collections.<String, List<String>>emptyMap(), sessionHandler, null, new ImmediateInstanceHandle<>(endpointInstance), cec.getConfig(), connectionBuilder.getUri().getQuery(), cec.getEncodingFactory().createEncoding(cec.getConfig()), cec, subProtocol, extensions, connectionBuilder);
endpointInstance.onOpen(undertowSession, cec.getConfig());
channel.resumeReceives();
return undertowSession;
}
use of io.undertow.websockets.WebSocketExtension in project undertow by undertow-io.
the class JsrWebsocketExtensionTestCase method testLongTextMessage.
@Test
public void testLongTextMessage() throws Exception {
final String SEC_WEBSOCKET_EXTENSIONS = "permessage-deflate; client_no_context_takeover; client_max_window_bits";
List<WebSocketExtension> extensionsList = WebSocketExtension.parse(SEC_WEBSOCKET_EXTENSIONS);
final WebSocketClientNegotiation negotiation = new WebSocketClientNegotiation(null, extensionsList);
Set<ExtensionHandshake> extensionHandshakes = new HashSet<>();
extensionHandshakes.add(new PerMessageDeflateHandshake(true));
final WebSocketChannel clientChannel = WebSocketClient.connect(DefaultServer.getWorker(), null, DefaultServer.getBufferPool(), OptionMap.EMPTY, new URI(DefaultServer.getDefaultServerURL()), WebSocketVersion.V13, negotiation, extensionHandshakes).get();
final LinkedBlockingDeque<String> resultQueue = new LinkedBlockingDeque<>();
clientChannel.getReceiveSetter().set(new AbstractReceiveListener() {
@Override
protected void onFullTextMessage(WebSocketChannel channel, BufferedTextMessage message) throws IOException {
String data = message.getData();
// WebSocketLogger.ROOT_LOGGER.info("onFullTextMessage() - Client - Received: " + data.getBytes().length + " bytes.");
resultQueue.addLast(data);
}
@Override
protected void onFullCloseMessage(WebSocketChannel channel, BufferedBinaryMessage message) throws IOException {
message.getData().close();
WebSocketLogger.ROOT_LOGGER.info("onFullCloseMessage");
}
@Override
protected void onError(WebSocketChannel channel, Throwable error) {
WebSocketLogger.ROOT_LOGGER.info("onError");
super.onError(channel, error);
error.printStackTrace();
resultQueue.add("FAILED " + error);
}
});
clientChannel.resumeReceives();
int LONG_MSG = 125 * 1024;
StringBuilder longMsg = new StringBuilder(LONG_MSG);
for (int i = 0; i < LONG_MSG; i++) {
longMsg.append(Integer.toString(i).charAt(0));
}
String message = longMsg.toString();
for (int j = 0; j < MSG_COUNT; ++j) {
WebSockets.sendTextBlocking(message, clientChannel);
String res = resultQueue.poll(3, TimeUnit.SECONDS);
Assert.assertEquals(message, res);
}
clientChannel.sendClose();
}
use of io.undertow.websockets.WebSocketExtension in project undertow by undertow-io.
the class JsrHybi13Handshake method selectedExtension.
@Override
protected List<WebSocketExtension> selectedExtension(List<WebSocketExtension> extensionList) {
List<Extension> ext = new ArrayList<>();
for (WebSocketExtension i : extensionList) {
ext.add(ExtensionImpl.create(i));
}
List<Extension> selected = HandshakeUtil.selectExtensions(config, ext);
if (selected == null) {
return Collections.emptyList();
}
Map<String, ExtensionHandshake> extensionMap = new HashMap<>();
for (ExtensionHandshake availible : availableExtensions) {
extensionMap.put(availible.getName(), availible);
}
List<WebSocketExtension> ret = new ArrayList<>();
List<ExtensionHandshake> accepted = new ArrayList<>();
for (Extension i : selected) {
ExtensionHandshake handshake = extensionMap.get(i.getName());
if (handshake == null) {
//should not happen
continue;
}
List<WebSocketExtension.Parameter> parameters = new ArrayList<>();
for (Extension.Parameter p : i.getParameters()) {
parameters.add(new WebSocketExtension.Parameter(p.getName(), p.getValue()));
}
if (!handshake.isIncompatible(accepted)) {
WebSocketExtension accept = handshake.accept(new WebSocketExtension(i.getName(), parameters));
if (accept != null) {
ret.add(accept);
accepted.add(handshake);
}
}
}
return ret;
}
use of io.undertow.websockets.WebSocketExtension in project undertow by undertow-io.
the class JsrWebsocketExtensionTestCase method testExtensionsHeaders.
@Test
public void testExtensionsHeaders() throws Exception {
final String SEC_WEBSOCKET_EXTENSIONS = "permessage-deflate; client_no_context_takeover; client_max_window_bits";
// List format
final String SEC_WEBSOCKET_EXTENSIONS_EXPECTED = "[permessage-deflate; client_no_context_takeover]";
List<WebSocketExtension> extensions = WebSocketExtension.parse(SEC_WEBSOCKET_EXTENSIONS);
final WebSocketClientNegotiation negotiation = new WebSocketClientNegotiation(null, extensions);
Set<ExtensionHandshake> extensionHandshakes = new HashSet<>();
extensionHandshakes.add(new PerMessageDeflateHandshake(true));
final WebSocketChannel clientChannel = WebSocketClient.connect(DefaultServer.getWorker(), null, DefaultServer.getBufferPool(), OptionMap.EMPTY, new URI(DefaultServer.getDefaultServerURL()), WebSocketVersion.V13, negotiation, extensionHandshakes).get();
final CountDownLatch latch = new CountDownLatch(1);
final AtomicReference<String> result = new AtomicReference<>();
clientChannel.getReceiveSetter().set(new AbstractReceiveListener() {
@Override
protected void onFullTextMessage(WebSocketChannel channel, BufferedTextMessage message) throws IOException {
String data = message.getData();
WebSocketLogger.ROOT_LOGGER.info("onFullTextMessage - Client - Received: " + data.getBytes().length + " bytes . Data: " + data);
result.set(data);
latch.countDown();
}
@Override
protected void onFullCloseMessage(WebSocketChannel channel, BufferedBinaryMessage message) throws IOException {
message.getData().close();
WebSocketLogger.ROOT_LOGGER.info("onFullCloseMessage");
}
@Override
protected void onError(WebSocketChannel channel, Throwable error) {
WebSocketLogger.ROOT_LOGGER.info("onError");
super.onError(channel, error);
error.printStackTrace();
latch.countDown();
}
});
clientChannel.resumeReceives();
StreamSinkFrameChannel sendChannel = clientChannel.send(WebSocketFrameType.TEXT);
new StringWriteChannelListener("Hello, World!").setup(sendChannel);
latch.await(10, TimeUnit.SECONDS);
Assert.assertEquals("Hello, World!", result.get());
clientChannel.sendClose();
Assert.assertEquals(SEC_WEBSOCKET_EXTENSIONS_EXPECTED, debug.getResponseExtensions().toString());
}
Aggregations