Search in sources :

Example 16 with ExtensionConfig

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

the class FragmentExtensionTest method testOutgoingFramesByMaxLength.

/**
     * Verify that outgoing text frames are fragmented by the maxLength configuration.
     * @throws IOException on test failure
     */
@Test
public void testOutgoingFramesByMaxLength() throws IOException {
    OutgoingFramesCapture capture = new OutgoingFramesCapture();
    FragmentExtension ext = new FragmentExtension();
    ext.setBufferPool(bufferPool);
    ext.setPolicy(WebSocketPolicy.newServerPolicy());
    ExtensionConfig config = ExtensionConfig.parse("fragment;maxLength=20");
    ext.setConfig(config);
    ext.setNextOutgoingFrames(capture);
    // Quote
    List<String> quote = new ArrayList<>();
    quote.add("No amount of experimentation can ever prove me right;");
    quote.add("a single experiment can prove me wrong.");
    quote.add("-- Albert Einstein");
    // Write quote as separate frames
    for (String section : quote) {
        Frame frame = new TextFrame().setPayload(section);
        ext.outgoingFrame(frame, null, BatchMode.OFF);
    }
    // Expected Frames
    List<WebSocketFrame> expectedFrames = new ArrayList<>();
    expectedFrames.add(new TextFrame().setPayload("No amount of experim").setFin(false));
    expectedFrames.add(new ContinuationFrame().setPayload("entation can ever pr").setFin(false));
    expectedFrames.add(new ContinuationFrame().setPayload("ove me right;").setFin(true));
    expectedFrames.add(new TextFrame().setPayload("a single experiment ").setFin(false));
    expectedFrames.add(new ContinuationFrame().setPayload("can prove me wrong.").setFin(true));
    expectedFrames.add(new TextFrame().setPayload("-- Albert Einstein").setFin(true));
    // capture.dump();
    int len = expectedFrames.size();
    capture.assertFrameCount(len);
    String prefix;
    LinkedList<WebSocketFrame> frames = capture.getFrames();
    for (int i = 0; i < len; i++) {
        prefix = "Frame[" + i + "]";
        WebSocketFrame actualFrame = frames.get(i);
        WebSocketFrame expectedFrame = expectedFrames.get(i);
        // System.out.printf("actual: %s%n",actualFrame);
        // System.out.printf("expect: %s%n",expectedFrame);
        // Validate Frame
        Assert.assertThat(prefix + ".opcode", actualFrame.getOpCode(), is(expectedFrame.getOpCode()));
        Assert.assertThat(prefix + ".fin", actualFrame.isFin(), is(expectedFrame.isFin()));
        Assert.assertThat(prefix + ".rsv1", actualFrame.isRsv1(), is(expectedFrame.isRsv1()));
        Assert.assertThat(prefix + ".rsv2", actualFrame.isRsv2(), is(expectedFrame.isRsv2()));
        Assert.assertThat(prefix + ".rsv3", actualFrame.isRsv3(), is(expectedFrame.isRsv3()));
        // Validate Payload
        ByteBuffer expectedData = expectedFrame.getPayload().slice();
        ByteBuffer actualData = actualFrame.getPayload().slice();
        Assert.assertThat(prefix + ".payloadLength", actualData.remaining(), is(expectedData.remaining()));
        ByteBufferAssert.assertEquals(prefix + ".payload", expectedData, actualData);
    }
}
Also used : WebSocketFrame(org.eclipse.jetty.websocket.common.WebSocketFrame) TextFrame(org.eclipse.jetty.websocket.common.frames.TextFrame) Frame(org.eclipse.jetty.websocket.api.extensions.Frame) ContinuationFrame(org.eclipse.jetty.websocket.common.frames.ContinuationFrame) PingFrame(org.eclipse.jetty.websocket.common.frames.PingFrame) ArrayList(java.util.ArrayList) ContinuationFrame(org.eclipse.jetty.websocket.common.frames.ContinuationFrame) FragmentExtension(org.eclipse.jetty.websocket.common.extensions.fragment.FragmentExtension) ByteBuffer(java.nio.ByteBuffer) OutgoingFramesCapture(org.eclipse.jetty.websocket.common.test.OutgoingFramesCapture) ExtensionConfig(org.eclipse.jetty.websocket.api.extensions.ExtensionConfig) TextFrame(org.eclipse.jetty.websocket.common.frames.TextFrame) WebSocketFrame(org.eclipse.jetty.websocket.common.WebSocketFrame) Test(org.junit.Test)

Example 17 with ExtensionConfig

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

the class JsrCreator method createWebSocket.

