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());
Endpoint instance = endpointInstance;
if (configured == null) {
synchronized (clientEndpoints) {
// make sure to create an instance of AnnotatedEndpoint if we have the annotation
configured = getClientEndpoint(endpointInstance.getClass(), false);
if (configured == null) {
// if we don't, add an endpoint anyway to the list of clientEndpoints
clientEndpoints.put(endpointInstance.getClass(), configured = new ConfiguredClientEndpoint());
} else {
// use the factory in configured to reach the endpoint
instance = configured.getFactory().createInstance(new ImmediateInstanceHandle<>(endpointInstance));
}
}
}
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);
instance.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 WebSocket13ClientHandshake method createHeaders.
public Map<String, String> createHeaders() {
Map<String, String> headers = new HashMap<>();
headers.put(Headers.UPGRADE_STRING, "websocket");
headers.put(Headers.CONNECTION_STRING, "upgrade");
String key = createSecKey();
headers.put(Headers.SEC_WEB_SOCKET_KEY_STRING, key);
headers.put(Headers.SEC_WEB_SOCKET_VERSION_STRING, getVersion().toHttpHeaderValue());
if (negotiation != null) {
List<String> subProtocols = negotiation.getSupportedSubProtocols();
if (subProtocols != null && !subProtocols.isEmpty()) {
StringBuilder sb = new StringBuilder();
Iterator<String> it = subProtocols.iterator();
while (it.hasNext()) {
sb.append(it.next());
if (it.hasNext()) {
sb.append(", ");
}
}
headers.put(Headers.SEC_WEB_SOCKET_PROTOCOL_STRING, sb.toString());
}
List<WebSocketExtension> extensions = negotiation.getSupportedExtensions();
if (extensions != null && !extensions.isEmpty()) {
StringBuilder sb = new StringBuilder();
Iterator<WebSocketExtension> it = extensions.iterator();
while (it.hasNext()) {
WebSocketExtension next = it.next();
sb.append(next.getName());
for (WebSocketExtension.Parameter param : next.getParameters()) {
sb.append("; ");
sb.append(param.getName());
/*
Extensions can have parameters without values
*/
if (param.getValue() != null && param.getValue().length() > 0) {
sb.append("=");
sb.append(param.getValue());
}
}
if (it.hasNext()) {
sb.append(", ");
}
}
headers.put(Headers.SEC_WEB_SOCKET_EXTENSIONS_STRING, sb.toString());
}
}
return headers;
}
use of io.undertow.websockets.WebSocketExtension in project undertow by undertow-io.
the class WebSocket13ClientHandshake method handshakeChecker.
@Override
public ExtendedHandshakeChecker handshakeChecker(final URI uri, final Map<String, List<String>> requestHeaders) {
final String sentKey = requestHeaders.containsKey(Headers.SEC_WEB_SOCKET_KEY_STRING) ? requestHeaders.get(Headers.SEC_WEB_SOCKET_KEY_STRING).get(0) : null;
return new ExtendedHandshakeChecker() {
@Override
public void checkHandshakeExtended(Map<String, List<String>> headers) throws IOException {
try {
if (negotiation != null) {
negotiation.afterRequest(headers);
}
String upgrade = getFirst(Headers.UPGRADE_STRING, headers);
if (upgrade == null || !upgrade.trim().equalsIgnoreCase("websocket")) {
throw WebSocketMessages.MESSAGES.noWebSocketUpgradeHeader();
}
String connHeader = getFirst(Headers.CONNECTION_STRING, headers);
if (connHeader == null || !connHeader.trim().equalsIgnoreCase("upgrade")) {
throw WebSocketMessages.MESSAGES.noWebSocketConnectionHeader();
}
String acceptKey = getFirst(Headers.SEC_WEB_SOCKET_ACCEPT_STRING, headers);
final String dKey = solve(sentKey);
if (!dKey.equals(acceptKey)) {
throw WebSocketMessages.MESSAGES.webSocketAcceptKeyMismatch(dKey, acceptKey);
}
if (negotiation != null) {
String subProto = getFirst(Headers.SEC_WEB_SOCKET_PROTOCOL_STRING, headers);
if (subProto != null && !subProto.isEmpty() && !negotiation.getSupportedSubProtocols().contains(subProto)) {
throw WebSocketMessages.MESSAGES.unsupportedProtocol(subProto, negotiation.getSupportedSubProtocols());
}
List<WebSocketExtension> extensions = Collections.emptyList();
String extHeader = getFirst(Headers.SEC_WEB_SOCKET_EXTENSIONS_STRING, headers);
if (extHeader != null) {
extensions = WebSocketExtension.parse(extHeader);
}
negotiation.handshakeComplete(subProto, extensions);
}
} catch (IOException e) {
throw e;
} catch (Exception e) {
throw new IOException(e);
}
}
};
}
use of io.undertow.websockets.WebSocketExtension in project undertow by undertow-io.
the class Handshake method selectedExtension.
protected List<WebSocketExtension> selectedExtension(List<WebSocketExtension> extensionList) {
List<WebSocketExtension> selected = new ArrayList<>();
List<ExtensionHandshake> configured = new ArrayList<>();
for (WebSocketExtension ext : extensionList) {
for (ExtensionHandshake extHandshake : availableExtensions) {
WebSocketExtension negotiated = extHandshake.accept(ext);
if (negotiated != null && !extHandshake.isIncompatible(configured)) {
selected.add(negotiated);
configured.add(extHandshake);
}
}
}
return selected;
}
Aggregations