Merge pull request #4881 from eclipse/jetty-10.0.x-WebSocketCoreRefactor

Issue #2173 & #2174 - separate out client and server parts of websocket-core
This commit is contained in:
Lachlan 2020-05-26 09:47:00 +10:00 committed by GitHub
commit 94c8edc02e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
161 changed files with 599 additions and 354 deletions

View File

@ -381,7 +381,17 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.eclipse.jetty.websocket</groupId> <groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-core</artifactId> <artifactId>websocket-core-common</artifactId>
<version>10.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-core-client</artifactId>
<version>10.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-core-server</artifactId>
<version>10.0.0-SNAPSHOT</version> <version>10.0.0-SNAPSHOT</version>
</dependency> </dependency>
<dependency> <dependency>

View File

@ -19,21 +19,11 @@
package org.eclipse.jetty.osgi.test; package org.eclipse.jetty.osgi.test;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.io.ClientConnector;
import org.eclipse.jetty.osgi.boot.OSGiServerConstants; import org.eclipse.jetty.osgi.boot.OSGiServerConstants;
import org.eclipse.jetty.toolchain.test.FS; import org.eclipse.jetty.toolchain.test.FS;
import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.StringUtil;
@ -43,16 +33,12 @@ import org.ops4j.pax.exam.Option;
import org.ops4j.pax.exam.options.WrappedUrlProvisionOption.OverwriteMode; import org.ops4j.pax.exam.options.WrappedUrlProvisionOption.OverwriteMode;
import org.ops4j.pax.tinybundles.core.TinyBundle; import org.ops4j.pax.tinybundles.core.TinyBundle;
import org.ops4j.pax.tinybundles.core.TinyBundles; import org.ops4j.pax.tinybundles.core.TinyBundles;
import org.ops4j.pax.url.mvn.internal.AetherBasedResolver;
import org.osgi.framework.Bundle; import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext; import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants; import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference; import org.osgi.framework.ServiceReference;
import org.osgi.service.http.HttpService;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.ops4j.pax.exam.CoreOptions.mavenBundle; import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
@ -195,7 +181,9 @@ public class TestOSGiUtil
res.add(mavenBundle().groupId("org.eclipse.jetty").artifactId("jetty-jndi").versionAsInProject().start()); res.add(mavenBundle().groupId("org.eclipse.jetty").artifactId("jetty-jndi").versionAsInProject().start());
res.add(mavenBundle().groupId("org.eclipse.jetty").artifactId("jetty-plus").versionAsInProject().start()); res.add(mavenBundle().groupId("org.eclipse.jetty").artifactId("jetty-plus").versionAsInProject().start());
res.add(mavenBundle().groupId("org.eclipse.jetty").artifactId("jetty-annotations").versionAsInProject().start()); res.add(mavenBundle().groupId("org.eclipse.jetty").artifactId("jetty-annotations").versionAsInProject().start());
res.add(mavenBundle().groupId("org.eclipse.jetty.websocket").artifactId("websocket-core").versionAsInProject().start()); res.add(mavenBundle().groupId("org.eclipse.jetty.websocket").artifactId("websocket-core-server").versionAsInProject().start());
res.add(mavenBundle().groupId("org.eclipse.jetty.websocket").artifactId("websocket-core-client").versionAsInProject().start());
res.add(mavenBundle().groupId("org.eclipse.jetty.websocket").artifactId("websocket-core-common").versionAsInProject().start());
res.add(mavenBundle().groupId("org.eclipse.jetty.websocket").artifactId("websocket-util").versionAsInProject().start()); res.add(mavenBundle().groupId("org.eclipse.jetty.websocket").artifactId("websocket-util").versionAsInProject().start());
res.add(mavenBundle().groupId("org.eclipse.jetty.websocket").artifactId("websocket-util-server").versionAsInProject().start()); res.add(mavenBundle().groupId("org.eclipse.jetty.websocket").artifactId("websocket-util-server").versionAsInProject().start());
res.add(mavenBundle().groupId("org.eclipse.jetty.websocket").artifactId("websocket-jetty-api").versionAsInProject().start()); res.add(mavenBundle().groupId("org.eclipse.jetty.websocket").artifactId("websocket-jetty-api").versionAsInProject().start());

View File

