Search in sources :

Example 1 with Extension

use of javax.websocket.Extension in project tomcat by apache.

the class DefaultServerEndpointConfigurator method getNegotiatedExtensions.

@Override
public List<Extension> getNegotiatedExtensions(List<Extension> installed, List<Extension> requested) {
    Set<String> installedNames = new HashSet<>();
    for (Extension e : installed) {
        installedNames.add(e.getName());
    }
    List<Extension> result = new ArrayList<>();
    for (Extension request : requested) {
        if (installedNames.contains(request.getName())) {
            result.add(request);
        }
    }
    return result;
}
Also used : Extension(javax.websocket.Extension) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet)

Example 2 with Extension

use of javax.websocket.Extension in project tomcat by apache.

the class UpgradeUtil method doUpgrade.

public static void doUpgrade(WsServerContainer sc, HttpServletRequest req, HttpServletResponse resp, ServerEndpointConfig sec, Map<String, String> pathParams) throws ServletException, IOException {
    // Validate the rest of the headers and reject the request if that
    // validation fails
    String key;
    String subProtocol = null;
    if (!headerContainsToken(req, Constants.CONNECTION_HEADER_NAME, Constants.CONNECTION_HEADER_VALUE)) {
        resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
        return;
    }
    if (!headerContainsToken(req, Constants.WS_VERSION_HEADER_NAME, Constants.WS_VERSION_HEADER_VALUE)) {
        resp.setStatus(426);
        resp.setHeader(Constants.WS_VERSION_HEADER_NAME, Constants.WS_VERSION_HEADER_VALUE);
        return;
    }
    key = req.getHeader(Constants.WS_KEY_HEADER_NAME);
    if (key == null) {
        resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
        return;
    }
    // Origin check
    String origin = req.getHeader(Constants.ORIGIN_HEADER_NAME);
    if (!sec.getConfigurator().checkOrigin(origin)) {
        resp.sendError(HttpServletResponse.SC_FORBIDDEN);
        return;
    }
    // Sub-protocols
    List<String> subProtocols = getTokensFromHeader(req, Constants.WS_PROTOCOL_HEADER_NAME);
    subProtocol = sec.getConfigurator().getNegotiatedSubprotocol(sec.getSubprotocols(), subProtocols);
    // Extensions
    // Should normally only be one header but handle the case of multiple
    // headers
    List<Extension> extensionsRequested = new ArrayList<>();
    Enumeration<String> extHeaders = req.getHeaders(Constants.WS_EXTENSIONS_HEADER_NAME);
    while (extHeaders.hasMoreElements()) {
        Util.parseExtensionHeader(extensionsRequested, extHeaders.nextElement());
    }
    // Negotiation phase 1. By default this simply filters out the
    // extensions that the server does not support but applications could
    // use a custom configurator to do more than this.
    List<Extension> installedExtensions = null;
    if (sec.getExtensions().size() == 0) {
        installedExtensions = Constants.INSTALLED_EXTENSIONS;
    } else {
        installedExtensions = new ArrayList<>();
        installedExtensions.addAll(sec.getExtensions());
        installedExtensions.addAll(Constants.INSTALLED_EXTENSIONS);
    }
    List<Extension> negotiatedExtensionsPhase1 = sec.getConfigurator().getNegotiatedExtensions(installedExtensions, extensionsRequested);
    // Negotiation phase 2. Create the Transformations that will be applied
    // to this connection. Note than an extension may be dropped at this
    // point if the client has requested a configuration that the server is
    // unable to support.
    List<Transformation> transformations = createTransformations(negotiatedExtensionsPhase1);
    List<Extension> negotiatedExtensionsPhase2;
    if (transformations.isEmpty()) {
        negotiatedExtensionsPhase2 = Collections.emptyList();
    } else {
        negotiatedExtensionsPhase2 = new ArrayList<>(transformations.size());
        for (Transformation t : transformations) {
            negotiatedExtensionsPhase2.add(t.getExtensionResponse());
        }
    }
    // Build the transformation pipeline
    Transformation transformation = null;
    StringBuilder responseHeaderExtensions = new StringBuilder();
    boolean first = true;
    for (Transformation t : transformations) {
        if (first) {
            first = false;
        } else {
            responseHeaderExtensions.append(',');
        }
        append(responseHeaderExtensions, t.getExtensionResponse());
        if (transformation == null) {
            transformation = t;
        } else {
            transformation.setNext(t);
        }
    }
    // Now we have the full pipeline, validate the use of the RSV bits.
    if (transformation != null && !transformation.validateRsvBits(0)) {
        throw new ServletException(sm.getString("upgradeUtil.incompatibleRsv"));
    }
    // If we got this far, all is good. Accept the connection.
    resp.setHeader(Constants.UPGRADE_HEADER_NAME, Constants.UPGRADE_HEADER_VALUE);
    resp.setHeader(Constants.CONNECTION_HEADER_NAME, Constants.CONNECTION_HEADER_VALUE);
    resp.setHeader(HandshakeResponse.SEC_WEBSOCKET_ACCEPT, getWebSocketAccept(key));
    if (subProtocol != null && subProtocol.length() > 0) {
        // RFC6455 4.2.2 explicitly states "" is not valid here
        resp.setHeader(Constants.WS_PROTOCOL_HEADER_NAME, subProtocol);
    }
    if (!transformations.isEmpty()) {
        resp.setHeader(Constants.WS_EXTENSIONS_HEADER_NAME, responseHeaderExtensions.toString());
    }
    WsHandshakeRequest wsRequest = new WsHandshakeRequest(req, pathParams);
    WsHandshakeResponse wsResponse = new WsHandshakeResponse();
    WsPerSessionServerEndpointConfig perSessionServerEndpointConfig = new WsPerSessionServerEndpointConfig(sec);
    sec.getConfigurator().modifyHandshake(perSessionServerEndpointConfig, wsRequest, wsResponse);
    wsRequest.finished();
    // Add any additional headers
    for (Entry<String, List<String>> entry : wsResponse.getHeaders().entrySet()) {
        for (String headerValue : entry.getValue()) {
            resp.addHeader(entry.getKey(), headerValue);
        }
    }
    Endpoint ep;
    try {
        Class<?> clazz = sec.getEndpointClass();
        if (Endpoint.class.isAssignableFrom(clazz)) {
            ep = (Endpoint) sec.getConfigurator().getEndpointInstance(clazz);
        } else {
            ep = new PojoEndpointServer();
            // Need to make path params available to POJO
            perSessionServerEndpointConfig.getUserProperties().put(org.apache.tomcat.websocket.pojo.Constants.POJO_PATH_PARAM_KEY, pathParams);
        }
    } catch (InstantiationException e) {
        throw new ServletException(e);
    }
    WsHttpUpgradeHandler wsHandler = req.upgrade(WsHttpUpgradeHandler.class);
    wsHandler.preInit(ep, perSessionServerEndpointConfig, sc, wsRequest, negotiatedExtensionsPhase2, subProtocol, transformation, pathParams, req.isSecure());
}
Also used : Transformation(org.apache.tomcat.websocket.Transformation) WsHandshakeResponse(org.apache.tomcat.websocket.WsHandshakeResponse) ArrayList(java.util.ArrayList) PojoEndpointServer(org.apache.tomcat.websocket.pojo.PojoEndpointServer) Extension(javax.websocket.Extension) ServletException(javax.servlet.ServletException) Endpoint(javax.websocket.Endpoint) ArrayList(java.util.ArrayList) List(java.util.List)

