Search in sources :

Example 1 with ExtensionConfig

use of org.eclipse.jetty.websocket.api.extensions.ExtensionConfig in project jetty.project by eclipse.

the class ExtensionStack method negotiate.

/**
     * Perform the extension negotiation.
     * <p>
     * For the list of negotiated extensions, use {@link #getNegotiatedExtensions()}
     * 
     * @param configs
     *            the configurations being requested
     */
public void negotiate(List<ExtensionConfig> configs) {
    if (LOG.isDebugEnabled())
        LOG.debug("Extension Configs={}", configs);
    this.extensions = new ArrayList<>();
    String[] rsvClaims = new String[3];
    for (ExtensionConfig config : configs) {
        Extension ext = factory.newInstance(config);
        if (ext == null) {
            // Extension not present on this side
            continue;
        }
        // Check RSV
        if (ext.isRsv1User() && (rsvClaims[0] != null)) {
            LOG.debug("Not adding extension {}. Extension {} already claimed RSV1", config, rsvClaims[0]);
            continue;
        }
        if (ext.isRsv2User() && (rsvClaims[1] != null)) {
            LOG.debug("Not adding extension {}. Extension {} already claimed RSV2", config, rsvClaims[1]);
            continue;
        }
        if (ext.isRsv3User() && (rsvClaims[2] != null)) {
            LOG.debug("Not adding extension {}. Extension {} already claimed RSV3", config, rsvClaims[2]);
            continue;
        }
        // Add Extension
        extensions.add(ext);
        addBean(ext);
        if (LOG.isDebugEnabled())
            LOG.debug("Adding Extension: {}", config);
        // Record RSV Claims
        if (ext.isRsv1User()) {
            rsvClaims[0] = ext.getName();
        }
        if (ext.isRsv2User()) {
            rsvClaims[1] = ext.getName();
        }
        if (ext.isRsv3User()) {
            rsvClaims[2] = ext.getName();
        }
    }
}
Also used : Extension(org.eclipse.jetty.websocket.api.extensions.Extension) ExtensionConfig(org.eclipse.jetty.websocket.api.extensions.ExtensionConfig)

Example 2 with ExtensionConfig

use of org.eclipse.jetty.websocket.api.extensions.ExtensionConfig in project jetty.project by eclipse.

the class WebSocketClient method connect.

/**
     * Connect to remote websocket endpoint
     *
     * @param websocket
     *            the websocket object
     * @param toUri
     *            the websocket uri to connect to
     * @param request
     *            the upgrade request information
     * @param upgradeListener
     *            the upgrade listener
     * @return the future for the session, available on success of connect
     * @throws IOException
     *             if unable to connect
     */
public Future<Session> connect(Object websocket, URI toUri, ClientUpgradeRequest request, UpgradeListener upgradeListener) throws IOException {
    /* Note: UpgradeListener is used by javax.websocket.ClientEndpointConfig.Configurator
         * See: org.eclipse.jetty.websocket.jsr356.JsrUpgradeListener
         */
    if (!isStarted()) {
        throw new IllegalStateException(WebSocketClient.class.getSimpleName() + "@" + this.hashCode() + " is not started");
    }
    // Validate websocket URI
    if (!toUri.isAbsolute()) {
        throw new IllegalArgumentException("WebSocket URI must be absolute");
    }
    if (StringUtil.isBlank(toUri.getScheme())) {
        throw new IllegalArgumentException("WebSocket URI must include a scheme");
    }
    String scheme = toUri.getScheme().toLowerCase(Locale.ENGLISH);
    if (("ws".equals(scheme) == false) && ("wss".equals(scheme) == false)) {
        throw new IllegalArgumentException("WebSocket URI scheme only supports [ws] and [wss], not [" + scheme + "]");
    }
    request.setRequestURI(toUri);
    request.setLocalEndpoint(websocket);
    // Validate Requested Extensions
    for (ExtensionConfig reqExt : request.getExtensions()) {
        if (!extensionRegistry.isAvailable(reqExt.getName())) {
            throw new IllegalArgumentException("Requested extension [" + reqExt.getName() + "] is not installed");
        }
    }
    if (LOG.isDebugEnabled())
        LOG.debug("connect websocket {} to {}", websocket, toUri);
    init();
    WebSocketUpgradeRequest wsReq = new WebSocketUpgradeRequest(this, httpClient, request);
    wsReq.setUpgradeListener(upgradeListener);
    return wsReq.sendAsync();
}
Also used : ExtensionConfig(org.eclipse.jetty.websocket.api.extensions.ExtensionConfig)