@ -14,9 +14,11 @@
<url>http://www.eclipse.org/jetty</url> <url>http://www.eclipse.org/jetty</url>
<modules> <modules>
<module>websocket-core</module> <!-- WebSocket Core Implementation -->
<module>websocket-util</module> <module>websocket-core-common</module>
<module>websocket-util-server</module> <module>websocket-core-client</module>
<module>websocket-core-server</module>
<module>websocket-core-tests</module>
<!-- Jetty WebSocket Implementation --> <!-- Jetty WebSocket Implementation -->
<module>websocket-jetty-api</module> <module>websocket-jetty-api</module>
<module>websocket-jetty-common</module> <module>websocket-jetty-common</module>
@ -28,6 +30,9 @@
<module>websocket-javax-client</module> <module>websocket-javax-client</module>
<module>websocket-javax-server</module> <module>websocket-javax-server</module>
<module>websocket-javax-tests</module> <module>websocket-javax-tests</module>
<!-- Common WebSocket Implementation -->
<module>websocket-util</module>
<module>websocket-util-server</module>
</modules> </modules>
<build> <build>

View File

@ -0,0 +1,82 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-parent</artifactId>
<version>10.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>websocket-core-client</artifactId>
<name>Jetty :: Websocket :: Core :: Client</name>
<properties>
<bundle-symbolic-name>${project.groupId}.core.client</bundle-symbolic-name>
</properties>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-core-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-client</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-xml</artifactId>
<version>${project.version}</version>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<executions>
<execution>
<id>ban-ws-apis</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<bannedDependencies>
<includes>
<include>org.eclipse.jetty.websocket:websocket-jetty-api</include>
<include>javax.websocket</include>
</includes>
</bannedDependencies>
</rules>
</configuration>
</execution>
<execution>
<id>ban-java-servlet-api</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<bannedDependencies>
<includes>
<include>javax.servlet</include>
<include>servletapi</include>
<include>org.eclipse.jetty.orbit:javax.servlet</include>
<include>org.mortbay.jetty:servlet-api</include>
<include>jetty:servlet-api</include>
<include>jetty-servlet-api</include>
</includes>
</bannedDependencies>
</rules>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,29 @@
//
// ========================================================================
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under
// the terms of the Eclipse Public License 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0
//
// This Source Code may also be made available under the following
// Secondary Licenses when the conditions for such availability set
// forth in the Eclipse Public License, v. 2.0 are satisfied:
// the Apache License v2.0 which is available at
// https://www.apache.org/licenses/LICENSE-2.0
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
module org.eclipse.jetty.websocket.core.client
{
exports org.eclipse.jetty.websocket.core.client;
requires org.slf4j;
requires transitive org.eclipse.jetty.client;
requires transitive org.eclipse.jetty.websocket.core.common;
// Only required if using XmlHttpClientProvider.
requires static org.eclipse.jetty.xml;
}

View File

@ -80,8 +80,8 @@ public abstract class ClientUpgradeRequest extends HttpRequest implements Respon
protected final CompletableFuture<CoreSession> futureCoreSession; protected final CompletableFuture<CoreSession> futureCoreSession;
private final WebSocketCoreClient wsClient; private final WebSocketCoreClient wsClient;
private FrameHandler frameHandler; private FrameHandler frameHandler;
private Configuration.ConfigurationCustomizer customizer = new Configuration.ConfigurationCustomizer(); private final Configuration.ConfigurationCustomizer customizer = new Configuration.ConfigurationCustomizer();
private List<UpgradeListener> upgradeListeners = new ArrayList<>(); private final List<UpgradeListener> upgradeListeners = new ArrayList<>();
private List<ExtensionConfig> requestedExtensions = new ArrayList<>(); private List<ExtensionConfig> requestedExtensions = new ArrayList<>();
public ClientUpgradeRequest(WebSocketCoreClient webSocketClient, URI requestURI) public ClientUpgradeRequest(WebSocketCoreClient webSocketClient, URI requestURI)

View File

@ -40,7 +40,7 @@ public class WebSocketCoreClient extends ContainerLifeCycle
private static final Logger LOG = LoggerFactory.getLogger(WebSocketCoreClient.class); private static final Logger LOG = LoggerFactory.getLogger(WebSocketCoreClient.class);
private final HttpClient httpClient; private final HttpClient httpClient;
private WebSocketComponents components; private final WebSocketComponents components;
// TODO: Things to consider for inclusion in this class (or removal if they can be set elsewhere, like HttpClient) // TODO: Things to consider for inclusion in this class (or removal if they can be set elsewhere, like HttpClient)
// - AsyncWrite Idle Timeout // - AsyncWrite Idle Timeout

View File