Example 3 with Extension

use of javax.websocket.Extension in project tomcat by apache.

the class UpgradeUtil method createTransformations.

private static List<Transformation> createTransformations(List<Extension> negotiatedExtensions) {
    TransformationFactory factory = TransformationFactory.getInstance();
    LinkedHashMap<String, List<List<Extension.Parameter>>> extensionPreferences = new LinkedHashMap<>();
    // Result will likely be smaller than this
    List<Transformation> result = new ArrayList<>(negotiatedExtensions.size());
    for (Extension extension : negotiatedExtensions) {
        List<List<Extension.Parameter>> preferences = extensionPreferences.get(extension.getName());
        if (preferences == null) {
            preferences = new ArrayList<>();
            extensionPreferences.put(extension.getName(), preferences);
        }
        preferences.add(extension.getParameters());
    }
    for (Map.Entry<String, List<List<Extension.Parameter>>> entry : extensionPreferences.entrySet()) {
        Transformation transformation = factory.create(entry.getKey(), entry.getValue(), true);
        if (transformation != null) {
            result.add(transformation);
        }
    }
    return result;
}
Also used : Transformation(org.apache.tomcat.websocket.Transformation) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) Extension(javax.websocket.Extension) ArrayList(java.util.ArrayList) List(java.util.List) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) TransformationFactory(org.apache.tomcat.websocket.TransformationFactory)