@Override
public Object createWebSocket(ServletUpgradeRequest req, ServletUpgradeResponse resp) {
    JsrHandshakeRequest jsrHandshakeRequest = new JsrHandshakeRequest(req);
    JsrHandshakeResponse jsrHandshakeResponse = new JsrHandshakeResponse(resp);
    // Get raw config, as defined when the endpoint was added to the container
    ServerEndpointConfig config = metadata.getConfig();
    // Establish a copy of the config, so that the UserProperties are unique
    // per upgrade request.
    config = new BasicServerEndpointConfig(containerScope, config);
    // Bug 444617 - Expose localAddress and remoteAddress for jsr modify handshake to use
    // This is being implemented as an optional set of userProperties so that
    // it is not JSR api breaking.  A few users on #jetty and a few from cometd
    // have asked for access to this information.
    Map<String, Object> userProperties = config.getUserProperties();
    userProperties.put(PROP_LOCAL_ADDRESS, req.getLocalSocketAddress());
    userProperties.put(PROP_REMOTE_ADDRESS, req.getRemoteSocketAddress());
    userProperties.put(PROP_LOCALES, Collections.list(req.getLocales()));
    // Get Configurator from config object (not guaranteed to be unique per endpoint upgrade)
    ServerEndpointConfig.Configurator configurator = config.getConfigurator();
    // [JSR] Step 1: check origin
    if (!configurator.checkOrigin(req.getOrigin())) {
        try {
            resp.sendForbidden("Origin mismatch");
        } catch (IOException e) {
            if (LOG.isDebugEnabled())
                LOG.debug("Unable to send error response", e);
        }
        return null;
    }
    // [JSR] Step 2: deal with sub protocols
    List<String> supported = config.getSubprotocols();
    List<String> requested = req.getSubProtocols();
    String subprotocol = configurator.getNegotiatedSubprotocol(supported, requested);
    if (StringUtil.isNotBlank(subprotocol)) {
        resp.setAcceptedSubProtocol(subprotocol);
    }
    // [JSR] Step 3: deal with extensions
    List<Extension> installedExtensions = new ArrayList<>();
    for (String extName : extensionFactory.getAvailableExtensions().keySet()) {
        installedExtensions.add(new JsrExtension(extName));
    }
    List<Extension> requestedExts = new ArrayList<>();
    for (ExtensionConfig reqCfg : req.getExtensions()) {
        requestedExts.add(new JsrExtension(reqCfg));
    }
    List<Extension> usedExtensions = configurator.getNegotiatedExtensions(installedExtensions, requestedExts);
    List<ExtensionConfig> configs = new ArrayList<>();
    if (usedExtensions != null) {
        for (Extension used : usedExtensions) {
            ExtensionConfig ecfg = new ExtensionConfig(used.getName());
            for (Parameter param : used.getParameters()) {
                ecfg.setParameter(param.getName(), param.getValue());
            }
            configs.add(ecfg);
        }
    }
    resp.setExtensions(configs);
    // [JSR] Step 4: build out new ServerEndpointConfig
    PathSpec pathSpec = jsrHandshakeRequest.getRequestPathSpec();
    if (pathSpec instanceof UriTemplatePathSpec) {
        // We have a PathParam path spec
        UriTemplatePathSpec wspathSpec = (UriTemplatePathSpec) pathSpec;
        String requestPath = req.getRequestPath();
        // Wrap the config with the path spec information
        config = new PathParamServerEndpointConfig(containerScope, config, wspathSpec, requestPath);
    }
    // [JSR] Step 5: Call modifyHandshake
    configurator.modifyHandshake(config, jsrHandshakeRequest, jsrHandshakeResponse);
    try {
        // [JSR] Step 6: create endpoint class
        Class<?> endpointClass = config.getEndpointClass();
        Object endpoint = config.getConfigurator().getEndpointInstance(endpointClass);
        // This will allow CDI to see Session for injection into Endpoint classes.
        return new EndpointInstance(endpoint, config, metadata);
    } catch (InstantiationException e) {
        if (LOG.isDebugEnabled())
            LOG.debug("Unable to create websocket: " + config.getEndpointClass().getName(), e);
        return null;
    }
}
Also used : ServerEndpointConfig(javax.websocket.server.ServerEndpointConfig) ArrayList(java.util.ArrayList) EndpointInstance(org.eclipse.jetty.websocket.jsr356.endpoints.EndpointInstance) IOException(java.io.IOException) UriTemplatePathSpec(org.eclipse.jetty.http.pathmap.UriTemplatePathSpec) PathSpec(org.eclipse.jetty.http.pathmap.PathSpec) JsrExtension(org.eclipse.jetty.websocket.jsr356.JsrExtension) Extension(javax.websocket.Extension) JsrExtension(org.eclipse.jetty.websocket.jsr356.JsrExtension) UriTemplatePathSpec(org.eclipse.jetty.http.pathmap.UriTemplatePathSpec) ExtensionConfig(org.eclipse.jetty.websocket.api.extensions.ExtensionConfig) Parameter(javax.websocket.Extension.Parameter)

Example 18 with ExtensionConfig

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

the class PerMessageDeflateExtension method setConfig.