@ -0,0 +1,98 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-parent</artifactId>
<version>10.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>websocket-core-common</artifactId>
<name>Jetty :: Websocket :: Core :: Common</name>
<properties>
<bundle-symbolic-name>${project.groupId}.core.common</bundle-symbolic-name>
</properties>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-io</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-http</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<executions>
<execution>
<id>ban-ws-apis</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<bannedDependencies>
<includes>
<include>org.eclipse.jetty.websocket:websocket-jetty-api</include>
<include>javax.websocket</include>
</includes>
</bannedDependencies>
</rules>
</configuration>
</execution>
<execution>
<id>ban-java-servlet-api</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<bannedDependencies>
<includes>
<include>javax.servlet</include>
<include>servletapi</include>
<include>org.eclipse.jetty.orbit:javax.servlet</include>
<include>org.mortbay.jetty:servlet-api</include>
<include>jetty:servlet-api</include>
<include>jetty-servlet-api</include>
</includes>
</bannedDependencies>
</rules>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<executions>
<execution>
<id>generate-manifest</id>
<goals>
<goal>manifest</goal>
</goals>
<configuration>
<instructions>
<Export-Package>*,org.eclipse.jetty.websocket.core.common.internal.*</Export-Package>
</instructions>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,11 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Enable both jetty and javax websocket modules for deployed web applications.
[tags]
websocket
[depend]
websocket-jetty
websocket-javax

View File

@ -22,22 +22,16 @@ import org.eclipse.jetty.websocket.core.internal.IdentityExtension;
import org.eclipse.jetty.websocket.core.internal.PerMessageDeflateExtension; import org.eclipse.jetty.websocket.core.internal.PerMessageDeflateExtension;
import org.eclipse.jetty.websocket.core.internal.ValidationExtension; import org.eclipse.jetty.websocket.core.internal.ValidationExtension;
module org.eclipse.jetty.websocket.core module org.eclipse.jetty.websocket.core.common
{ {
exports org.eclipse.jetty.websocket.core; exports org.eclipse.jetty.websocket.core;
exports org.eclipse.jetty.websocket.core.client;
exports org.eclipse.jetty.websocket.core.server;
exports org.eclipse.jetty.websocket.core.exception; exports org.eclipse.jetty.websocket.core.exception;
exports org.eclipse.jetty.websocket.core.internal to org.eclipse.jetty.util; exports org.eclipse.jetty.websocket.core.internal to org.eclipse.jetty.websocket.core.client, org.eclipse.jetty.websocket.core.server, org.eclipse.jetty.util;
requires jetty.servlet.api; requires org.eclipse.jetty.http;
requires transitive org.eclipse.jetty.client; requires org.eclipse.jetty.io;
requires transitive org.eclipse.jetty.server;
requires org.slf4j; requires org.slf4j;
// Only required if using XmlHttpClientProvider.
requires static org.eclipse.jetty.xml;
uses Extension; uses Extension;
provides Extension with provides Extension with

View File

@ -306,15 +306,12 @@ public class CloseStatus
} }
// Reserved / not yet allocated // Reserved / not yet allocated
if ((statusCode == 1004) || // Reserved in RFC6455 (might be defined in the future) // RFC6455 Not allowed to be used for any purpose
((statusCode >= 1016) && (statusCode <= 2999)) || // Reserved in RFC6455 (for future revisions, and extensions) return (statusCode != 1004) && // Reserved in RFC6455 (might be defined in the future)
(statusCode >= 5000)) // RFC6455 Not allowed to be used for any purpose ((statusCode < 1016) || (statusCode > 2999)) && // Reserved in RFC6455 (for future revisions, and extensions)
{ (statusCode < 5000);
return false;
}
// All others are allowed // All others are allowed
return true;
} }
public Frame toFrame() public Frame toFrame()

View File

