Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'jetty-websocket/websocket-api/src')
-rw-r--r--jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/BadPayloadException.java2
-rw-r--r--jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/InvalidWebSocketException.java1
-rw-r--r--jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/RemoteEndpoint.java36
-rw-r--r--jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/Session.java20
-rw-r--r--jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/StatusCode.java6
-rw-r--r--jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeRequest.java49
-rw-r--r--jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeResponse.java12
-rw-r--r--jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketListener.java2
-rw-r--r--jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketPolicy.java262
-rw-r--r--jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketClose.java2
-rw-r--r--jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketConnect.java2
-rw-r--r--jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketError.java2
-rw-r--r--jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketFrame.java3
-rw-r--r--jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketMessage.java3
-rw-r--r--jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/WebSocket.java4
-rw-r--r--jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/Extension.java20
-rw-r--r--jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/ExtensionConfig.java10
-rw-r--r--jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/ExtensionFactory.java5
-rw-r--r--jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/Frame.java15
-rw-r--r--jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/IncomingFrames.java5
-rw-r--r--jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/util/QuoteUtil.java56
21 files changed, 417 insertions, 100 deletions
diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/BadPayloadException.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/BadPayloadException.java
index 70f57af746..262150b9ff 100644
--- a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/BadPayloadException.java
+++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/BadPayloadException.java
@@ -20,7 +20,7 @@ package org.eclipse.jetty.websocket.api;
/**
* Exception to terminate the connection because it has received data within a frame payload that was not consistent with the requirements of that frame
- * payload. (eg: not UTF-8 in a text frame, or a bad data seen in the {@link PerMessageCompressionExtension})
+ * payload. (eg: not UTF-8 in a text frame, or a unexpected data seen by an extension)
*
* @see StatusCode#BAD_PAYLOAD
*/
diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/InvalidWebSocketException.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/InvalidWebSocketException.java
index 3ffe7f124d..6cd55ec425 100644
--- a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/InvalidWebSocketException.java
+++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/InvalidWebSocketException.java
@@ -18,6 +18,7 @@
package org.eclipse.jetty.websocket.api;
+
/**
* Indicating that the provided Class is not a valid WebSocket as defined by the API.
* <p>
diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/RemoteEndpoint.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/RemoteEndpoint.java
index dfdefecd7c..c1d000c37b 100644
--- a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/RemoteEndpoint.java
+++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/RemoteEndpoint.java
@@ -35,19 +35,27 @@ public interface RemoteEndpoint
void sendBytes(ByteBuffer data) throws IOException;
/**
- * Initiates the asynchronous transmission of a binary message. This method returns before the message is transmitted. Developers may provide a callback to
- * be notified when the message has been transmitted, or may use the returned Future object to track progress of the transmission. Errors in transmission
- * are given to the developer in the WriteResult object in either case.
+ * Initiates the asynchronous transmission of a binary message. This method returns before the message is transmitted. Developers may use the returned
+ * Future object to track progress of the transmission.
*
* @param data
* the data being sent
- * @param completion
- * handler that will be notified of progress
* @return the Future object representing the send operation.
*/
Future<Void> sendBytesByFuture(ByteBuffer data);
/**
+ * Initiates the asynchronous transmission of a binary message. This method returns before the message is transmitted. Developers may provide a callback to
+ * be notified when the message has been transmitted or resulted in an error.
+ *
+ * @param data
+ * the data being sent
+ * @param callback
+ * callback to notify of success or failure of the write operation
+ */
+ void sendBytes(ByteBuffer data, WriteCallback callback);
+
+ /**
* Send a binary message in pieces, blocking until all of the message has been transmitted. The runtime reads the message in order. Non-final pieces are
* sent with isLast set to false. The final piece must be sent with isLast set to true.
*
@@ -94,15 +102,23 @@ public interface RemoteEndpoint
void sendString(String text) throws IOException;
/**
- * Initiates the asynchronous transmission of a text message. This method returns before the message is transmitted. Developers may provide a callback to be
- * notified when the message has been transmitted, or may use the returned Future object to track progress of the transmission. Errors in transmission are
- * given to the developer in the WriteResult object in either case.
+ * Initiates the asynchronous transmission of a text message. This method may return before the message is transmitted. Developers may use the returned
+ * Future object to track progress of the transmission.
*
* @param text
* the text being sent
- * @param completion
- * the handler which will be notified of progress
* @return the Future object representing the send operation.
*/
Future<Void> sendStringByFuture(String text);
+
+ /**
+ * Initiates the asynchronous transmission of a text message. This method may return before the message is transmitted. Developers may provide a callback to
+ * be notified when the message has been transmitted or resulted in an error.
+ *
+ * @param text
+ * the text being sent
+ * @param callback
+ * callback to notify of success or failure of the write operation
+ */
+ void sendString(String text, WriteCallback callback);
}
diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/Session.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/Session.java
index 7748dd0899..fdc03086c7 100644
--- a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/Session.java
+++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/Session.java
@@ -22,8 +22,6 @@ import java.io.Closeable;
import java.io.IOException;
import java.net.InetSocketAddress;
-import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
-
/**
* Session represents an active link of communications with a Remote WebSocket Endpoint.
* <p>
@@ -40,7 +38,7 @@ public interface Session extends Closeable
* @see #disconnect()
*/
@Override
- void close() throws IOException;
+ void close();
/**
* Request Close the current conversation, giving a reason for the closure. Note the websocket spec defines the acceptable uses of status codes and reason
@@ -55,7 +53,7 @@ public interface Session extends Closeable
* @see #close(int, String)
* @see #disconnect()
*/
- void close(CloseStatus closeStatus) throws IOException;
+ void close(CloseStatus closeStatus);
/**
* Send a websocket Close frame, with status code.
@@ -72,7 +70,7 @@ public interface Session extends Closeable
* @see #close(CloseStatus)
* @see #disconnect()
*/
- void close(int statusCode, String reason) throws IOException;
+ void close(int statusCode, String reason);
/**
* Issue a harsh disconnect of the underlying connection.
@@ -107,13 +105,6 @@ public interface Session extends Closeable
public InetSocketAddress getLocalAddress();
/**
- * The maximum total length of messages, text or binary, that this Session can handle.
- *
- * @return the message size
- */
- long getMaximumMessageSize();
-
- /**
* Access the (now read-only) {@link WebSocketPolicy} in use for this connection.
*
* @return the policy in use
@@ -179,11 +170,6 @@ public interface Session extends Closeable
void setIdleTimeout(long ms);
/**
- * Sets the maximum total length of messages, text or binary, that this Session can handle.
- */
- void setMaximumMessageSize(long length);
-
- /**
* Suspend a the incoming read events on the connection.
*
* @return the suspend token suitable for resuming the reading of data on the connection.
diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/StatusCode.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/StatusCode.java
index f286e7dbc4..ee3a13c4b9 100644
--- a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/StatusCode.java
+++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/StatusCode.java
@@ -75,6 +75,12 @@ public class StatusCode
* See <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1">RFC 6455, Section 7.4.1 Defined Status Codes</a>.
*/
public final static int NO_CLOSE = 1006;
+
+ /**
+ * Abnormal Close is a synonym for {@link #NO_CLOSE}, used to indicate a close
+ * condition where no close frame was processed from the remote side.
+ */
+ public final static int ABNORMAL = NO_CLOSE;
/**
* 1007 indicates that an endpoint is terminating the connection because it has received data within a message that was not consistent with the type of the
diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeRequest.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeRequest.java
index 28405122f8..8729131d34 100644
--- a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeRequest.java
+++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeRequest.java
@@ -20,12 +20,13 @@ package org.eclipse.jetty.websocket.api;
import java.net.HttpCookie;
import java.net.URI;
+import java.security.Principal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
-import java.util.Locale;
import java.util.Map;
+import java.util.TreeMap;
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
import org.eclipse.jetty.websocket.api.util.QuoteUtil;
@@ -36,8 +37,8 @@ public class UpgradeRequest
private List<String> subProtocols = new ArrayList<>();
private List<ExtensionConfig> extensions = new ArrayList<>();
private List<HttpCookie> cookies = new ArrayList<>();
- private Map<String, List<String>> headers = new HashMap<>();
- private Map<String, String[]> parameters = new HashMap<>();
+ private Map<String, List<String>> headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+ private Map<String, List<String>> parameters = new HashMap<>();
private Object session;
private String httpVersion;
private String method;
@@ -76,6 +77,11 @@ public class UpgradeRequest
}
}
+ public void clearHeaders()
+ {
+ headers.clear();
+ }
+
public List<HttpCookie> getCookies()
{
return cookies;
@@ -88,7 +94,7 @@ public class UpgradeRequest
public String getHeader(String name)
{
- List<String> values = headers.get(name.toLowerCase(Locale.ENGLISH));
+ List<String> values = headers.get(name);
// no value list
if (values == null)
{
@@ -122,7 +128,7 @@ public class UpgradeRequest
public int getHeaderInt(String name)
{
- List<String> values = headers.get(name.toLowerCase(Locale.ENGLISH));
+ List<String> values = headers.get(name);
// no value list
if (values == null)
{
@@ -177,7 +183,7 @@ public class UpgradeRequest
*
* @return a unmodifiable map of query parameters of the request.
*/
- public Map<String, String[]> getParameterMap()
+ public Map<String, List<String>> getParameterMap()
{
return Collections.unmodifiableMap(parameters);
}
@@ -219,6 +225,19 @@ public class UpgradeRequest
return subProtocols;
}
+ /**
+ * Get the User Principal for this request.
+ * <p>
+ * Only applicable when using UpgradeRequest from server side.
+ *
+ * @return the user principal
+ */
+ public Principal getUserPrincipal()
+ {
+ // Server side should override to implement
+ return null;
+ }
+
public boolean hasSubProtocol(String test)
{
for (String protocol : subProtocols)
@@ -248,14 +267,26 @@ public class UpgradeRequest
public void setHeader(String name, List<String> values)
{
- headers.put(name.toLowerCase(Locale.ENGLISH),values);
+ headers.put(name,values);
}
public void setHeader(String name, String value)
{
List<String> values = new ArrayList<>();
values.add(value);
- setHeader(name.toLowerCase(Locale.ENGLISH),values);
+ setHeader(name,values);
+ }
+
+ public void setHeaders(Map<String, List<String>> headers)
+ {
+ clearHeaders();
+
+ for (Map.Entry<String, List<String>> entry : headers.entrySet())
+ {
+ String name = entry.getKey();
+ List<String> values = entry.getValue();
+ setHeader(name,values);
+ }
}
public void setHttpVersion(String httpVersion)
@@ -268,7 +299,7 @@ public class UpgradeRequest
this.method = method;
}
- protected void setParameterMap(Map<String, String[]> parameters)
+ protected void setParameterMap(Map<String, List<String>> parameters)
{
this.parameters.clear();
this.parameters.putAll(parameters);
diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeResponse.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeResponse.java
index cf4424af0f..147c5a01d8 100644
--- a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeResponse.java
+++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeResponse.java
@@ -20,10 +20,10 @@ package org.eclipse.jetty.websocket.api;
import java.io.IOException;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.TreeMap;
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
import org.eclipse.jetty.websocket.api.util.QuoteUtil;
@@ -33,13 +33,13 @@ public class UpgradeResponse
public static final String SEC_WEBSOCKET_PROTOCOL = "Sec-WebSocket-Protocol";
private int statusCode;
private String statusReason;
- private Map<String, List<String>> headers = new HashMap<>();
+ private Map<String, List<String>> headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
private List<ExtensionConfig> extensions = new ArrayList<>();
private boolean success = false;
public void addHeader(String name, String value)
{
- String key = name.toLowerCase();
+ String key = name;
List<String> values = headers.get(key);
if (values == null)
{
@@ -115,7 +115,7 @@ public class UpgradeResponse
public List<String> getHeaders(String name)
{
- return headers.get(name.toLowerCase());
+ return headers.get(name);
}
public int getStatusCode()
@@ -163,8 +163,6 @@ public class UpgradeResponse
/**
* Set the list of extensions that are approved for use with this websocket.
* <p>
- * This is Advanced usage of the WebSocketCreator to allow for a custom set of negotiated extensions.
- * <p>
* Notes:
* <ul>
* <li>Per the spec you cannot add extensions that have not been seen in the {@link UpgradeRequest}, just remove entries you don't want to use</li>
@@ -188,7 +186,7 @@ public class UpgradeResponse
{
List<String> values = new ArrayList<>();
values.add(value);
- headers.put(name.toLowerCase(),values);
+ headers.put(name,values);
}
public void setStatusCode(int statusCode)
diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketListener.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketListener.java
index 89c712736f..8f632a8e6c 100644
--- a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketListener.java
+++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketListener.java
@@ -38,7 +38,7 @@ public interface WebSocketListener
/**
* A Close Event was received.
* <p>
- * The underlying {@link WebSocketConnection} will be considered closed at this point.
+ * The underlying Connection will be considered closed at this point.
*
* @param statusCode
* the close status code. (See {@link StatusCode})
diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketPolicy.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketPolicy.java
index 348a0e06d1..ce20b2ca28 100644
--- a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketPolicy.java
+++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketPolicy.java
@@ -38,9 +38,45 @@ public class WebSocketPolicy
/**
* The maximum size of a text message during parsing/generating.
* <p>
+ * Text messages over this maximum will result in a close code 1009 {@link StatusCode#MESSAGE_TOO_LARGE}
+ * <p>
+ * Default: 65536 (64 K)
+ */
+ private int maxTextMessageSize = 64 * KB;
+
+ /**
+ * The maximum size of a text message buffer.
+ * <p>
+ * Used ONLY for stream based message writing.
+ * <p>
+ * Default: 32768 (32 K)
+ */
+ private int maxTextMessageBufferSize = 32 * KB;
+
+ /**
+ * The maximum size of a binary message during parsing/generating.
+ * <p>
+ * Binary messages over this maximum will result in a close code 1009 {@link StatusCode#MESSAGE_TOO_LARGE}
+ * <p>
* Default: 65536 (64 K)
*/
- private long maxMessageSize = 64 * KB;
+ private int maxBinaryMessageSize = 64 * KB;
+
+ /**
+ * The maximum size of a binary message buffer
+ * <p>
+ * Used ONLY for for stream based message writing
+ * <p>
+ * Default: 32768 (32 K)
+ */
+ private int maxBinaryMessageBufferSize = 32 * KB;
+
+ /**
+ * The timeout in ms (milliseconds) for async write operations.
+ * <p>
+ * Negative values indicate a disabled timeout.
+ */
+ private long asyncWriteTimeout = 60000;
/**
* The time in ms (milliseconds) that a websocket may be idle before closing.
@@ -66,14 +102,42 @@ public class WebSocketPolicy
this.behavior = behavior;
}
- public void assertValidMessageSize(int requestedSize)
+ private void assertLessThan(String name, long size, String otherName, long otherSize)
+ {
+ if (size > otherSize)
+ {
+ throw new IllegalArgumentException(String.format("%s [%d] must be less than %s [%d]",name,size,otherName,otherSize));
+ }
+ }
+
+ private void assertPositive(String name, long size)
+ {
+ if (size < 1)
+ {
+ throw new IllegalArgumentException(String.format("%s [%d] must be a postive value larger than 0",name,size));
+ }
+ }
+
+ public void assertValidBinaryMessageSize(int requestedSize)
+ {
+ if (maxBinaryMessageSize > 0)
+ {
+ // validate it
+ if (requestedSize > maxBinaryMessageSize)
+ {
+ throw new MessageTooLargeException("Binary message size [" + requestedSize + "] exceeds maximum size [" + maxBinaryMessageSize + "]");
+ }
+ }
+ }
+
+ public void assertValidTextMessageSize(int requestedSize)
{
- if (maxMessageSize > 0)
+ if (maxTextMessageSize > 0)
{
// validate it
- if (requestedSize > maxMessageSize)
+ if (requestedSize > maxTextMessageSize)
{
- throw new MessageTooLargeException("Requested message size [" + requestedSize + "] exceeds maximum size [" + maxMessageSize + "]");
+ throw new MessageTooLargeException("Text message size [" + requestedSize + "] exceeds maximum size [" + maxTextMessageSize + "]");
}
}
}
@@ -82,43 +146,213 @@ public class WebSocketPolicy
{
WebSocketPolicy clone = new WebSocketPolicy(this.behavior);
clone.idleTimeout = this.idleTimeout;
- clone.maxMessageSize = this.maxMessageSize;
+ clone.maxTextMessageSize = this.maxTextMessageSize;
+ clone.maxTextMessageBufferSize = this.maxTextMessageBufferSize;
+ clone.maxBinaryMessageSize = this.maxBinaryMessageSize;
+ clone.maxBinaryMessageBufferSize = this.maxBinaryMessageBufferSize;
clone.inputBufferSize = this.inputBufferSize;
+ clone.asyncWriteTimeout = this.asyncWriteTimeout;
return clone;
}
+ /**
+ * The timeout in ms (milliseconds) for async write operations.
+ * <p>
+ * Negative values indicate a disabled timeout.
+ *
+ * @return the timeout for async write operations. negative values indicate disabled timeout.
+ */
+ public long getAsyncWriteTimeout()
+ {
+ return asyncWriteTimeout;
+ }
+
public WebSocketBehavior getBehavior()
{
return behavior;
}
+ /**
+ * The time in ms (milliseconds) that a websocket connection mad by idle before being closed automatically.
+ *
+ * @return the timeout in milliseconds for idle timeout.
+ */
public long getIdleTimeout()
{
return idleTimeout;
}
+ /**
+ * The size of the input (read from network layer) buffer size.
+ * <p>
+ * This is the raw read operation buffer size, before the parsing of the websocket frames.
+ *
+ * @return the raw network bytes read operation buffer size.
+ */
public int getInputBufferSize()
{
return inputBufferSize;
}
- public long getMaxMessageSize()
+ /**
+ * Get the maximum size of a binary message buffer (for streaming writing)
+ *
+ * @return the maximum size of a binary message buffer
+ */
+ public int getMaxBinaryMessageBufferSize()
+ {
+ return maxBinaryMessageBufferSize;
+ }
+
+ /**
+ * Get the maximum size of a binary message during parsing/generating.
+ * <p>
+ * Binary messages over this maximum will result in a close code 1009 {@link StatusCode#MESSAGE_TOO_LARGE}
+ *
+ * @return the maximum size of a binary message
+ */
+ public int getMaxBinaryMessageSize()
+ {
+ return maxBinaryMessageSize;
+ }
+
+ /**
+ * Get the maximum size of a text message buffer (for streaming writing)
+ *
+ * @return the maximum size of a text message buffer
+ */
+ public int getMaxTextMessageBufferSize()
+ {
+ return maxTextMessageBufferSize;
+ }
+
+ /**
+ * Get the maximum size of a text message during parsing/generating.
+ * <p>
+ * Text messages over this maximum will result in a close code 1009 {@link StatusCode#MESSAGE_TOO_LARGE}
+ *
+ * @return the maximum size of a text message.
+ */
+ public int getMaxTextMessageSize()
+ {
+ return maxTextMessageSize;
+ }
+
+ /**
+ * The timeout in ms (milliseconds) for async write operations.
+ * <p>
+ * Negative values indicate a disabled timeout.
+ *
+ * @param ms
+ * the timeout in milliseconds
+ */
+ public void setAsyncWriteTimeout(long ms)
+ {
+ assertLessThan("AsyncWriteTimeout",ms,"IdleTimeout",idleTimeout);
+ this.asyncWriteTimeout = ms;
+ }
+
+ /**
+ * The time in ms (milliseconds) that a websocket may be idle before closing.
+ *
+ * @param ms
+ * the timeout in milliseconds
+ */
+ public void setIdleTimeout(long ms)
+ {
+ assertPositive("IdleTimeout",ms);
+ this.idleTimeout = ms;
+ }
+
+ /**
+ * The size of the input (read from network layer) buffer size.
+ *
+ * @param size
+ * the size in bytes
+ */
+ public void setInputBufferSize(int size)
+ {
+ assertPositive("InputBufferSize",size);
+ assertLessThan("InputBufferSize",size,"MaxTextMessageBufferSize",maxTextMessageBufferSize);
+ assertLessThan("InputBufferSize",size,"MaxBinaryMessageBufferSize",maxBinaryMessageBufferSize);
+
+ this.inputBufferSize = size;
+ }
+
+ /**
+ * The maximum size of a binary message buffer.
+ * <p>
+ * Used ONLY for stream based message writing.
+ *
+ * @param size
+ * the maximum size of the binary message buffer
+ */
+ public void setMaxBinaryMessageBufferSize(int size)
+ {
+ assertPositive("MaxBinaryMessageBufferSize",size);
+
+ this.maxBinaryMessageBufferSize = size;
+ }
+
+ /**
+ * The maximum size of a binary message during parsing/generating.
+ * <p>
+ * Binary messages over this maximum will result in a close code 1009 {@link StatusCode#MESSAGE_TOO_LARGE}
+ *
+ * @param size
+ * the maximum allowed size of a binary message.
+ */
+ public void setMaxBinaryMessageSize(int size)
{
- return maxMessageSize;
+ assertPositive("MaxBinaryMessageSize",size);
+
+ this.maxBinaryMessageSize = size;
}
- public void setIdleTimeout(long idleTimeout)
+ /**
+ * The maximum size of a text message buffer.
+ * <p>
+ * Used ONLY for stream based message writing.
+ *
+ * @param size
+ * the maximum size of the text message buffer
+ */
+ public void setMaxTextMessageBufferSize(int size)
{
- this.idleTimeout = idleTimeout;
+ assertPositive("MaxTextMessageBufferSize",size);
+
+ this.maxTextMessageBufferSize = size;
}
- public void setInputBufferSize(int inputBufferSize)
+ /**
+ * The maximum size of a text message during parsing/generating.
+ * <p>
+ * Text messages over this maximum will result in a close code 1009 {@link StatusCode#MESSAGE_TOO_LARGE}
+ *
+ * @param size
+ * the maximum allowed size of a text message.
+ */
+ public void setMaxTextMessageSize(int size)
{
- this.inputBufferSize = inputBufferSize;
+ assertPositive("MaxTextMessageSize",size);
+
+ this.maxTextMessageSize = size;
}
- public void setMaxMessageSize(long maxMessageSize)
+ @Override
+ public String toString()
{
- this.maxMessageSize = maxMessageSize;
+ StringBuilder builder = new StringBuilder();
+ builder.append("WebSocketPolicy@").append(Integer.toHexString(hashCode()));
+ builder.append("[behavior=").append(behavior);
+ builder.append(",maxTextMessageSize=").append(maxTextMessageSize);
+ builder.append(",maxTextMessageBufferSize=").append(maxTextMessageBufferSize);
+ builder.append(",maxBinaryMessageSize=").append(maxBinaryMessageSize);
+ builder.append(",maxBinaryMessageBufferSize=").append(maxBinaryMessageBufferSize);
+ builder.append(",asyncWriteTimeout=").append(asyncWriteTimeout);
+ builder.append(",idleTimeout=").append(idleTimeout);
+ builder.append(",inputBufferSize=").append(inputBufferSize);
+ builder.append("]");
+ return builder.toString();
}
}
diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketClose.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketClose.java
index cd348b9a09..285cbd19c5 100644
--- a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketClose.java
+++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketClose.java
@@ -24,8 +24,6 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
-import org.eclipse.jetty.websocket.api.Session;
-
/**
* Annotation for tagging methods to receive connection close events.
* <p>
diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketConnect.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketConnect.java
index f9e427e0d5..d35640da09 100644
--- a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketConnect.java
+++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketConnect.java
@@ -24,8 +24,6 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
-import org.eclipse.jetty.websocket.api.Session;
-
/**
* Annotation for tagging methods to receive connection open events.
* <p>
diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketError.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketError.java
index 452ab922d7..89afe36847 100644
--- a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketError.java
+++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketError.java
@@ -24,8 +24,6 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
-import org.eclipse.jetty.websocket.api.Session;
-
/**
* Annotation for receiving websocket errors (exceptions) that have occurred internally in the websocket implementation.
* <p>
diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketFrame.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketFrame.java
index 13f8309266..f12e8a135d 100644
--- a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketFrame.java
+++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketFrame.java
@@ -24,9 +24,6 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
-import org.eclipse.jetty.websocket.api.Session;
-import org.eclipse.jetty.websocket.api.extensions.Frame;
-
/**
* (ADVANCED) Annotation for tagging methods to receive frame events.
* <p>
diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketMessage.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketMessage.java
index 9d62877055..e26b277e1c 100644
--- a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketMessage.java
+++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketMessage.java
@@ -18,15 +18,12 @@
package org.eclipse.jetty.websocket.api.annotations;
-import java.io.Reader;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
-import org.eclipse.jetty.websocket.api.Session;
-
/**
* Annotation for tagging methods to receive Binary or Text Message events.
* <p>
diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/WebSocket.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/WebSocket.java
index a95378b6ec..a62c36b3f9 100644
--- a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/WebSocket.java
+++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/WebSocket.java
@@ -35,7 +35,9 @@ public @interface WebSocket
{
int inputBufferSize() default -2;
+ int maxBinaryMessageSize() default -2;
+
int maxIdleTime() default -2;
- int maxMessageSize() default -2;
+ int maxTextMessageSize() default -2;
}
diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/Extension.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/Extension.java
index 1db2187866..09064ffb48 100644
--- a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/Extension.java
+++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/Extension.java
@@ -21,7 +21,7 @@ package org.eclipse.jetty.websocket.api.extensions;
/**
* Interface for WebSocket Extensions.
* <p>
- * That work is performed by the two {@link FrameHandler} implementations for incoming and outgoing frame handling.
+ * That {@link Frame}s are passed through the Extension via the {@link IncomingFrames} and {@link OutgoingFrames} interfaces
*/
public interface Extension extends IncomingFrames, OutgoingFrames
{
@@ -67,19 +67,6 @@ public interface Extension extends IncomingFrames, OutgoingFrames
public abstract boolean isRsv3User();
/**
- * Used to indicate that the extension works as a decoder of TEXT Data Frames.
- * <p>
- * This is used to adjust validation during parsing/generating, as per spec TEXT Data Frames can only contain UTF8 encoded String data.
- * <p>
- * Example: a compression extension will process a compressed set of text data, the parser/generator should no longer be concerned about the validity of the
- * TEXT Data Frames as this is now the responsibility of the extension.
- *
- * @return true if extension will process TEXT Data Frames, false if extension makes no modifications of TEXT Data Frames. If false, the parser/generator is
- * now free to validate the conformance to spec of TEXT Data Frames.
- */
- public abstract boolean isTextDataDecoder();
-
- /**
* Set the next {@link IncomingFrames} to call in the chain.
*
* @param nextIncoming
@@ -94,4 +81,9 @@ public interface Extension extends IncomingFrames, OutgoingFrames
* the next outgoing extension
*/
public void setNextOutgoingFrames(OutgoingFrames nextOutgoing);
+
+ // TODO: Extension should indicate if it requires boundary of fragments to be preserved
+
+ // TODO: Extension should indicate if it uses the Extension data field of frame for its own reasons.
+
} \ No newline at end of file
diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/ExtensionConfig.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/ExtensionConfig.java
index b03f0cb245..04c01217de 100644
--- a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/ExtensionConfig.java
+++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/ExtensionConfig.java
@@ -96,8 +96,12 @@ public class ExtensionConfig
{
str.append(';');
str.append(param);
- str.append('=');
- QuoteUtil.quoteIfNeeded(str,parameters.get(param),";=");
+ String value = parameters.get(param);
+ if (value != null)
+ {
+ str.append('=');
+ QuoteUtil.quoteIfNeeded(str,value,";=");
+ }
}
return str.toString();
}
@@ -108,7 +112,7 @@ public class ExtensionConfig
}
/**
- * Return parameters in way similar to how {@link javax.net.websocket.extensions.Extension#getParameters()} works.
+ * Return parameters found in request URI.
*
* @return the parameter map
*/
diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/ExtensionFactory.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/ExtensionFactory.java
index b95d10d1a7..7edb2db06f 100644
--- a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/ExtensionFactory.java
+++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/ExtensionFactory.java
@@ -34,7 +34,10 @@ public abstract class ExtensionFactory implements Iterable<Class<? extends Exten
availableExtensions = new HashMap<>();
for (Extension ext : extensionLoader)
{
- availableExtensions.put(ext.getName(),ext.getClass());
+ if (ext != null)
+ {
+ availableExtensions.put(ext.getName(),ext.getClass());
+ }
}
}
diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/Frame.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/Frame.java
index c4cf84bc6e..7a201f8fbc 100644
--- a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/Frame.java
+++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/Frame.java
@@ -81,16 +81,17 @@ public interface Frame
public ByteBuffer getPayload();
+ /**
+ * The original payload length ({@link ByteBuffer#remaining()})
+ *
+ * @return the original payload length ({@link ByteBuffer#remaining()})
+ */
public int getPayloadLength();
- public int getPayloadStart();
-
public Type getType();
public boolean hasPayload();
- public boolean isContinuation();
-
public boolean isFin();
/**
@@ -98,6 +99,7 @@ public interface Frame
*
* @return true if final frame.
*/
+ // FIXME: remove
public boolean isLast();
public boolean isMasked();
@@ -108,5 +110,10 @@ public interface Frame
public boolean isRsv3();
+ /**
+ * The current number of bytes left to read from the payload ByteBuffer.
+ *
+ * @return the current number of bytes left to read from the payload ByteBuffer
+ */
public int remaining();
}
diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/IncomingFrames.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/IncomingFrames.java
index 2ea7e09dd2..a4b578007f 100644
--- a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/IncomingFrames.java
+++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/IncomingFrames.java
@@ -18,15 +18,12 @@
package org.eclipse.jetty.websocket.api.extensions;
-import org.eclipse.jetty.websocket.api.WebSocketException;
-
/**
* Interface for dealing with Incoming Frames.
*/
public interface IncomingFrames
{
- // TODO: JSR-356 change to Throwable
- public void incomingError(WebSocketException e);
+ public void incomingError(Throwable t);
public void incomingFrame(Frame frame);
}
diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/util/QuoteUtil.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/util/QuoteUtil.java
index 42a63fcc0f..eed6f20ed1 100644
--- a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/util/QuoteUtil.java
+++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/util/QuoteUtil.java
@@ -18,8 +18,8 @@
package org.eclipse.jetty.websocket.api.util;
-import java.io.IOException;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;
@@ -342,7 +342,6 @@ public class QuoteUtil
* the string to possibly quote
* @param delim
* the delimiter characters that will trigger automatic quoting
- * @throws IOException
*/
public static void quoteIfNeeded(StringBuilder buf, String str, String delim)
{
@@ -448,4 +447,57 @@ public class QuoteUtil
}
return ret.toString();
}
+
+ public static String join(Object[] objs, String delim)
+ {
+ if (objs == null)
+ {
+ return "";
+ }
+ StringBuilder ret = new StringBuilder();
+ int len = objs.length;
+ for (int i = 0; i < len; i++)
+ {
+ if (i > 0)
+ {
+ ret.append(delim);
+ }
+ if (objs[i] instanceof String)
+ {
+ ret.append('"').append(objs[i]).append('"');
+ }
+ else
+ {
+ ret.append(objs[i]);
+ }
+ }
+ return ret.toString();
+ }
+
+ public static String join(Collection<?> objs, String delim)
+ {
+ if (objs == null)
+ {
+ return "";
+ }
+ StringBuilder ret = new StringBuilder();
+ boolean needDelim = false;
+ for (Object obj : objs)
+ {
+ if (needDelim)
+ {
+ ret.append(delim);
+ }
+ if (obj instanceof String)
+ {
+ ret.append('"').append(obj).append('"');
+ }
+ else
+ {
+ ret.append(obj);
+ }
+ needDelim = true;
+ }
+ return ret.toString();
+ }
}

Back to the top