@Override
public void setConfig(final ExtensionConfig config) {
    configRequested = new ExtensionConfig(config);
    configNegotiated = new ExtensionConfig(config.getName());
    for (String key : config.getParameterKeys()) {
        key = key.trim();
        switch(key) {
            case "client_max_window_bits":
            case "server_max_window_bits":
                {
                    // Don't negotiate these parameters
                    break;
                }
            case "client_no_context_takeover":
                {
                    configNegotiated.setParameter("client_no_context_takeover");
                    switch(getPolicy().getBehavior()) {
                        case CLIENT:
                            incomingContextTakeover = false;
                            break;
                        case SERVER:
                            outgoingContextTakeover = false;
                            break;
                    }
                    break;
                }
            case "server_no_context_takeover":
                {
                    configNegotiated.setParameter("server_no_context_takeover");
                    switch(getPolicy().getBehavior()) {
                        case CLIENT:
                            outgoingContextTakeover = false;
                            break;
                        case SERVER:
                            incomingContextTakeover = false;
                            break;
                    }
                    break;
                }
            default:
                {
                    throw new IllegalArgumentException();
                }
        }
    }
    LOG.debug("config: outgoingContextTakover={}, incomingContextTakeover={} : {}", outgoingContextTakeover, incomingContextTakeover, this);
    super.setConfig(configNegotiated);
}
Also used : ExtensionConfig(org.eclipse.jetty.websocket.api.extensions.ExtensionConfig)

Example 19 with ExtensionConfig

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

the class BlockheadServerConnection method parseExtensions.

public List<ExtensionConfig> parseExtensions(List<String> requestLines) {
    List<ExtensionConfig> extensionConfigs = new ArrayList<>();
    List<String> hits = regexFind(requestLines, "^Sec-WebSocket-Extensions: (.*)$");
    for (String econf : hits) {
        // found extensions
        ExtensionConfig config = ExtensionConfig.parse(econf);
        extensionConfigs.add(config);
    }
    return extensionConfigs;
}
Also used : ExtensionConfig(org.eclipse.jetty.websocket.api.extensions.ExtensionConfig) ArrayList(java.util.ArrayList)

Example 20 with ExtensionConfig

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

the class BlockheadServerConnection method upgrade.

public List<String> upgrade() throws IOException {
    List<String> requestLines = readRequestLines();
    List<ExtensionConfig> extensionConfigs = parseExtensions(requestLines);
    String key = parseWebSocketKey(requestLines);
    LOG.debug("Client Request Extensions: {}", extensionConfigs);
    LOG.debug("Client Request Key: {}", key);
    Assert.assertThat("Request: Sec-WebSocket-Key", key, notNullValue());
    // collect extensions configured in response header
    ExtensionStack extensionStack = new ExtensionStack(extensionRegistry);
    extensionStack.negotiate(extensionConfigs);
    // Start with default routing
    extensionStack.setNextIncoming(this);
    extensionStack.setNextOutgoing(this);
    // Configure Parser / Generator
    extensionStack.configure(parser);
    extensionStack.configure(generator);
    // Start Stack
    try {
        extensionStack.start();
    } catch (Exception e) {
        throw new IOException("Unable to start Extension Stack");
    }
    // Configure Parser
    parser.setIncomingFramesHandler(extensionStack);
    // Setup Response
    StringBuilder resp = new StringBuilder();
    resp.append("HTTP/1.1 101 Upgrade\r\n");
    resp.append("Connection: upgrade\r\n");
    resp.append("Content-Length: 0\r\n");
    resp.append("Sec-WebSocket-Accept: ");
    resp.append(AcceptHash.hashKey(key)).append("\r\n");
    if (extensionStack.hasNegotiatedExtensions()) {
        // Respond to used extensions
        resp.append("Sec-WebSocket-Extensions: ");
        boolean delim = false;
        for (ExtensionConfig ext : extensionStack.getNegotiatedExtensions()) {
            if (delim) {
                resp.append(", ");
            }
            resp.append(ext.getParameterizedName());
            delim = true;
        }
        resp.append("\r\n");
    }
    if (extraResponseHeaders.size() > 0) {
        for (Map.Entry<String, String> xheader : extraResponseHeaders.entrySet()) {
            resp.append(xheader.getKey());
            resp.append(": ");
            resp.append(xheader.getValue());
            resp.append("\r\n");
        }
    }
    resp.append("\r\n");
    // Write Response
    LOG.debug("Response: {}", resp.toString());
    write(resp.toString().getBytes());
    return requestLines;
}
Also used : ExtensionConfig(org.eclipse.jetty.websocket.api.extensions.ExtensionConfig) IOException(java.io.IOException) ExtensionStack(org.eclipse.jetty.websocket.common.extensions.ExtensionStack) HashMap(java.util.HashMap) Map(java.util.Map) TimeoutException(java.util.concurrent.TimeoutException) SocketException(java.net.SocketException) IOException(java.io.IOException)

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