@ -38,7 +38,7 @@ import org.eclipse.jetty.util.Trie;
*/ */
public class ExtensionConfig public class ExtensionConfig
{ {
private static Trie<ExtensionConfig> CACHE = new ArrayTrie<>(512); private static final Trie<ExtensionConfig> CACHE = new ArrayTrie<>(512);
static static
{ {
@ -315,7 +315,7 @@ public class ExtensionConfig
{ {
private final String parameterizedName; private final String parameterizedName;
private String name; private String name;
private Map<String, String> params = new HashMap<>(); private final Map<String, String> params = new HashMap<>();
public ParamParser(String parameterizedName) public ParamParser(String parameterizedName)
{ {

View File

@ -193,11 +193,7 @@ public class Frame
{ {
return false; return false;
} }
if (!Arrays.equals(mask, other.mask)) return Arrays.equals(mask, other.mask);
{
return false;
}
return true;
} }
public byte[] getMask() public byte[] getMask()

View File

@ -19,8 +19,6 @@
package org.eclipse.jetty.websocket.core; package org.eclipse.jetty.websocket.core;
import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.websocket.core.client.ClientUpgradeRequest;
import org.eclipse.jetty.websocket.core.server.Negotiation;
/** /**
* Interface for local WebSocket Endpoint Frame handling. * Interface for local WebSocket Endpoint Frame handling.
@ -31,11 +29,11 @@ import org.eclipse.jetty.websocket.core.server.Negotiation;
* is instantiated by the application, either: * is instantiated by the application, either:
* </p> * </p>
* <ul> * <ul>
* <li>On the server, the application layer must provide a {@link org.eclipse.jetty.websocket.core.server.WebSocketNegotiator} instance * <li>On the server, the application layer must provide a {@code org.eclipse.jetty.websocket.core.server.WebSocketNegotiator} instance
* to negotiate and accept websocket connections, which will return the FrameHandler instance to use from * to negotiate and accept websocket connections, which will return the FrameHandler instance to use from
* {@link org.eclipse.jetty.websocket.core.server.WebSocketNegotiator#negotiate(Negotiation)}.</li> * {@code org.eclipse.jetty.websocket.core.server.WebSocketNegotiator#negotiate(Negotiation)}.</li>
* <li>On the client, the application returns the FrameHandler instance to user from the {@link ClientUpgradeRequest} * <li>On the client, the application returns the FrameHandler instance to user from the {@code ClientUpgradeRequest}
* instance that it passes to the {@link org.eclipse.jetty.websocket.core.client.WebSocketCoreClient#connect(ClientUpgradeRequest)} method/</li> * instance that it passes to the {@code org.eclipse.jetty.websocket.core.client.WebSocketCoreClient#connect(ClientUpgradeRequest)} method/</li>
* </ul> * </ul>
* <p> * <p>
* Once instantiated the FrameHandler follows is used as follows: * Once instantiated the FrameHandler follows is used as follows:

View File

@ -19,7 +19,6 @@
package org.eclipse.jetty.websocket.core; package org.eclipse.jetty.websocket.core;
import java.util.zip.Deflater; import java.util.zip.Deflater;
import javax.servlet.ServletContext;
import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.MappedByteBufferPool; import org.eclipse.jetty.io.MappedByteBufferPool;
@ -31,26 +30,14 @@ import org.eclipse.jetty.util.compression.InflaterPool;
/** /**
* A collection of components which are the resources needed for websockets such as * A collection of components which are the resources needed for websockets such as
* {@link ByteBufferPool}, {@link WebSocketExtensionRegistry}, and {@link DecoratedObjectFactory}. * {@link ByteBufferPool}, {@link WebSocketExtensionRegistry}, and {@link DecoratedObjectFactory}.
*
* These components should be accessed through {@link WebSocketComponents#ensureWebSocketComponents} so that
* the instance can be shared by being stored as a bean on the ContextHandler.
*/ */
public class WebSocketComponents public class WebSocketComponents
{ {
public static final String WEBSOCKET_COMPONENTS_ATTRIBUTE = WebSocketComponents.class.getName(); private final DecoratedObjectFactory objectFactory;
private final WebSocketExtensionRegistry extensionRegistry;
public static WebSocketComponents ensureWebSocketComponents(ServletContext servletContext) private final ByteBufferPool bufferPool;
{ private final InflaterPool inflaterPool;
// Ensure a mapping exists private final DeflaterPool deflaterPool;
WebSocketComponents components = (WebSocketComponents)servletContext.getAttribute(WEBSOCKET_COMPONENTS_ATTRIBUTE);
if (components == null)
{
components = new WebSocketComponents();
servletContext.setAttribute(WEBSOCKET_COMPONENTS_ATTRIBUTE, components);
}
return components;
}
public WebSocketComponents() public WebSocketComponents()
{ {
@ -69,12 +56,6 @@ public class WebSocketComponents
this.inflaterPool = inflaterPool; this.inflaterPool = inflaterPool;
} }
private DecoratedObjectFactory objectFactory;
private WebSocketExtensionRegistry extensionRegistry;
private ByteBufferPool bufferPool;
private InflaterPool inflaterPool;
private DeflaterPool deflaterPool;
public ByteBufferPool getBufferPool() public ByteBufferPool getBufferPool()
{ {
return bufferPool; return bufferPool;

View File

@ -30,7 +30,7 @@ import org.eclipse.jetty.util.TypeUtil;
public class WebSocketExtensionRegistry implements Iterable<Class<? extends Extension>> public class WebSocketExtensionRegistry implements Iterable<Class<? extends Extension>>
{ {
private Map<String, Class<? extends Extension>> availableExtensions = new HashMap<>(); private final Map<String, Class<? extends Extension>> availableExtensions = new HashMap<>();
public WebSocketExtensionRegistry() public WebSocketExtensionRegistry()
{ {

View File

@ -21,7 +21,7 @@ package org.eclipse.jetty.websocket.core.exception;
@SuppressWarnings("serial") @SuppressWarnings("serial")
public class CloseException extends WebSocketException public class CloseException extends WebSocketException
{ {
private int statusCode; private final int statusCode;
public CloseException(int closeCode, String message) public CloseException(int closeCode, String message)
{ {

View File

@ -54,7 +54,7 @@ public class ExtensionStack implements IncomingFrames, OutgoingFrames, Dumpable
private List<Extension> extensions; private List<Extension> extensions;
private IncomingFrames incoming; private IncomingFrames incoming;
private OutgoingFrames outgoing; private OutgoingFrames outgoing;
private Extension[] rsvClaims = new Extension[3]; private final Extension[] rsvClaims = new Extension[3];
public ExtensionStack(WebSocketComponents components, Behavior behavior) public ExtensionStack(WebSocketComponents components, Behavior behavior)
{ {

View File

@ -51,8 +51,8 @@ public class FrameCaptureExtension extends AbstractExtension
private Path incomingFramesPath; private Path incomingFramesPath;
private Path outgoingFramesPath; private Path outgoingFramesPath;
private AtomicInteger incomingCount = new AtomicInteger(0); private final AtomicInteger incomingCount = new AtomicInteger(0);
private AtomicInteger outgoingCount = new AtomicInteger(0); private final AtomicInteger outgoingCount = new AtomicInteger(0);
private SeekableByteChannel incomingChannel; private SeekableByteChannel incomingChannel;
private SeekableByteChannel outgoingChannel; private SeekableByteChannel outgoingChannel;

View File

@ -511,7 +511,7 @@ public class FrameFlusher extends IteratingCallback
private class Entry extends FrameEntry private class Entry extends FrameEntry
{ {
private ByteBuffer headerBuffer; private ByteBuffer headerBuffer;
private long timeOfCreation = System.currentTimeMillis(); private final long timeOfCreation = System.currentTimeMillis();
private Entry(Frame frame, Callback callback, boolean batch) private Entry(Frame frame, Callback callback, boolean batch)
{ {

View File

@ -63,8 +63,8 @@ public class WebSocketConnection extends AbstractConnection implements Connectio
private long demand; private long demand;
private boolean fillingAndParsing; private boolean fillingAndParsing;
private LongAdder messagesIn = new LongAdder(); private final LongAdder messagesIn = new LongAdder();
private LongAdder bytesIn = new LongAdder(); private final LongAdder bytesIn = new LongAdder();
// Read / Parse variables // Read / Parse variables
private RetainableByteBuffer networkBuffer; private RetainableByteBuffer networkBuffer;

View File

@ -29,7 +29,6 @@ import java.util.concurrent.Executor;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.Utf8Appendable; import org.eclipse.jetty.util.Utf8Appendable;
import org.eclipse.jetty.util.component.Dumpable; import org.eclipse.jetty.util.component.Dumpable;
@ -81,7 +80,6 @@ public class WebSocketCoreSession implements IncomingFrames, CoreSession, Dumpab
private long maxTextMessageSize = WebSocketConstants.DEFAULT_MAX_TEXT_MESSAGE_SIZE; private long maxTextMessageSize = WebSocketConstants.DEFAULT_MAX_TEXT_MESSAGE_SIZE;
private Duration idleTimeout = WebSocketConstants.DEFAULT_IDLE_TIMEOUT; private Duration idleTimeout = WebSocketConstants.DEFAULT_IDLE_TIMEOUT;
private Duration writeTimeout = WebSocketConstants.DEFAULT_WRITE_TIMEOUT; private Duration writeTimeout = WebSocketConstants.DEFAULT_WRITE_TIMEOUT;
private final ContextHandler contextHandler;
public WebSocketCoreSession(FrameHandler handler, Behavior behavior, Negotiated negotiated, WebSocketComponents components) public WebSocketCoreSession(FrameHandler handler, Behavior behavior, Negotiated negotiated, WebSocketComponents components)
{ {
@ -90,26 +88,16 @@ public class WebSocketCoreSession implements IncomingFrames, CoreSession, Dumpab
this.behavior = behavior; this.behavior = behavior;
this.negotiated = negotiated; this.negotiated = negotiated;
this.demanding = handler.isDemanding(); this.demanding = handler.isDemanding();
if (behavior == Behavior.SERVER)
{
ContextHandler.Context context = ContextHandler.getCurrentContext();
this.contextHandler = (context != null) ? context.getContextHandler() : null;
}
else
{
this.contextHandler = null;
}
negotiated.getExtensions().initialize(new IncomingAdaptor(), new OutgoingAdaptor(), this); negotiated.getExtensions().initialize(new IncomingAdaptor(), new OutgoingAdaptor(), this);
} }
private void handle(Runnable runnable) /**
* Can be overridden to scope into the correct classloader before calling application code.
* @param runnable the runnable to execute.
*/
protected void handle(Runnable runnable)
{ {
if (contextHandler != null) runnable.run();
contextHandler.handle(runnable);
else
runnable.run();
} }
/** /**

View File

@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-parent</artifactId>
<version>10.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>websocket-core-server</artifactId>
<name>Jetty :: Websocket :: Core :: Server</name>
<properties>
<bundle-symbolic-name>${project.groupId}.core.server</bundle-symbolic-name>
</properties>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-core-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<executions>
<execution>
<id>ban-ws-apis</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<bannedDependencies>
<includes>
<include>org.eclipse.jetty.websocket:websocket-jetty-api</include>
<include>javax.websocket</include>
</includes>
</bannedDependencies>
</rules>
</configuration>
</execution>
<execution>
<id>ban-java-servlet-api</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<bannedDependencies>
<includes>
<include>javax.servlet</include>
<include>servletapi</include>
<include>org.eclipse.jetty.orbit:javax.servlet</include>
<include>org.mortbay.jetty:servlet-api</include>
<include>jetty:servlet-api</include>
<include>jetty-servlet-api</include>
</includes>
</bannedDependencies>
</rules>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,11 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Enable both jetty and javax websocket modules for deployed web applications.
[tags]
websocket
[depend]
websocket-jetty
websocket-javax

View File

@ -0,0 +1,26 @@
//
// ========================================================================
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under
// the terms of the Eclipse Public License 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0
//
// This Source Code may also be made available under the following
// Secondary Licenses when the conditions for such availability set
// forth in the Eclipse Public License, v. 2.0 are satisfied:
// the Apache License v2.0 which is available at
// https://www.apache.org/licenses/LICENSE-2.0
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
module org.eclipse.jetty.websocket.core.server
{
exports org.eclipse.jetty.websocket.core.server;
requires org.slf4j;
requires transitive org.eclipse.jetty.server;
requires transitive org.eclipse.jetty.websocket.core.common;
}

View File

@ -0,0 +1,51 @@
//
// ========================================================================
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under
// the terms of the Eclipse Public License 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0
//
// This Source Code may also be made available under the following
// Secondary Licenses when the conditions for such availability set
// forth in the Eclipse Public License, v. 2.0 are satisfied:
// the Apache License v2.0 which is available at
// https://www.apache.org/licenses/LICENSE-2.0
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.websocket.core.server;
import javax.servlet.ServletContext;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.util.DecoratedObjectFactory;
import org.eclipse.jetty.websocket.core.WebSocketComponents;
import org.eclipse.jetty.websocket.core.WebSocketExtensionRegistry;
/**
* A collection of components which are the resources needed for websockets such as
* {@link ByteBufferPool}, {@link WebSocketExtensionRegistry}, and {@link DecoratedObjectFactory}.
*
* These components should be accessed through {@link WebSocketServerComponents#ensureWebSocketComponents} so that
* the instance can be shared by being stored as a bean on the ContextHandler.
*/
public class WebSocketServerComponents extends WebSocketComponents
{
public static final String WEBSOCKET_COMPONENTS_ATTRIBUTE = WebSocketComponents.class.getName();
public static WebSocketComponents ensureWebSocketComponents(ServletContext servletContext)
{
// Ensure a mapping exists
WebSocketComponents components = (WebSocketComponents)servletContext.getAttribute(WEBSOCKET_COMPONENTS_ATTRIBUTE);
if (components == null)
{
components = new WebSocketServerComponents();
servletContext.setAttribute(WEBSOCKET_COMPONENTS_ATTRIBUTE, components);
}
return components;
}
}

View File

@ -34,6 +34,7 @@ import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpTransport; import org.eclipse.jetty.server.HttpTransport;
import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response; import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.thread.Scheduler; import org.eclipse.jetty.util.thread.Scheduler;
import org.eclipse.jetty.websocket.core.Behavior; import org.eclipse.jetty.websocket.core.Behavior;
import org.eclipse.jetty.websocket.core.Configuration; import org.eclipse.jetty.websocket.core.Configuration;
@ -132,7 +133,7 @@ public abstract class AbstractHandshaker implements Handshaker
Negotiated negotiated = new Negotiated(baseRequest.getHttpURI().toURI(), protocol, baseRequest.isSecure(), extensionStack, WebSocketConstants.SPEC_VERSION_STRING); Negotiated negotiated = new Negotiated(baseRequest.getHttpURI().toURI(), protocol, baseRequest.isSecure(), extensionStack, WebSocketConstants.SPEC_VERSION_STRING);
// Create the Session // Create the Session
WebSocketCoreSession coreSession = newWebSocketCoreSession(handler, negotiated, components); WebSocketCoreSession coreSession = newWebSocketCoreSession(request, handler, negotiated, components);
if (defaultCustomizer != null) if (defaultCustomizer != null)
defaultCustomizer.customize(coreSession); defaultCustomizer.customize(coreSession);
negotiator.customize(coreSession); negotiator.customize(coreSession);
@ -195,9 +196,20 @@ public abstract class AbstractHandshaker implements Handshaker
return true; return true;
} }
protected WebSocketCoreSession newWebSocketCoreSession(FrameHandler handler, Negotiated negotiated, WebSocketComponents components) protected WebSocketCoreSession newWebSocketCoreSession(HttpServletRequest request, FrameHandler handler, Negotiated negotiated, WebSocketComponents components)
{ {
return new WebSocketCoreSession(handler, Behavior.SERVER, negotiated, components); final ContextHandler contextHandler = ContextHandler.getContextHandler(request.getServletContext());
return new WebSocketCoreSession(handler, Behavior.SERVER, negotiated, components)
{
@Override
protected void handle(Runnable runnable)
{
if (contextHandler != null)
contextHandler.handle(runnable);
else
runnable.run();
}
};
} }
protected abstract WebSocketConnection createWebSocketConnection(Request baseRequest, WebSocketCoreSession coreSession); protected abstract WebSocketConnection createWebSocketConnection(Request baseRequest, WebSocketCoreSession coreSession);

View File

@ -7,105 +7,53 @@
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>websocket-core</artifactId> <artifactId>websocket-core-tests</artifactId>
<name>Jetty :: Websocket :: Core</name> <name>Jetty :: Websocket :: Core :: Tests</name>
<properties> <properties>
<bundle-symbolic-name>${project.groupId}.core</bundle-symbolic-name> <bundle-symbolic-name>${project.groupId}.core.tests</bundle-symbolic-name>
</properties> </properties>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.eclipse.jetty</groupId> <groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>jetty-util</artifactId> <artifactId>websocket-core-client</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.eclipse.jetty</groupId> <groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>jetty-io</artifactId> <artifactId>websocket-core-server</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.eclipse.jetty</groupId> <groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>jetty-http</artifactId> <artifactId>websocket-core-common</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-xml</artifactId>
<version>${project.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-client</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency> <dependency>
<groupId>org.eclipse.jetty</groupId> <groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-slf4j-impl</artifactId> <artifactId>jetty-slf4j-impl</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-test-helper</artifactId>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
<build> <build>
<plugins> <plugins>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId> <artifactId>maven-deploy-plugin</artifactId>
<executions> <configuration>
<execution> <!-- No point deploying testing projects -->
<id>ban-ws-apis</id> <skip>true</skip>
<goals> </configuration>
<goal>enforce</goal> </plugin>
</goals> <plugin>
<configuration> <groupId>org.apache.maven.plugins</groupId>
<rules> <artifactId>maven-javadoc-plugin</artifactId>
<bannedDependencies> <configuration>
<includes> <!-- No point building javadoc on testing projects -->
<include>org.eclipse.jetty.websocket:websocket-jetty-api</include> <skip>true</skip>
<include>javax.websocket</include> </configuration>
</includes>
</bannedDependencies>
</rules>
</configuration>
</execution>
<execution>
<id>ban-java-servlet-api</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<bannedDependencies>
<includes>
<include>javax.servlet</include>
<include>servletapi</include>
<include>org.eclipse.jetty.orbit:javax.servlet</include>
<include>org.mortbay.jetty:servlet-api</include>
<include>jetty:servlet-api</include>
<include>jetty-servlet-api</include>
</includes>
</bannedDependencies>
</rules>
</configuration>
</execution>
</executions>
</plugin> </plugin>
</plugins> </plugins>
</build> </build>

View File

@ -26,7 +26,7 @@ import org.eclipse.jetty.util.Callback;
public class CapturedHexPayloads implements OutgoingFrames public class CapturedHexPayloads implements OutgoingFrames
{ {
private List<String> captured = new ArrayList<>(); private final List<String> captured = new ArrayList<>();
@Override @Override
public void sendFrame(Frame frame, Callback callback, boolean batch) public void sendFrame(Frame frame, Callback callback, boolean batch)

View File

@ -41,9 +41,9 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
public class FlushTest public class FlushTest
{ {
private WebSocketServer server; private WebSocketServer server;
private TestFrameHandler serverHandler = new TestFrameHandler(); private final TestFrameHandler serverHandler = new TestFrameHandler();
private WebSocketCoreClient client; private WebSocketCoreClient client;
private WebSocketComponents components = new WebSocketComponents(); private final WebSocketComponents components = new WebSocketComponents();
@BeforeEach @BeforeEach
public void startup() throws Exception public void startup() throws Exception

View File

@ -40,9 +40,9 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
public class FrameBufferTest extends WebSocketTester public class FrameBufferTest extends WebSocketTester
{ {
private WebSocketServer server; private WebSocketServer server;
private TestFrameHandler serverHandler = new TestFrameHandler(); private final TestFrameHandler serverHandler = new TestFrameHandler();
private WebSocketCoreClient client; private WebSocketCoreClient client;
private WebSocketComponents components = new WebSocketComponents(); private final WebSocketComponents components = new WebSocketComponents();
@BeforeEach @BeforeEach
public void startup() throws Exception public void startup() throws Exception

View File

@ -39,7 +39,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
*/ */
public class GeneratorFrameFlagsTest public class GeneratorFrameFlagsTest
{ {
private static WebSocketComponents components = new WebSocketComponents(); private static final WebSocketComponents components = new WebSocketComponents();
private WebSocketCoreSession coreSession; private WebSocketCoreSession coreSession;
public static Stream<Arguments> data() public static Stream<Arguments> data()

View File

@ -33,7 +33,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
public class GeneratorParserRoundTripTest public class GeneratorParserRoundTripTest
{ {
private ByteBufferPool bufferPool = new MappedByteBufferPool(); private final ByteBufferPool bufferPool = new MappedByteBufferPool();
@Test @Test
public void testParserAndGenerator() throws Exception public void testParserAndGenerator() throws Exception

View File

@ -47,9 +47,9 @@ public class GeneratorTest
{ {
private static final Logger LOG = LoggerFactory.getLogger(Helper.class); private static final Logger LOG = LoggerFactory.getLogger(Helper.class);
private static Generator generator = new Generator(); private static final Generator generator = new Generator();
private static WebSocketCoreSession coreSession = newWebSocketCoreSession(Behavior.SERVER); private static final WebSocketCoreSession coreSession = newWebSocketCoreSession(Behavior.SERVER);
private static WebSocketComponents components = new WebSocketComponents(); private static final WebSocketComponents components = new WebSocketComponents();
private static WebSocketCoreSession newWebSocketCoreSession(Behavior behavior) private static WebSocketCoreSession newWebSocketCoreSession(Behavior behavior)
{ {

View File

@ -65,7 +65,7 @@ public class MessageHandlerTest
coreSession = new CoreSession.Empty() coreSession = new CoreSession.Empty()
{ {
private ByteBufferPool byteBufferPool = new MappedByteBufferPool(); private final ByteBufferPool byteBufferPool = new MappedByteBufferPool();
@Override @Override
public void sendFrame(Frame frame, Callback callback, boolean batch) public void sendFrame(Frame frame, Callback callback, boolean batch)

View File

@ -38,7 +38,7 @@ import static org.hamcrest.Matchers.lessThan;
public class OutgoingNetworkBytesCapture implements OutgoingFrames public class OutgoingNetworkBytesCapture implements OutgoingFrames
{ {
private final Generator generator; private final Generator generator;
private List<ByteBuffer> captured; private final List<ByteBuffer> captured;
public OutgoingNetworkBytesCapture(Generator generator) public OutgoingNetworkBytesCapture(Generator generator)
{ {

View File

@ -65,7 +65,7 @@ public class ParserBadCloseStatusCodesTest
); );
} }
private ByteBufferPool bufferPool = new MappedByteBufferPool(); private final ByteBufferPool bufferPool = new MappedByteBufferPool();
@ParameterizedTest(name = "closeCode={0} {1}") @ParameterizedTest(name = "closeCode={0} {1}")
@MethodSource("data") @MethodSource("data")

View File

@ -57,7 +57,7 @@ public class ParserBadOpCodesTest
); );
} }
private ByteBufferPool bufferPool = new MappedByteBufferPool(); private final ByteBufferPool bufferPool = new MappedByteBufferPool();
@ParameterizedTest(name = "opcode={0} {1}") @ParameterizedTest(name = "opcode={0} {1}")
@MethodSource("data") @MethodSource("data")

Some files were not shown because too many files have changed in this diff Show More