Example 3 with ExtensionConfig

use of org.eclipse.jetty.websocket.api.extensions.ExtensionConfig in project jetty.project by eclipse.

the class WebSocketUpgradeRequest method initWebSocketHeaders.

private void initWebSocketHeaders() {
    method(HttpMethod.GET);
    version(HttpVersion.HTTP_1_1);
    // The Upgrade Headers
    header(HttpHeader.UPGRADE, "websocket");
    header(HttpHeader.CONNECTION, "Upgrade");
    // The WebSocket Headers
    header(HttpHeader.SEC_WEBSOCKET_KEY, genRandomKey());
    header(HttpHeader.SEC_WEBSOCKET_VERSION, "13");
    // (Per the hybi list): Add no-cache headers to avoid compatibility issue.
    // There are some proxies that rewrite "Connection: upgrade"
    // to "Connection: close" in the response if a request doesn't contain
    // these headers.
    header(HttpHeader.PRAGMA, "no-cache");
    header(HttpHeader.CACHE_CONTROL, "no-cache");
    // handle "Sec-WebSocket-Extensions"
    if (!apiRequestFacade.getExtensions().isEmpty()) {
        for (ExtensionConfig ext : apiRequestFacade.getExtensions()) {
            header(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, ext.getParameterizedName());
        }
    }
    // handle "Sec-WebSocket-Protocol"
    if (!apiRequestFacade.getSubProtocols().isEmpty()) {
        for (String protocol : apiRequestFacade.getSubProtocols()) {
            header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, protocol);
        }
    }
    if (upgradeListener != null) {
        upgradeListener.onHandshakeRequest(apiRequestFacade);
    }
}
Also used : ExtensionConfig(org.eclipse.jetty.websocket.api.extensions.ExtensionConfig)

Example 4 with ExtensionConfig

use of org.eclipse.jetty.websocket.api.extensions.ExtensionConfig in project jetty.project by eclipse.

the class WebSocketUpgradeRequest method upgrade.

@Override
public void upgrade(HttpResponse response, HttpConnectionOverHTTP oldConn) {
    if (!this.getHeaders().get(HttpHeader.UPGRADE).equalsIgnoreCase("websocket")) {
        // Not my upgrade
        throw new HttpResponseException("Not WebSocket Upgrade", response);
    }
    // Check the Accept hash
    String reqKey = this.getHeaders().get(HttpHeader.SEC_WEBSOCKET_KEY);
    String expectedHash = AcceptHash.hashKey(reqKey);
    String respHash = response.getHeaders().get(HttpHeader.SEC_WEBSOCKET_ACCEPT);
    if (expectedHash.equalsIgnoreCase(respHash) == false) {
        throw new HttpResponseException("Invalid Sec-WebSocket-Accept hash", response);
    }
    // We can upgrade
    EndPoint endp = oldConn.getEndPoint();
    WebSocketClientConnection connection = new WebSocketClientConnection(endp, wsClient.getExecutor(), wsClient.getScheduler(), localEndpoint.getPolicy(), wsClient.getBufferPool());
    URI requestURI = this.getURI();
    WebSocketSession session = getSessionFactory().createSession(requestURI, localEndpoint, connection);
    session.setUpgradeRequest(new ClientUpgradeRequest(this));
    session.setUpgradeResponse(new ClientUpgradeResponse(response));
    connection.addListener(session);
    ExtensionStack extensionStack = new ExtensionStack(getExtensionFactory());
    List<ExtensionConfig> extensions = new ArrayList<>();
    HttpField extField = response.getHeaders().getField(HttpHeader.SEC_WEBSOCKET_EXTENSIONS);
    if (extField != null) {
        String[] extValues = extField.getValues();
        if (extValues != null) {
            for (String extVal : extValues) {
                QuotedStringTokenizer tok = new QuotedStringTokenizer(extVal, ",");
                while (tok.hasMoreTokens()) {
                    extensions.add(ExtensionConfig.parse(tok.nextToken()));
                }
            }
        }
    }
    extensionStack.negotiate(extensions);
    extensionStack.configure(connection.getParser());
    extensionStack.configure(connection.getGenerator());
    // Setup Incoming Routing
    connection.setNextIncomingFrames(extensionStack);
    extensionStack.setNextIncoming(session);
    // Setup Outgoing Routing
    session.setOutgoingHandler(extensionStack);
    extensionStack.setNextOutgoing(connection);
    session.addManaged(extensionStack);
    session.setFuture(fut);
    wsClient.addManaged(session);
    if (upgradeListener != null) {
        upgradeListener.onHandshakeResponse(new ClientUpgradeResponse(response));
    }
    // Now swap out the connection
    endp.upgrade(connection);
}
Also used : ArrayList(java.util.ArrayList) WebSocketClientConnection(org.eclipse.jetty.websocket.client.io.WebSocketClientConnection) HttpResponseException(org.eclipse.jetty.client.HttpResponseException) EndPoint(org.eclipse.jetty.io.EndPoint) URI(java.net.URI) ExtensionStack(org.eclipse.jetty.websocket.common.extensions.ExtensionStack) WebSocketSession(org.eclipse.jetty.websocket.common.WebSocketSession) QuotedStringTokenizer(org.eclipse.jetty.util.QuotedStringTokenizer) ExtensionConfig(org.eclipse.jetty.websocket.api.extensions.ExtensionConfig) HttpField(org.eclipse.jetty.http.HttpField)

