You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by re...@apache.org on 2017/10/13 15:25:23 UTC
svn commit: r1812142 - in /tomcat/trunk/java/org/apache/tomcat/websocket:
LocalStrings.properties WsWebSocketContainer.java
Author: remm
Date: Fri Oct 13 15:25:23 2017
New Revision: 1812142
URL: http://svn.apache.org/viewvc?rev=1812142&view=rev
Log:
Fix the merge mess caused by me cut&pasting the client code back to the container class. Noticed while porting to 8.5. Also fix the i18n property names.
Modified:
tomcat/trunk/java/org/apache/tomcat/websocket/LocalStrings.properties
tomcat/trunk/java/org/apache/tomcat/websocket/WsWebSocketContainer.java
Modified: tomcat/trunk/java/org/apache/tomcat/websocket/LocalStrings.properties
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/LocalStrings.properties?rev=1812142&r1=1812141&r2=1812142&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/LocalStrings.properties (original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/LocalStrings.properties Fri Oct 13 15:25:23 2017
@@ -127,18 +127,18 @@ wsWebSocketContainer.maxBuffer=This impl
wsWebSocketContainer.missingAnnotation=Cannot use POJO class [{0}] as it is not annotated with @ClientEndpoint
wsWebSocketContainer.sessionCloseFail=Session with ID [{0}] did not close cleanly
-wsWebSocketClient.asynchronousSocketChannelFail=Unable to open a connection to the server
-wsWebSocketClient.httpRequestFailed=The HTTP request to initiate the WebSocket connection failed
-wsWebSocketClient.invalidExtensionParameters=The server responded with extension parameters the client is unable to support
-wsWebSocketClient.invalidHeader=Unable to parse HTTP header as no colon is present to delimit header name and header value in [{0}]. The header has been skipped.
-wsWebSocketClient.invalidStatus=The HTTP response from the server [{0}] did not permit the HTTP upgrade to WebSocket
-wsWebSocketClient.invalidSubProtocol=The WebSocket server returned multiple values for the Sec-WebSocket-Protocol header
-wsWebSocketClient.pathNoHost=No host was specified in URI
-wsWebSocketClient.pathWrongScheme=The scheme [{0}] is not supported. The supported schemes are ws and wss
-wsWebSocketClient.proxyConnectFail=Failed to connect to the configured Proxy [{0}]. The HTTP response code was [{1}]
-wsWebSocketClient.sslEngineFail=Unable to create SSLEngine to support SSL/TLS connections
-wsWebSocketClient.missingLocationHeader=Failed to handle HTTP response code [{0}]. Missing Location header in response
-wsWebSocketClient.redirectThreshold=Cyclic Location header [{0}] detected / reached max number of redirects [{1}] of max [{2}]
-wsWebSocketClient.unsupportedAuthScheme=Failed to handle HTTP response code [{0}]. Unsupported Authentication scheme [{1}] returned in response
-wsWebSocketClient.failedAuthentication=Failed to handle HTTP response code [{0}]. Authentication header was not accepted by server.
-wsWebSocketClient.missingWWWAuthenticateHeader=Failed to handle HTTP response code [{0}]. Missing WWW-Authenticate header in response
\ No newline at end of file
+wsWebSocketContainer.asynchronousSocketChannelFail=Unable to open a connection to the server
+wsWebSocketContainer.httpRequestFailed=The HTTP request to initiate the WebSocket connection failed
+wsWebSocketContainer.invalidExtensionParameters=The server responded with extension parameters the client is unable to support
+wsWebSocketContainer.invalidHeader=Unable to parse HTTP header as no colon is present to delimit header name and header value in [{0}]. The header has been skipped.
+wsWebSocketContainer.invalidStatus=The HTTP response from the server [{0}] did not permit the HTTP upgrade to WebSocket
+wsWebSocketContainer.invalidSubProtocol=The WebSocket server returned multiple values for the Sec-WebSocket-Protocol header
+wsWebSocketContainer.pathNoHost=No host was specified in URI
+wsWebSocketContainer.pathWrongScheme=The scheme [{0}] is not supported. The supported schemes are ws and wss
+wsWebSocketContainer.proxyConnectFail=Failed to connect to the configured Proxy [{0}]. The HTTP response code was [{1}]
+wsWebSocketContainer.sslEngineFail=Unable to create SSLEngine to support SSL/TLS connections
+wsWebSocketContainer.missingLocationHeader=Failed to handle HTTP response code [{0}]. Missing Location header in response
+wsWebSocketContainer.redirectThreshold=Cyclic Location header [{0}] detected / reached max number of redirects [{1}] of max [{2}]
+wsWebSocketContainer.unsupportedAuthScheme=Failed to handle HTTP response code [{0}]. Unsupported Authentication scheme [{1}] returned in response
+wsWebSocketContainer.failedAuthentication=Failed to handle HTTP response code [{0}]. Authentication header was not accepted by server.
+wsWebSocketContainer.missingWWWAuthenticateHeader=Failed to handle HTTP response code [{0}]. Missing WWW-Authenticate header in response
\ No newline at end of file
Modified: tomcat/trunk/java/org/apache/tomcat/websocket/WsWebSocketContainer.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/WsWebSocketContainer.java?rev=1812142&r1=1812141&r2=1812142&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/WsWebSocketContainer.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/WsWebSocketContainer.java Fri Oct 13 15:25:23 2017
@@ -76,7 +76,6 @@ import org.apache.tomcat.websocket.pojo.
public class WsWebSocketContainer implements WebSocketContainer, BackgroundProcess {
private static final StringManager sm = StringManager.getManager(WsWebSocketContainer.class);
-
private static final Random RANDOM = new Random();
private static final byte[] CRLF = new byte[] { 13, 10 };
@@ -195,172 +194,6 @@ public class WsWebSocketContainer implem
return connectToServerRecursive(endpoint, clientEndpointConfiguration, path, new HashSet<>());
}
- protected void registerSession(Endpoint endpoint, WsSession wsSession) {
-
- if (!wsSession.isOpen()) {
- // The session was closed during onOpen. No need to register it.
- return;
- }
- synchronized (endPointSessionMapLock) {
- if (endpointSessionMap.size() == 0) {
- BackgroundProcessManager.getInstance().register(this);
- }
- Set<WsSession> wsSessions = endpointSessionMap.get(endpoint);
- if (wsSessions == null) {
- wsSessions = new HashSet<>();
- endpointSessionMap.put(endpoint, wsSessions);
- }
- wsSessions.add(wsSession);
- }
- sessions.put(wsSession, wsSession);
- }
-
-
- protected void unregisterSession(Endpoint endpoint, WsSession wsSession) {
-
- synchronized (endPointSessionMapLock) {
- Set<WsSession> wsSessions = endpointSessionMap.get(endpoint);
- if (wsSessions != null) {
- wsSessions.remove(wsSession);
- if (wsSessions.size() == 0) {
- endpointSessionMap.remove(endpoint);
- }
- }
- if (endpointSessionMap.size() == 0) {
- BackgroundProcessManager.getInstance().unregister(this);
- }
- }
- sessions.remove(wsSession);
- }
-
-
- Set<Session> getOpenSessions(Endpoint endpoint) {
- Set<Session> result = new HashSet<>();
- synchronized (endPointSessionMapLock) {
- Set<WsSession> sessions = endpointSessionMap.get(endpoint);
- if (sessions != null) {
- result.addAll(sessions);
- }
- }
- return result;
- }
-
- @Override
- public long getDefaultMaxSessionIdleTimeout() {
- return defaultMaxSessionIdleTimeout;
- }
-
-
- @Override
- public void setDefaultMaxSessionIdleTimeout(long timeout) {
- this.defaultMaxSessionIdleTimeout = timeout;
- }
-
-
- @Override
- public int getDefaultMaxBinaryMessageBufferSize() {
- return maxBinaryMessageBufferSize;
- }
-
-
- @Override
- public void setDefaultMaxBinaryMessageBufferSize(int max) {
- maxBinaryMessageBufferSize = max;
- }
-
-
- @Override
- public int getDefaultMaxTextMessageBufferSize() {
- return maxTextMessageBufferSize;
- }
-
-
- @Override
- public void setDefaultMaxTextMessageBufferSize(int max) {
- maxTextMessageBufferSize = max;
- }
-
-
- /**
- * {@inheritDoc}
- *
- * Currently, this implementation does not support any extensions.
- */
- @Override
- public Set<Extension> getInstalledExtensions() {
- return Collections.emptySet();
- }
-
-
- /**
- * {@inheritDoc}
- *
- * The default value for this implementation is -1.
- */
- @Override
- public long getDefaultAsyncSendTimeout() {
- return defaultAsyncTimeout;
- }
-
-
- /**
- * {@inheritDoc}
- *
- * The default value for this implementation is -1.
- */
- @Override
- public void setAsyncSendTimeout(long timeout) {
- this.defaultAsyncTimeout = timeout;
- }
-
-
- /**
- * Cleans up the resources still in use by WebSocket sessions created from
- * this container. This includes closing sessions and cancelling
- * {@link Future}s associated with blocking read/writes.
- */
- public void destroy() {
- CloseReason cr = new CloseReason(
- CloseCodes.GOING_AWAY, sm.getString("wsWebSocketContainer.shutdown"));
-
- for (WsSession session : sessions.keySet()) {
- try {
- session.close(cr);
- } catch (IOException ioe) {
- log.debug(sm.getString(
- "wsWebSocketContainer.sessionCloseFail", session.getId()), ioe);
- }
- }
-
- // Only unregister with AsyncChannelGroupUtil if this instance
- // registered with it
- if (asynchronousChannelGroup != null) {
- synchronized (asynchronousChannelGroupLock) {
- if (asynchronousChannelGroup != null) {
- AsyncChannelGroupUtil.unregister();
- asynchronousChannelGroup = null;
- }
- }
- }
- }
-
-
- protected AsynchronousChannelGroup getAsynchronousChannelGroup() {
- // Use AsyncChannelGroupUtil to share a common group amongst all
- // WebSocket clients
- AsynchronousChannelGroup result = asynchronousChannelGroup;
- if (result == null) {
- synchronized (asynchronousChannelGroupLock) {
- if (asynchronousChannelGroup == null) {
- asynchronousChannelGroup = AsyncChannelGroupUtil.register();
- }
- result = asynchronousChannelGroup;
- }
- }
- return result;
- }
-
-
private Session connectToServerRecursive(Endpoint endpoint,
ClientEndpointConfig clientEndpointConfiguration, URI path,
Set<URI> redirectSet)
@@ -379,14 +212,14 @@ public class WsWebSocketContainer implem
secure = true;
} else {
throw new DeploymentException(sm.getString(
- "wsWebSocketClient.pathWrongScheme", scheme));
+ "wsWebSocketContainer.pathWrongScheme", scheme));
}
// Validate host
String host = path.getHost();
if (host == null) {
throw new DeploymentException(
- sm.getString("wsWebSocketClient.pathNoHost"));
+ sm.getString("wsWebSocketContainer.pathNoHost"));
}
int port = path.getPort();
@@ -445,7 +278,7 @@ public class WsWebSocketContainer implem
socketChannel = AsynchronousSocketChannel.open(getAsynchronousChannelGroup());
} catch (IOException ioe) {
throw new DeploymentException(sm.getString(
- "wsWebSocketClient.asynchronousSocketChannelFail"), ioe);
+ "wsWebSocketContainer.asynchronousSocketChannelFail"), ioe);
}
Map<String,Object> userProperties = clientEndpointConfiguration.getUserProperties();
@@ -478,7 +311,7 @@ public class WsWebSocketContainer implem
HttpResponse httpResponse = processResponse(response, channel, timeout);
if (httpResponse.getStatus() != 200) {
throw new DeploymentException(sm.getString(
- "wsWebSocketClient.proxyConnectFail", selectedProxy,
+ "wsWebSocketContainer.proxyConnectFail", selectedProxy,
Integer.toString(httpResponse.getStatus())));
}
} catch (TimeoutException | InterruptedException | ExecutionException |
@@ -487,7 +320,7 @@ public class WsWebSocketContainer implem
channel.close();
}
throw new DeploymentException(
- sm.getString("wsWebSocketClient.httpRequestFailed"), e);
+ sm.getString("wsWebSocketContainer.httpRequestFailed"), e);
}
}
@@ -530,7 +363,7 @@ public class WsWebSocketContainer implem
if (locationHeader == null || locationHeader.isEmpty() ||
locationHeader.get(0) == null || locationHeader.get(0).isEmpty()) {
throw new DeploymentException(sm.getString(
- "wsWebSocketClient.missingLocationHeader",
+ "wsWebSocketContainer.missingLocationHeader",
Integer.toString(httpResponse.status)));
}
@@ -551,7 +384,7 @@ public class WsWebSocketContainer implem
if (!redirectSet.add(redirectLocation) || redirectSet.size() > maxRedirects) {
throw new DeploymentException(sm.getString(
- "wsWebSocketClient.redirectThreshold", redirectLocation,
+ "wsWebSocketContainer.redirectThreshold", redirectLocation,
Integer.toString(redirectSet.size()),
Integer.toString(maxRedirects)));
}
@@ -564,7 +397,7 @@ public class WsWebSocketContainer implem
if (userProperties.get(Constants.AUTHORIZATION_HEADER_NAME) != null) {
throw new DeploymentException(sm.getString(
- "wsWebSocketClient.failedAuthentication",
+ "wsWebSocketContainer.failedAuthentication",
Integer.valueOf(httpResponse.status)));
}
@@ -574,7 +407,7 @@ public class WsWebSocketContainer implem
if (wwwAuthenticateHeaders == null || wwwAuthenticateHeaders.isEmpty() ||
wwwAuthenticateHeaders.get(0) == null || wwwAuthenticateHeaders.get(0).isEmpty()) {
throw new DeploymentException(sm.getString(
- "wsWebSocketClient.missingWWWAuthenticateHeader",
+ "wsWebSocketContainer.missingWWWAuthenticateHeader",
Integer.toString(httpResponse.status)));
}
@@ -586,7 +419,7 @@ public class WsWebSocketContainer implem
if (auth == null) {
throw new DeploymentException(
- sm.getString("wsWebSocketClient.unsupportedAuthScheme",
+ sm.getString("wsWebSocketContainer.unsupportedAuthScheme",
Integer.valueOf(httpResponse.status), authScheme));
}
@@ -598,7 +431,7 @@ public class WsWebSocketContainer implem
}
else {
- throw new DeploymentException(sm.getString("wsWebSocketClient.invalidStatus",
+ throw new DeploymentException(sm.getString("wsWebSocketContainer.invalidStatus",
Integer.toString(httpResponse.status)));
}
}
@@ -614,7 +447,7 @@ public class WsWebSocketContainer implem
subProtocol = protocolHeaders.get(0);
} else {
throw new DeploymentException(
- sm.getString("wsWebSocketClient.invalidSubProtocol"));
+ sm.getString("wsWebSocketContainer.invalidSubProtocol"));
}
// Extensions
@@ -636,7 +469,7 @@ public class WsWebSocketContainer implem
Transformation t = factory.create(extension.getName(), wrapper, false);
if (t == null) {
throw new DeploymentException(sm.getString(
- "wsWebSocketClient.invalidExtensionParameters"));
+ "wsWebSocketContainer.invalidExtensionParameters"));
}
if (transformation == null) {
transformation = t;
@@ -649,7 +482,7 @@ public class WsWebSocketContainer implem
} catch (ExecutionException | InterruptedException | SSLException |
EOFException | TimeoutException | URISyntaxException | AuthenticationException e) {
throw new DeploymentException(
- sm.getString("wsWebSocketClient.httpRequestFailed"), e);
+ sm.getString("wsWebSocketContainer.httpRequestFailed"), e);
} finally {
if (!success) {
channel.close();
@@ -744,6 +577,56 @@ public class WsWebSocketContainer implem
return ByteBuffer.wrap(bytes);
}
+ protected void registerSession(Endpoint endpoint, WsSession wsSession) {
+
+ if (!wsSession.isOpen()) {
+ // The session was closed during onOpen. No need to register it.
+ return;
+ }
+ synchronized (endPointSessionMapLock) {
+ if (endpointSessionMap.size() == 0) {
+ BackgroundProcessManager.getInstance().register(this);
+ }
+ Set<WsSession> wsSessions = endpointSessionMap.get(endpoint);
+ if (wsSessions == null) {
+ wsSessions = new HashSet<>();
+ endpointSessionMap.put(endpoint, wsSessions);
+ }
+ wsSessions.add(wsSession);
+ }
+ sessions.put(wsSession, wsSession);
+ }
+
+
+ protected void unregisterSession(Endpoint endpoint, WsSession wsSession) {
+
+ synchronized (endPointSessionMapLock) {
+ Set<WsSession> wsSessions = endpointSessionMap.get(endpoint);
+ if (wsSessions != null) {
+ wsSessions.remove(wsSession);
+ if (wsSessions.size() == 0) {
+ endpointSessionMap.remove(endpoint);
+ }
+ }
+ if (endpointSessionMap.size() == 0) {
+ BackgroundProcessManager.getInstance().unregister(this);
+ }
+ }
+ sessions.remove(wsSession);
+ }
+
+
+ Set<Session> getOpenSessions(Endpoint endpoint) {
+ HashSet<Session> result = new HashSet<>();
+ synchronized (endPointSessionMapLock) {
+ Set<WsSession> sessions = endpointSessionMap.get(endpoint);
+ if (sessions != null) {
+ result.addAll(sessions);
+ }
+ }
+ return result;
+ }
+
private static Map<String, List<String>> createRequestHeaders(String host, int port,
ClientEndpointConfig clientEndpointConfiguration) {
@@ -933,13 +816,13 @@ public class WsWebSocketContainer implem
// CONNECT for proxy may return a 1.0 response
if (parts.length < 2 || !("HTTP/1.0".equals(parts[0]) || "HTTP/1.1".equals(parts[0]))) {
throw new DeploymentException(sm.getString(
- "wsWebSocketClient.invalidStatus", line));
+ "wsWebSocketContainer.invalidStatus", line));
}
try {
return Integer.parseInt(parts[1]);
} catch (NumberFormatException nfe) {
throw new DeploymentException(sm.getString(
- "wsWebSocketClient.invalidStatus", line));
+ "wsWebSocketContainer.invalidStatus", line));
}
}
@@ -949,7 +832,7 @@ public class WsWebSocketContainer implem
int index = line.indexOf(':');
if (index == -1) {
- log.warn(sm.getString("wsWebSocketClient.invalidHeader", line));
+ log.warn(sm.getString("wsWebSocketContainer.invalidHeader", line));
return;
}
// Header names are case insensitive so always use lower case
@@ -1034,28 +917,127 @@ public class WsWebSocketContainer implem
return engine;
} catch (Exception e) {
throw new DeploymentException(sm.getString(
- "wsWebSocketClient.sslEngineFail"), e);
+ "wsWebSocketContainer.sslEngineFail"), e);
}
}
- private static class HttpResponse {
- private final int status;
- private final HandshakeResponse handshakeResponse;
- public HttpResponse(int status, HandshakeResponse handshakeResponse) {
- this.status = status;
- this.handshakeResponse = handshakeResponse;
+ @Override
+ public long getDefaultMaxSessionIdleTimeout() {
+ return defaultMaxSessionIdleTimeout;
+ }
+
+
+ @Override
+ public void setDefaultMaxSessionIdleTimeout(long timeout) {
+ this.defaultMaxSessionIdleTimeout = timeout;
+ }
+
+
+ @Override
+ public int getDefaultMaxBinaryMessageBufferSize() {
+ return maxBinaryMessageBufferSize;
+ }
+
+
+ @Override
+ public void setDefaultMaxBinaryMessageBufferSize(int max) {
+ maxBinaryMessageBufferSize = max;
+ }
+
+
+ @Override
+ public int getDefaultMaxTextMessageBufferSize() {
+ return maxTextMessageBufferSize;
+ }
+
+
+ @Override
+ public void setDefaultMaxTextMessageBufferSize(int max) {
+ maxTextMessageBufferSize = max;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ *
+ * Currently, this implementation does not support any extensions.
+ */
+ @Override
+ public Set<Extension> getInstalledExtensions() {
+ return Collections.emptySet();
+ }
+
+
+ /**
+ * {@inheritDoc}
+ *
+ * The default value for this implementation is -1.
+ */
+ @Override
+ public long getDefaultAsyncSendTimeout() {
+ return defaultAsyncTimeout;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ *
+ * The default value for this implementation is -1.
+ */
+ @Override
+ public void setAsyncSendTimeout(long timeout) {
+ this.defaultAsyncTimeout = timeout;
+ }
+
+
+ /**
+ * Cleans up the resources still in use by WebSocket sessions created from
+ * this container. This includes closing sessions and cancelling
+ * {@link Future}s associated with blocking read/writes.
+ */
+ public void destroy() {
+ CloseReason cr = new CloseReason(
+ CloseCodes.GOING_AWAY, sm.getString("wsWebSocketContainer.shutdown"));
+
+ for (WsSession session : sessions.keySet()) {
+ try {
+ session.close(cr);
+ } catch (IOException ioe) {
+ log.debug(sm.getString(
+ "wsWebSocketContainer.sessionCloseFail", session.getId()), ioe);
+ }
}
- public int getStatus() {
- return status;
+ // Only unregister with AsyncChannelGroupUtil if this instance
+ // registered with it
+ if (asynchronousChannelGroup != null) {
+ synchronized (asynchronousChannelGroupLock) {
+ if (asynchronousChannelGroup != null) {
+ AsyncChannelGroupUtil.unregister();
+ asynchronousChannelGroup = null;
+ }
+ }
}
+ }
- public HandshakeResponse getHandshakeResponse() {
- return handshakeResponse;
+
+ private AsynchronousChannelGroup getAsynchronousChannelGroup() {
+ // Use AsyncChannelGroupUtil to share a common group amongst all
+ // WebSocket clients
+ AsynchronousChannelGroup result = asynchronousChannelGroup;
+ if (result == null) {
+ synchronized (asynchronousChannelGroupLock) {
+ if (asynchronousChannelGroup == null) {
+ asynchronousChannelGroup = AsyncChannelGroupUtil.register();
+ }
+ result = asynchronousChannelGroup;
+ }
}
+ return result;
}
+
// ----------------------------------------------- BackgroundProcess methods
@Override
@@ -1090,4 +1072,24 @@ public class WsWebSocketContainer implem
return processPeriod;
}
+
+ private static class HttpResponse {
+ private final int status;
+ private final HandshakeResponse handshakeResponse;
+
+ public HttpResponse(int status, HandshakeResponse handshakeResponse) {
+ this.status = status;
+ this.handshakeResponse = handshakeResponse;
+ }
+
+
+ public int getStatus() {
+ return status;
+ }
+
+
+ public HandshakeResponse getHandshakeResponse() {
+ return handshakeResponse;
+ }
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org