Example 4 with Extension

use of javax.websocket.Extension in project tomcat by apache.

the class TestUtil method doTestParseExtensionHeaderSimple.

private void doTestParseExtensionHeaderSimple(String header) {
    // Simple test
    List<Extension> result = new ArrayList<>();
    Util.parseExtensionHeader(result, header);
    Assert.assertEquals(1, result.size());
    Extension ext = result.get(0);
    Assert.assertEquals("ext", ext.getName());
    List<Parameter> params = ext.getParameters();
    Assert.assertEquals(2, params.size());
    Parameter paramA = params.get(0);
    Assert.assertEquals("a", paramA.getName());
    Assert.assertEquals("1", paramA.getValue());
    Parameter paramB = params.get(1);
    Assert.assertEquals("b", paramB.getName());
    Assert.assertEquals("2", paramB.getValue());
}
Also used : Extension(javax.websocket.Extension) ArrayList(java.util.ArrayList) Parameter(javax.websocket.Extension.Parameter)

Example 5 with Extension

use of javax.websocket.Extension in project tomcat by apache.

the class TestUtil method doTestParseExtensionHeaderMultiple.

private void doTestParseExtensionHeaderMultiple(String header) {
    // Simple test
    List<Extension> result = new ArrayList<>();
    Util.parseExtensionHeader(result, header);
    Assert.assertEquals(3, result.size());
    Extension ext = result.get(0);
    Assert.assertEquals("ext", ext.getName());
    List<Parameter> params = ext.getParameters();
    Assert.assertEquals(2, params.size());
    Parameter paramA = params.get(0);
    Assert.assertEquals("a", paramA.getName());
    Assert.assertEquals("1", paramA.getValue());
    Parameter paramB = params.get(1);
    Assert.assertEquals("b", paramB.getName());
    Assert.assertEquals("2", paramB.getValue());
    Extension ext2 = result.get(1);
    Assert.assertEquals("ext2", ext2.getName());
    List<Parameter> params2 = ext2.getParameters();
    Assert.assertEquals(2, params2.size());
    Parameter paramC = params2.get(0);
    Assert.assertEquals("c", paramC.getName());
    Assert.assertNull(paramC.getValue());
    Parameter paramD = params2.get(1);
    Assert.assertEquals("d", paramD.getName());
    Assert.assertEquals("xyz", paramD.getValue());
    Extension ext3 = result.get(2);
    Assert.assertEquals("ext3", ext3.getName());
    List<Parameter> params3 = ext3.getParameters();
    Assert.assertEquals(0, params3.size());
}
Also used : Extension(javax.websocket.Extension) ArrayList(java.util.ArrayList) Parameter(javax.websocket.Extension.Parameter)

Aggregations

Extension (javax.websocket.Extension)22 ArrayList (java.util.ArrayList)16 ClientEndpointConfig (javax.websocket.ClientEndpointConfig)6 URI (java.net.URI)5 WebSocketExtension (io.undertow.websockets.WebSocketExtension)4 DeploymentException (javax.websocket.DeploymentException)4 Endpoint (javax.websocket.Endpoint)4 Parameter (javax.websocket.Extension.Parameter)4 Session (javax.websocket.Session)4 IOException (java.io.IOException)3 InetSocketAddress (java.net.InetSocketAddress)3 HashMap (java.util.HashMap)3 List (java.util.List)3 CountDownLatch (java.util.concurrent.CountDownLatch)3 ServerEndpointConfig (javax.websocket.server.ServerEndpointConfig)3 JsrExtension (org.eclipse.jetty.websocket.jsr356.JsrExtension)3 WebSocketChannel (io.undertow.websockets.core.WebSocketChannel)2 ExtensionHandshake (io.undertow.websockets.extensions.ExtensionHandshake)2 HashSet (java.util.HashSet)2 ExecutionException (java.util.concurrent.ExecutionException)2