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 new file mode 100644 index 00000000000..fa53de92876 --- /dev/null +++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/BadPayloadException.java @@ -0,0 +1,44 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +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}) + * + * @see StatusCode#BAD_PAYLOAD + */ +@SuppressWarnings("serial") +public class BadPayloadException extends CloseException +{ + public BadPayloadException(String message) + { + super(StatusCode.BAD_PAYLOAD,message); + } + + public BadPayloadException(String message, Throwable t) + { + super(StatusCode.BAD_PAYLOAD,message,t); + } + + public BadPayloadException(Throwable t) + { + super(StatusCode.BAD_PAYLOAD,t); + } +} diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/CloseException.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/CloseException.java new file mode 100644 index 00000000000..67fd046800c --- /dev/null +++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/CloseException.java @@ -0,0 +1,49 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.api; + +@SuppressWarnings("serial") +public class CloseException extends WebSocketException +{ + private int statusCode; + + public CloseException(int closeCode, String message) + { + super(message); + this.statusCode = closeCode; + } + + public CloseException(int closeCode, String message, Throwable cause) + { + super(message,cause); + this.statusCode = closeCode; + } + + public CloseException(int closeCode, Throwable cause) + { + super(cause); + this.statusCode = closeCode; + } + + public int getStatusCode() + { + return statusCode; + } + +} 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 new file mode 100644 index 00000000000..287eb34f2f8 --- /dev/null +++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/InvalidWebSocketException.java @@ -0,0 +1,43 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.api; + +/** + * Indicating that the provided Class is not a valid WebSocket as defined by the API. + *

+ * A valid WebSocket should do one of the following: + *