Example 5 with ExtensionConfig

use of org.eclipse.jetty.websocket.api.extensions.ExtensionConfig in project jetty.project by eclipse.

the class BrowserDebugTool method createWebSocket.

@Override
public Object createWebSocket(ServletUpgradeRequest req, ServletUpgradeResponse resp) {
    LOG.debug("Creating BrowserSocket");
    if (req.getSubProtocols() != null) {
        if (!req.getSubProtocols().isEmpty()) {
            String subProtocol = req.getSubProtocols().get(0);
            resp.setAcceptedSubProtocol(subProtocol);
        }
    }
    String ua = req.getHeader("User-Agent");
    String rexts = req.getHeader("Sec-WebSocket-Extensions");
    // manually negotiate extensions
    List<ExtensionConfig> negotiated = new ArrayList<>();
    // adding frame debug
    negotiated.add(new ExtensionConfig("@frame-capture; output-dir=target"));
    for (ExtensionConfig config : req.getExtensions()) {
        if (config.getName().equals("permessage-deflate")) {
            // what we are interested in here
            negotiated.add(config);
            continue;
        }
    // skip all others
    }
    resp.setExtensions(negotiated);
    LOG.debug("User-Agent: {}", ua);
    LOG.debug("Sec-WebSocket-Extensions (Request) : {}", rexts);
    LOG.debug("Sec-WebSocket-Protocol (Request): {}", req.getHeader("Sec-WebSocket-Protocol"));
    LOG.debug("Sec-WebSocket-Protocol (Response): {}", resp.getAcceptedSubProtocol());
    req.getExtensions();
    return new BrowserSocket(ua, rexts);
}
Also used : ExtensionConfig(org.eclipse.jetty.websocket.api.extensions.ExtensionConfig) ArrayList(java.util.ArrayList)

Aggregations

ExtensionConfig (org.eclipse.jetty.websocket.api.extensions.ExtensionConfig)26 ArrayList (java.util.ArrayList)11 Test (org.junit.Test)11 WebSocketFrame (org.eclipse.jetty.websocket.common.WebSocketFrame)10 TextFrame (org.eclipse.jetty.websocket.common.frames.TextFrame)10 ByteBuffer (java.nio.ByteBuffer)9 Frame (org.eclipse.jetty.websocket.api.extensions.Frame)8 ContinuationFrame (org.eclipse.jetty.websocket.common.frames.ContinuationFrame)7 PingFrame (org.eclipse.jetty.websocket.common.frames.PingFrame)7 FragmentExtension (org.eclipse.jetty.websocket.common.extensions.fragment.FragmentExtension)5 IncomingFramesCapture (org.eclipse.jetty.websocket.common.test.IncomingFramesCapture)5 AbstractExtensionTest (org.eclipse.jetty.websocket.common.extensions.AbstractExtensionTest)4 OutgoingFramesCapture (org.eclipse.jetty.websocket.common.test.OutgoingFramesCapture)4 IOException (java.io.IOException)3 WebSocketPolicy (org.eclipse.jetty.websocket.api.WebSocketPolicy)3 ExtensionStack (org.eclipse.jetty.websocket.common.extensions.ExtensionStack)3 Extension (org.eclipse.jetty.websocket.api.extensions.Extension)2 Generator (org.eclipse.jetty.websocket.common.Generator)2 IdentityExtension (org.eclipse.jetty.websocket.common.extensions.identity.IdentityExtension)2 OutgoingNetworkBytesCapture (org.eclipse.jetty.websocket.common.test.OutgoingNetworkBytesCapture)2