+ */ +@SuppressWarnings("serial") +public class InvalidWebSocketException extends WebSocketException +{ + public InvalidWebSocketException(String message) + { + super(message); + } + + public InvalidWebSocketException(String message, Throwable cause) + { + super(message,cause); + } +} diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/MessageTooLargeException.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/MessageTooLargeException.java new file mode 100644 index 00000000000..9d1ecc98b71 --- /dev/null +++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/MessageTooLargeException.java @@ -0,0 +1,43 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.api; + +/** + * Exception when a message is too large for the internal buffers occurs and should trigger a connection close. + * + * @see StatusCode#MESSAGE_TOO_LARGE + */ +@SuppressWarnings("serial") +public class MessageTooLargeException extends CloseException +{ + public MessageTooLargeException(String message) + { + super(StatusCode.MESSAGE_TOO_LARGE,message); + } + + public MessageTooLargeException(String message, Throwable t) + { + super(StatusCode.MESSAGE_TOO_LARGE,message,t); + } + + public MessageTooLargeException(Throwable t) + { + super(StatusCode.MESSAGE_TOO_LARGE,t); + } +} diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/PolicyViolationException.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/PolicyViolationException.java new file mode 100644 index 00000000000..f50e9fc74b4 --- /dev/null +++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/PolicyViolationException.java @@ -0,0 +1,43 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.api; + +/** + * Exception when a violation of policy occurs and should trigger a connection close. + * + * @see StatusCode#POLICY_VIOLATION + */ +@SuppressWarnings("serial") +public class PolicyViolationException extends CloseException +{ + public PolicyViolationException(String message) + { + super(StatusCode.POLICY_VIOLATION,message); + } + + public PolicyViolationException(String message, Throwable t) + { + super(StatusCode.POLICY_VIOLATION,message,t); + } + + public PolicyViolationException(Throwable t) + { + super(StatusCode.POLICY_VIOLATION,t); + } +} diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/ProtocolException.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/ProtocolException.java new file mode 100644 index 00000000000..721f3af4fd5 --- /dev/null +++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/ProtocolException.java @@ -0,0 +1,41 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.api; + +/** + * Per spec, a protocol error should result in a Close frame of status code 1002 (PROTOCOL_ERROR) + */ +@SuppressWarnings("serial") +public class ProtocolException extends CloseException +{ + public ProtocolException(String message) + { + super(StatusCode.PROTOCOL,message); + } + + public ProtocolException(String message, Throwable t) + { + super(StatusCode.PROTOCOL,message,t); + } + + public ProtocolException(Throwable t) + { + super(StatusCode.PROTOCOL,t); + } +} 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 new file mode 100644 index 00000000000..3114c085222 --- /dev/null +++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/StatusCode.java @@ -0,0 +1,141 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.api; + +/** + * The RFC 6455 specified status codes and IANA: WebSocket Close Code Number Registry + */ +public class StatusCode +{ + /** + * 1000 indicates a normal closure, meaning that the purpose for which the connection was established has been fulfilled. + *

+ * See RFC 6455, Section 7.4.1 Defined Status Codes. + */ + public final static int NORMAL = 1000; + + /** + * 1001 indicates that an endpoint is "going away", such as a server going down or a browser having navigated away from a page. + *

+ * See RFC 6455, Section 7.4.1 Defined Status Codes. + */ + public final static int SHUTDOWN = 1001; + + /** + * 1002 indicates that an endpoint is terminating the connection due to a protocol error. + *

+ * See RFC 6455, Section 7.4.1 Defined Status Codes. + */ + public final static int PROTOCOL = 1002; + + /** + * 1003 indicates that an endpoint is terminating the connection because it has received a type of data it cannot accept (e.g., an endpoint that understands + * only text data MAY send this if it receives a binary message). + *

+ * See RFC 6455, Section 7.4.1 Defined Status Codes. + */ + public final static int BAD_DATA = 1003; + + /** + * Reserved. The specific meaning might be defined in the future. + *

+ * See RFC 6455, Section 7.4.1 Defined Status Codes. + */ + public final static int UNDEFINED = 1004; + + /** + * 1005 is a reserved value and MUST NOT be set as a status code in a Close control frame by an endpoint. It is designated for use in applications expecting + * a status code to indicate that no status code was actually present. + *

+ * See RFC 6455, Section 7.4.1 Defined Status Codes. + */ + public final static int NO_CODE = 1005; + + /** + * 1006 is a reserved value and MUST NOT be set as a status code in a Close control frame by an endpoint. It is designated for use in applications expecting + * a status code to indicate that the connection was closed abnormally, e.g., without sending or receiving a Close control frame. + *

+ * See RFC 6455, Section 7.4.1 Defined Status Codes. + */ + public final static int NO_CLOSE = 1006; + + /** + * 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 + * message (e.g., non-UTF-8 [RFC3629] data within a text message). + *

+ * See RFC 6455, Section 7.4.1 Defined Status Codes. + */ + public final static int BAD_PAYLOAD = 1007; + + /** + * 1008 indicates that an endpoint is terminating the connection because it has received a message that violates its policy. This is a generic status code + * that can be returned when there is no other more suitable status code (e.g., 1003 or 1009) or if there is a need to hide specific details about the + * policy. + *

+ * See RFC 6455, Section 7.4.1 Defined Status Codes. + */ + public final static int POLICY_VIOLATION = 1008; + + /** + * 1009 indicates that an endpoint is terminating the connection because it has received a message that is too big for it to process. + *

+ * See RFC 6455, Section 7.4.1 Defined Status Codes. + */ + public final static int MESSAGE_TOO_LARGE = 1009; + + /** + * 1010 indicates that an endpoint (client) is terminating the connection because it has expected the server to negotiate one or more extension, but the + * server didn't return them in the response message of the WebSocket handshake. The list of extensions that are needed SHOULD appear in the /reason/ part + * of the Close frame. Note that this status code is not used by the server, because it can fail the WebSocket handshake instead. + *

+ * See RFC 6455, Section 7.4.1 Defined Status Codes. + */ + public final static int REQUIRED_EXTENSION = 1010; + + /** + * 1011 indicates that a server is terminating the connection because it encountered an unexpected condition that prevented it from fulfilling the request. + *

+ * See RFC 6455, Section 7.4.1 Defined Status Codes. + */ + public final static int SERVER_ERROR = 1011; + + /** + * 1012 indicates that the service is restarted. a client may reconnect, and if it chooses to do, should reconnect using a randomized delay of 5 - 30s. + *

+ * See [hybi] Additional WebSocket Close Error Codes + */ + public final static int SERVICE_RESTART = 1012; + + /** + * 1013 indicates that the service is experiencing overload. a client should only connect to a different IP (when there are multiple for the target) or + * reconnect to the same IP upon user action. + *

+ * See [hybi] Additional WebSocket Close Error Codes + */ + public final static int TRY_AGAIN_LATER = 1013; + + /** + * 1015 is a reserved value and MUST NOT be set as a status code in a Close control frame by an endpoint. It is designated for use in applications expecting + * a status code to indicate that the connection was closed due to a failure to perform a TLS handshake (e.g., the server certificate can't be verified). + *

+ * See RFC 6455, Section 7.4.1 Defined Status Codes. + */ + public final static int FAILED_TLS_HANDSHAKE = 1015; +} diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/SuspendToken.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/SuspendToken.java new file mode 100644 index 00000000000..d64c01da96d --- /dev/null +++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/SuspendToken.java @@ -0,0 +1,30 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.api; + +/** + * Connection suspend token + */ +public interface SuspendToken +{ + /** + * Resume a previously suspended connection. + */ + void resume(); +} \ No newline at end of file diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeException.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeException.java new file mode 100644 index 00000000000..6e353eba081 --- /dev/null +++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeException.java @@ -0,0 +1,46 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.api; + +/** + * Exception during WebSocket Upgrade Handshake. + */ +@SuppressWarnings("serial") +public class UpgradeException extends WebSocketException +{ + public UpgradeException() + { + super(); + } + + public UpgradeException(String message) + { + super(message); + } + + public UpgradeException(String message, Throwable cause) + { + super(message,cause); + } + + public UpgradeException(Throwable cause) + { + super(cause); + } +} 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 new file mode 100644 index 00000000000..825b1fce9a2 --- /dev/null +++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeRequest.java @@ -0,0 +1,59 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.api; + +import java.util.List; +import java.util.Map; + +import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig; + +public interface UpgradeRequest +{ + public void addExtensions(String... extConfigs); + + public Map getCookieMap(); + + public List getExtensions(); + + public String getHeader(String name); + + public Map> getHeaders(); + + public String getHost(); + + public String getHttpVersion(); + + public String getMethod(); + + public String getOrigin(); + + public Map getParameterMap(); + + public String getQueryString(); + + public String getRemoteURI(); + + public List getSubProtocols(); + + public boolean hasSubProtocol(String test); + + public boolean isOrigin(String test); + + public void setSubProtocols(String protocols); +} 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 new file mode 100644 index 00000000000..3f3bb14bfb5 --- /dev/null +++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeResponse.java @@ -0,0 +1,99 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.api; + +import java.io.IOException; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig; + +public interface UpgradeResponse +{ + public void addHeader(String name, String value); + + /** + * Get the accepted WebSocket protocol. + * + * @return the accepted WebSocket protocol. + */ + public String getAcceptedSubProtocol(); + + /** + * Get the list of extensions that should be used for the websocket. + * + * @return the list of negotiated extensions to use. + */ + public List getExtensions(); + + public Set getHeaderNamesSet(); + + public String getHeaderValue(String name); + + public Iterator getHeaderValues(String name); + + public int getStatusCode(); + + public String getStatusReason(); + + public boolean isSuccess(); + + /** + * Issue a forbidden upgrade response. + *

+ * This means that the websocket endpoint was valid, but the conditions to use a WebSocket resulted in a forbidden access. + *

+ * Use this when the origin or authentication is invalid. + * + * @param message + * the short 1 line detail message about the forbidden response + * @throws IOException + */ + public void sendForbidden(String message) throws IOException; + + /** + * Set the accepted WebSocket Protocol. + * + * @param protocol + * the protocol to list as accepted + */ + public void setAcceptedSubProtocol(String protocol); + + /** + * Set the list of extensions that are approved for use with this websocket. + *

+ * This is Advanced usage of the {@link WebSocketCreator} to allow for a custom set of negotiated extensions. + *

+ * Notes: + *

+ * + * @param extensions + * the list of extensions to use. + */ + public void setExtensions(List extensions); + + public void setHeader(String name, String value); + + public void validateWebSocketHash(String expectedHash) throws UpgradeException; +} diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketAdapter.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketAdapter.java new file mode 100644 index 00000000000..843c6e4e8c7 --- /dev/null +++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketAdapter.java @@ -0,0 +1,83 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.api; + +import org.eclipse.jetty.websocket.api.io.WebSocketBlockingConnection; + +/** + * Default implementation of the {@link WebSocketListener}. + *

+ * Convenient abstract class to base standard WebSocket implementations off of. + */ +public class WebSocketAdapter implements WebSocketListener +{ + private WebSocketConnection connection; + private WebSocketBlockingConnection blocking; + + public WebSocketBlockingConnection getBlockingConnection() + { + return blocking; + } + + public WebSocketConnection getConnection() + { + return connection; + } + + public boolean isConnected() + { + return (connection != null) && (connection.isOpen()); + } + + public boolean isNotConnected() + { + return (connection == null) || (!connection.isOpen()); + } + + @Override + public void onWebSocketBinary(byte[] payload, int offset, int len) + { + /* do nothing */ + } + + @Override + public void onWebSocketClose(int statusCode, String reason) + { + this.connection = null; + } + + @Override + public void onWebSocketConnect(WebSocketConnection connection) + { + this.connection = connection; + this.blocking = new WebSocketBlockingConnection(this.connection); + } + + @Override + public void onWebSocketException(WebSocketException error) + { + /* do nothing */ + } + + @Override + public void onWebSocketText(String message) + { + /* do nothing */ + } +} diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketBehavior.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketBehavior.java new file mode 100644 index 00000000000..ad4f452ab5f --- /dev/null +++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketBehavior.java @@ -0,0 +1,31 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.api; + +/** + * Behavior for how the WebSocket should operate. + *

+ * This dictated by the RFC 6455 spec in various places, where certain behavior must be performed depending on + * operation as a CLIENT vs a SERVER + */ +public enum WebSocketBehavior +{ + CLIENT, + SERVER; +} diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketConnection.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketConnection.java new file mode 100644 index 00000000000..c24ebe60e82 --- /dev/null +++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketConnection.java @@ -0,0 +1,134 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.api; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.URI; +import java.nio.ByteBuffer; +import java.util.concurrent.Future; + +/** + * Connection interface for WebSocket protocol RFC-6455. + */ +public interface WebSocketConnection +{ + /** + * Send a websocket Close frame, without a status code or reason. + *

+ * Basic usage: results in an non-blocking async write, then connection close. + * + * @see StatusCode + * @see #close(int, String) + */ + public void close(); + + /** + * Send a websocket Close frame, with status code. + *

+ * Advanced usage: results in an non-blocking async write, then connection close. + * + * @param statusCode + * the status code + * @param reason + * the (optional) reason. (can be null for no reason) + * @see StatusCode + */ + public void close(int statusCode, String reason); + + /** + * Is the connection open. + * + * @return true if open + */ + public boolean isOpen(); + + /** + * Suspend a the incoming read events on the connection. + * + * @return the suspend token suitable for resuming the reading of data on the connection. + */ + SuspendToken suspend(); + + /** + * Get the address of the remote side. + * + * @return the remote side address + */ + public InetSocketAddress getRemoteAddress(); + + /** + * Get the address of the local side. + * + * @return the local side address + */ + public InetSocketAddress getLocalAddress(); + + /** + * Get the Request URI + * + * @return the requested URI + */ + public URI getRequestURI(); + + /** + * Access the (now read-only) {@link WebSocketPolicy} in use for this connection. + * + * @return the policy in use + */ + WebSocketPolicy getPolicy(); + + /** + * Get the SubProtocol in use for this connection. + * + * @return the negotiated sub protocol name in use for this connection, can be null if there is no sub-protocol negotiated. + */ + String getSubProtocol(); + + /** + * Send a single ping messages. + *

+ * NIO style with callbacks, allows for knowledge of successful ping send. + *

+ * Use @OnWebSocketFrame and monitor Pong frames + */ + Future ping(C context, byte payload[]) throws IOException; + + /** + * Send a a binary message. + *

+ * NIO style with callbacks, allows for concurrent results of the write operation. + */ + Future write(C context, byte buf[], int offset, int len) throws IOException; + + /** + * Send a a binary message. + *

+ * NIO style with callbacks, allows for concurrent results of the write operation. + */ + Future write(C context, ByteBuffer buffer) throws IOException; + + /** + * Send a series of text messages. + *

+ * NIO style with callbacks, allows for concurrent results of the entire write operation. (Callback is only called once at the end of processing all of the + * messages) + */ + Future write(C context, String message) throws IOException; +} \ No newline at end of file diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketException.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketException.java new file mode 100644 index 00000000000..e92c209c4e0 --- /dev/null +++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketException.java @@ -0,0 +1,46 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.api; + +/** + * A recoverable exception within the websocket framework. + */ +@SuppressWarnings("serial") +public class WebSocketException extends RuntimeException +{ + public WebSocketException() + { + super(); + } + + public WebSocketException(String message) + { + super(message); + } + + public WebSocketException(String message, Throwable cause) + { + super(message,cause); + } + + public WebSocketException(Throwable cause) + { + super(cause); + } +} 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 new file mode 100644 index 00000000000..68de551830c --- /dev/null +++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketListener.java @@ -0,0 +1,78 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.api; + +/** + * Basic WebSocket Listener interface for incoming WebSocket events. + */ +public interface WebSocketListener +{ + /** + * A WebSocket binary frame has been received. + * + * @param payload the raw payload array received + * @param offset the offset in the payload array where the data starts + * @param len the length of bytes in the payload + */ + void onWebSocketBinary(byte payload[], int offset, int len); + + /** + * A Close Event was received. + *

+ * The underlying {@link WebSocketConnection} will be considered closed at this point. + * + * @param statusCode + * the close status code. (See {@link StatusCode}) + * @param reason + * the optional reason for the close. + */ + void onWebSocketClose(int statusCode, String reason); + + /** + * A WebSocketConnection has connected successfully and is ready to be used. + *

+ * Note: It is a good idea to track this connection as a field in your object so that you can write messages back. + * + * @param connection + * the connection to use to send messages on. + */ + void onWebSocketConnect(WebSocketConnection connection); + + /** + * A WebSocket exception has occurred. + *

+ * Usually this occurs from bad / malformed incoming packets. (example: bad UTF8 data, frames that are too big, violations of the spec) + *

+ * This will result in the {@link WebSocketConnection} being closed by the implementing side. + *

+ * Note: you will receive no {@link #onWebSocketClose(int, String)} as this condition results in the API calling + * {@link WebSocketConnection#close(int, String)} for you. + * + * @param error + * the error that occurred. + */ + void onWebSocketException(WebSocketException error); + + /** + * A WebSocket Text frame was received. + * + * @param message + */ + void onWebSocketText(String message); +} 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 new file mode 100644 index 00000000000..026eaa8ccac --- /dev/null +++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketPolicy.java @@ -0,0 +1,208 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.api; + + +/** + * Settings for WebSocket operations. + */ +public class WebSocketPolicy +{ + public static WebSocketPolicy newClientPolicy() + { + return new WebSocketPolicy(WebSocketBehavior.CLIENT); + } + + public static WebSocketPolicy newServerPolicy() + { + return new WebSocketPolicy(WebSocketBehavior.SERVER); + } + + /** + * Automatically fragment large frames. + *

+ * If frames are encountered at size larger than {@link #maxPayloadSize} then they are automatically fragmented into pieces fitting within the + * maxPayloadSize. + *

+ * Default: false + */ + private boolean autoFragment = false; + + /** + * The maximum allowed payload size (validated in both directions) + *

+ * Default: 65536 (64K) + */ + private int maxPayloadSize = 65536; + + /** + * The maximum size of a text message during parsing/generating. + *

+ * Default: 16384 (16 K) + */ + private int maxTextMessageSize = 16384; + + /** + * The maximum size of a binary message during parsing/generating. + *

+ * Default: -1 (no validation) + */ + private int maxBinaryMessageSize = -1; + + /** + * Maximum Message Buffer size, which is also the max frame byte size. + *

+ * Default: 65536 (64 K) + */ + private int bufferSize = 65536; + + // TODO: change bufferSize to windowSize for FrameBytes logic? + + /** + * The time in ms (milliseconds) that a websocket may be idle before closing. + *

+ * Default: 300000 (ms) + */ + private int idleTimeout = 300000; + + /** + * Behavior of the websockets + */ + private final WebSocketBehavior behavior; + + public WebSocketPolicy(WebSocketBehavior behavior) + { + this.behavior = behavior; + } + + public void assertValidBinaryMessageSize(int requestedSize) + { + if (maxBinaryMessageSize > 0) + { + // validate it + if (requestedSize > maxBinaryMessageSize) + { + throw new MessageTooLargeException("Requested binary message size [" + requestedSize + "] exceeds maximum size [" + maxBinaryMessageSize + "]"); + } + } + } + + public void assertValidPayloadLength(int payloadLength) + { + // validate to buffer sizes + if (payloadLength > maxPayloadSize) + { + throw new MessageTooLargeException("Requested payload length [" + payloadLength + "] exceeds maximum size [" + maxPayloadSize + "]"); + } + } + + public void assertValidTextMessageSize(int requestedSize) + { + if (maxTextMessageSize > 0) + { + // validate it + if (requestedSize > maxTextMessageSize) + { + throw new MessageTooLargeException("Requested text message size [" + requestedSize + "] exceeds maximum size [" + maxTextMessageSize + "]"); + } + } + } + + public WebSocketPolicy clonePolicy() + { + WebSocketPolicy clone = new WebSocketPolicy(this.behavior); + clone.autoFragment = this.autoFragment; + clone.idleTimeout = this.idleTimeout; + clone.bufferSize = this.bufferSize; + clone.maxPayloadSize = this.maxPayloadSize; + clone.maxBinaryMessageSize = this.maxBinaryMessageSize; + clone.maxTextMessageSize = this.maxTextMessageSize; + return clone; + } + + public WebSocketBehavior getBehavior() + { + return behavior; + } + + public int getBufferSize() + { + return bufferSize; + } + + public int getIdleTimeout() + { + return idleTimeout; + } + + public int getMaxBinaryMessageSize() + { + return maxBinaryMessageSize; + } + + public int getMaxPayloadSize() + { + return maxPayloadSize; + } + + public int getMaxTextMessageSize() + { + return maxTextMessageSize; + } + + public boolean isAutoFragment() + { + return autoFragment; + } + + public void setAutoFragment(boolean autoFragment) + { + this.autoFragment = autoFragment; + } + + public void setBufferSize(int bufferSize) + { + this.bufferSize = bufferSize; + } + + public void setIdleTimeout(int idleTimeout) + { + this.idleTimeout = idleTimeout; + } + + public void setMaxBinaryMessageSize(int maxBinaryMessageSize) + { + this.maxBinaryMessageSize = maxBinaryMessageSize; + } + + public void setMaxPayloadSize(int maxPayloadSize) + { + if (maxPayloadSize < bufferSize) + { + throw new IllegalStateException("Cannot have payload size be smaller than buffer size"); + } + this.maxPayloadSize = maxPayloadSize; + } + + public void setMaxTextMessageSize(int maxTextMessageSize) + { + this.maxTextMessageSize = maxTextMessageSize; + } + +} 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 new file mode 100644 index 00000000000..8c322819311 --- /dev/null +++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketClose.java @@ -0,0 +1,46 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.api.annotations; + +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.WebSocketConnection; + +/** + * Annotation for tagging methods to receive connection close events. + *

+ * Acceptable method patterns.
+ * Note: methodName can be any name you want to use. + *

    + *
  1. public void methodName(int statusCode, String reason)
  2. + *
  3. public void methodName({@link WebSocketConnection} conn, int statusCode, String reason)
  4. + *
+ */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target(value = +{ ElementType.METHOD }) +public @interface OnWebSocketClose +{ + /* no config */ +} 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 new file mode 100644 index 00000000000..26e0df1d702 --- /dev/null +++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketConnect.java @@ -0,0 +1,45 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.api.annotations; + +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.WebSocketConnection; + +/** + * Annotation for tagging methods to receive connection open events. + *

+ * Only 1 acceptable method pattern for this annotation.
+ * Note: methodName can be any name you want to use. + *

    + *
  1. public void methodName({@link WebSocketConnection} conn)
  2. + *
+ */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target(value = +{ ElementType.METHOD }) +public @interface OnWebSocketConnect +{ + /* no config */ +} 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 new file mode 100644 index 00000000000..360b9f763ba --- /dev/null +++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketFrame.java @@ -0,0 +1,48 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.api.annotations; + +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.WebSocketConnection; + +/** + * (ADVANCED) Annotation for tagging methods to receive frame events. + *

+ * Note: any frame derived from {@link WebSocketFrame} is acceptable to use as the last parameter here. + *

+ * Acceptable method patterns.
+ * Note: methodName can be any name you want to use. + *

    + *
  1. public void methodName({@link WebSocketFrame} frame)
  2. + *
  3. public void methodName({@link WebSocketConnection} conn, {@link WebSocketFrame} frame)
  4. + *
+ */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target(value = +{ ElementType.METHOD }) +public @interface OnWebSocketFrame +{ + /* no config */ +} 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 new file mode 100644 index 00000000000..f46e0a52298 --- /dev/null +++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketMessage.java @@ -0,0 +1,61 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +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.WebSocketConnection; + +/** + * Annotation for tagging methods to receive Binary or Text Message events. + *

+ * Acceptable method patterns.
+ * Note: methodName can be any name you want to use. + *

+ * Text Message Versions + *

    + *
  1. public void methodName(String text)
  2. + *
  3. public void methodName({@link WebSocketConnection} conn, String text)
  4. + *
  5. public void methodName(Reader reader)
  6. + *
  7. public void methodName({@link WebSocketConnection} conn, Reader reader)
  8. + *
+ * Note: that the {@link Reader} in this case will always use UTF-8 encoding/charset (this is dictated by the RFC 6455 spec for Text Messages. If you need to + * use a non-UTF-8 encoding/charset, you are instructed to use the binary messaging techniques. + *

+ * Binary Message Versions + *

    + *
  1. public void methodName(byte buf[], int offset, int length)
  2. + *
  3. public void methodName({@link WebSocketConnection} conn, byte buf[], int offset, int length)
  4. + *
  5. public void methodName(InputStream stream)
  6. + *
  7. public void methodName({@link WebSocketConnection} conn, InputStream stream)
  8. + *
+ */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target(value = +{ ElementType.METHOD }) +public @interface OnWebSocketMessage +{ + /* no config */ +} 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 new file mode 100644 index 00000000000..21eb65948fd --- /dev/null +++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/WebSocket.java @@ -0,0 +1,43 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.api.annotations; + +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; + +/** + * Tags a POJO as being a WebSocket class. + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target(value = +{ ElementType.TYPE }) +public @interface WebSocket +{ + int maxBinarySize() default -2; + + int maxBufferSize() default -2; + + int maxIdleTime() default -2; + + int maxTextSize() 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 new file mode 100644 index 00000000000..aa8425a0fa5 --- /dev/null +++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/Extension.java @@ -0,0 +1,55 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.api.extensions; + +/** + * Interface for WebSocket Extensions. + *

+ * That work is performed by the two {@link FrameHandler} implementations for incoming and outgoing frame handling. + */ +public interface Extension +{ + /** + * Create an instance of a Incoming {@link FrameHandler} for working with frames destined for the End User WebSocket Object. + * + * @return the frame handler for incoming frames. + */ + public FrameHandler createIncomingFrameHandler(); + + /** + * Create an instance of a Outgoing {@link FrameHandler} for working with frames destined for the Network Bytes Layer. + * + * @return the frame handler for outgoing frames. + */ + public FrameHandler createOutgoingFrameHandler(); + + /** + * The active configuration for this extension. + * + * @return the configuration for this extension. never null. + */ + public ExtensionConfig getConfig(); + + /** + * The Sec-WebSocket-Extensions name for this extension. + *

+ * Also known as the extension-token per Section 9.1. Negotiating Extensions. + */ + public String getName(); +} \ 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 new file mode 100644 index 00000000000..b03e447a90b --- /dev/null +++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/ExtensionConfig.java @@ -0,0 +1,41 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.api.extensions; + +import java.util.Set; + +/** + * Represents an Extension Configuration, as seen during the connection Handshake process. + */ +public interface ExtensionConfig +{ + public String getName(); + + public int getParameter(String key, int defValue); + + public String getParameter(String key, String defValue); + + public String getParameterizedName(); + + public Set getParameterKeys(); + + public void setParameter(String key, int value); + + public void setParameter(String key, String value); +} \ No newline at end of file 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 new file mode 100644 index 00000000000..20c8e67f360 --- /dev/null +++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/ExtensionFactory.java @@ -0,0 +1,46 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.api.extensions; + +import java.util.HashMap; +import java.util.Map; +import java.util.ServiceLoader; + +public class ExtensionFactory +{ + private static ServiceLoader extensionLoader = ServiceLoader.load(Extension.class); + private static Map availableExtensions; + + public static Map getAvailableExtensions() + { + synchronized (extensionLoader) + { + if (availableExtensions == null) + { + availableExtensions = new HashMap<>(); + for (Extension ext : extensionLoader) + { + availableExtensions.put(ext.getName(),ext); + } + } + + return availableExtensions; + } + } +} diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/ExtensionRegistry.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/ExtensionRegistry.java new file mode 100644 index 00000000000..87ae3889aee --- /dev/null +++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/ExtensionRegistry.java @@ -0,0 +1,76 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.api.extensions; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.ServiceLoader; +import java.util.Set; + +public class ExtensionRegistry implements Iterable +{ + private ServiceLoader extensionLoader = ServiceLoader.load(Extension.class); + private Map availableExtensions; + + public ExtensionRegistry() + { + availableExtensions = new HashMap<>(); + for (Extension ext : extensionLoader) + { + availableExtensions.put(ext.getName(),ext); + } + } + + public Map getAvailableExtensions() + { + return availableExtensions; + } + + public Extension getExtension(String name) + { + return availableExtensions.get(name); + } + + public Set getExtensionNames() + { + return availableExtensions.keySet(); + } + + public boolean isAvailable(String name) + { + return availableExtensions.containsKey(name); + } + + @Override + public Iterator iterator() + { + return availableExtensions.values().iterator(); + } + + public void register(String name, Extension extension) + { + availableExtensions.put(name,extension); + } + + public void unregister(String name) + { + availableExtensions.remove(name); + } +} 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 new file mode 100644 index 00000000000..8a1ea438d1d --- /dev/null +++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/Frame.java @@ -0,0 +1,103 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.api.extensions; + +import java.nio.ByteBuffer; + +/** + * An immutable websocket frame. + */ +public interface Frame +{ + public static enum Type + { + TEXT((byte)0x01), + BINARY((byte)0x02), + CLOSE((byte)0x08), + PING((byte)0x09), + PONG((byte)0x0A); + + public static Type from(byte op) + { + for (Type type : values()) + { + if (type.opcode == op) + { + return type; + } + } + throw new IllegalArgumentException("OpCode " + op + " is not a valid Frame.Type"); + } + + private byte opcode; + + private Type(byte code) + { + this.opcode = code; + } + + public byte getOpCode() + { + return opcode; + } + + public boolean isControl() + { + return (opcode >= CLOSE.getOpCode()); + } + + public boolean isData() + { + return (opcode == TEXT.getOpCode()) | (opcode == BINARY.getOpCode()); + } + + @Override + public String toString() + { + return this.name(); + } + } + + public byte[] getMask(); + + public ByteBuffer getPayload(); + + public int getPayloadLength(); + + public Type getType(); + + public boolean isContinuation(); + + public boolean isFin(); + + /** + * Same as {@link #isFin()} + * + * @return true if final frame. + */ + public boolean isLast(); + + public boolean isMasked(); + + public boolean isRsv1(); + + public boolean isRsv2(); + + public boolean isRsv3(); +} diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/FrameHandler.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/FrameHandler.java new file mode 100644 index 00000000000..367cda6aaca --- /dev/null +++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/FrameHandler.java @@ -0,0 +1,27 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.api.extensions; + +/** + * Represents a Handler for a Frame (regardless of direction) + */ +public interface FrameHandler +{ + public void handleFrame(Frame frame); +} diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/FrameHandlerWrapper.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/FrameHandlerWrapper.java new file mode 100644 index 00000000000..5f078e24dec --- /dev/null +++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/FrameHandlerWrapper.java @@ -0,0 +1,29 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.api.extensions; + +/** + * Represents a Handler that processes and delegates results to a child {@link FrameHandler} + */ +public interface FrameHandlerWrapper extends FrameHandler +{ + public FrameHandler getNextHandler(); + + public void setNextHandler(FrameHandler handler); +} diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/io/WebSocketBlockingConnection.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/io/WebSocketBlockingConnection.java new file mode 100644 index 00000000000..a6b0012586a --- /dev/null +++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/io/WebSocketBlockingConnection.java @@ -0,0 +1,87 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.api.io; + +import java.io.IOException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +import org.eclipse.jetty.websocket.api.WebSocketConnection; +import org.eclipse.jetty.websocket.api.WebSocketException; + +/** + * For working with the {@link WebSocketConnection} in a blocking technique. + *

+ * This is an end-user accessible class. + */ +public class WebSocketBlockingConnection +{ + private static final String CONTEXT_BINARY = "BLOCKING_BINARY"; + private static final String CONTEXT_TEXT = "BLOCKING_TEXT"; + private final WebSocketConnection conn; + + public WebSocketBlockingConnection(WebSocketConnection conn) + { + this.conn = conn; + } + + /** + * Send a binary message. + *

+ * Basic usage, results in a blocking write. + */ + public void write(byte[] data, int offset, int length) throws IOException + { + try + { + Future blocker = conn.write(CONTEXT_BINARY,data,offset,length); + blocker.get(); // block till finished + } + catch (InterruptedException e) + { + throw new IOException("Blocking write failed",e); + } + catch (ExecutionException e) + { + throw new WebSocketException(e.getCause()); + } + } + + /** + * Send text message. + *

+ * Basic usage, results in a blocking write. + */ + public void write(String message) throws IOException + { + try + { + Future blocker = conn.write(CONTEXT_TEXT,message); + blocker.get(); // block till finished + } + catch (InterruptedException e) + { + throw new IOException("Blocking write failed",e); + } + catch (ExecutionException e) + { + throw new WebSocketException(e.getCause()); + } + } +} diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/io/WebSocketOutputStream.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/io/WebSocketOutputStream.java new file mode 100644 index 00000000000..ac2e9716d97 --- /dev/null +++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/io/WebSocketOutputStream.java @@ -0,0 +1,40 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.api.io; + +import java.io.IOException; +import java.io.OutputStream; + +import org.eclipse.jetty.websocket.api.WebSocketConnection; + +public class WebSocketOutputStream extends OutputStream +{ + private final WebSocketConnection conn; + + public WebSocketOutputStream(WebSocketConnection conn) + { + this.conn = conn; + } + + @Override + public void write(int b) throws IOException + { + // TODO Auto-generated method stub + } +} diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/io/WebSocketWriter.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/io/WebSocketWriter.java new file mode 100644 index 00000000000..ae4191c9631 --- /dev/null +++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/io/WebSocketWriter.java @@ -0,0 +1,54 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.api.io; + +import java.io.IOException; +import java.io.Writer; +import java.nio.charset.Charset; + +import org.eclipse.jetty.websocket.api.WebSocketConnection; + +public class WebSocketWriter extends Writer +{ + private final Charset charset = Charset.forName("UTF-8"); + private final WebSocketConnection conn; + + public WebSocketWriter(WebSocketConnection conn) + { + this.conn = conn; + } + + @Override + public void close() throws IOException + { + // TODO Auto-generated method stub + } + + @Override + public void flush() throws IOException + { + // TODO Auto-generated method stub + } + + @Override + public void write(char[] cbuf, int off, int len) throws IOException + { + // TODO Auto-generated method stub + } +}