Skip to content

Commit

Permalink
Replace not extendable WebSocketCloseCode enum by more flexible int c…
Browse files Browse the repository at this point in the history
…onstants and check client side close codes
  • Loading branch information
MrStahlfelge committed Feb 2, 2021
1 parent 1173384 commit 19a2c0c
Show file tree
Hide file tree
Showing 10 changed files with 107 additions and 111 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.github.czyzby.websocket.impl;

import com.github.czyzby.websocket.WebSockets;
import com.github.czyzby.websocket.data.WebSocketCloseCode;
import com.github.czyzby.websocket.data.WebSocketException;
import com.github.czyzby.websocket.data.WebSocketState;
Expand Down Expand Up @@ -47,7 +48,7 @@ protected void dispose() {
final WebSocket currentWebSocket = webSocket;
if (currentWebSocket != null && currentWebSocket.isOpen()) {
try {
currentWebSocket.disconnect(WebSocketCloseCode.AWAY.getCode());
currentWebSocket.disconnect(WebSockets.ABNORMAL_AUTOMATIC_CLOSE_CODE);
} catch (final Exception exception) {
postErrorEvent(exception);
}
Expand Down Expand Up @@ -88,11 +89,12 @@ public boolean isOpen() {
}

@Override
public void close(final WebSocketCloseCode code, final String reason) throws WebSocketException {
public void close(final int closeCode, final String reason) throws WebSocketException {
WebSocketCloseCode.checkIfAllowedInClient(closeCode);
final WebSocket currentWebSocket = webSocket;
if (currentWebSocket != null) {
try {
currentWebSocket.disconnect(code.getCode(), reason);
currentWebSocket.disconnect(closeCode, reason);
} catch (final Throwable exception) {
throw new WebSocketException("Unable to close the web socket.", exception);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public void onDisconnected(final WebSocket websocket, final WebSocketFrame serve
}

private void triggerOnDisconnectEvent(final int closeCode, final String closeReason) {
socket.postCloseEvent(WebSocketCloseCode.getByCodeOrElse(closeCode, WebSocketCloseCode.ABNORMAL), closeReason);
socket.postCloseEvent(closeCode, closeReason);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public boolean onOpen(final WebSocket webSocket) {
}

@Override
public boolean onClose(final WebSocket webSocket, final WebSocketCloseCode code, final String reason) {
public boolean onClose(final WebSocket webSocket, final int closecCode, final String reason) {
return NOT_HANDLED;
}

Expand Down
8 changes: 4 additions & 4 deletions core/src/main/java/com/github/czyzby/websocket/WebSocket.java
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,14 @@ public interface WebSocket {

/** Closes the connection. Uses no disconnection reason.
*
* @param code connection close code. Cannot be null.
* @param closeCode connection close code. Cannot be null.
* @throws WebSocketException if unable to close the connection. */
void close(WebSocketCloseCode code) throws WebSocketException;
void close(int closeCode) throws WebSocketException;

/** Closes the connection.
*
* @param code connection close code. Cannot be null.
* @param closeCode connection close code.
* @param reason closing reason. Optional.
* @throws WebSocketException if unable to close the connection. */
void close(WebSocketCloseCode code, String reason) throws WebSocketException;
void close(int closeCode, String reason) throws WebSocketException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public boolean onOpen(final WebSocket webSocket) {
}

@Override
public boolean onClose(final WebSocket webSocket, final WebSocketCloseCode code, final String reason) {
public boolean onClose(final WebSocket webSocket, final int closeCode, final String reason) {
return NOT_HANDLED;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ public interface WebSocketListener {
/** Triggered when the client is disconnected.
*
* @param webSocket affected socket.
* @param code code of closing.
* @param closeCode code of closing.
* @param reason optional reason of the closing.
* @return <code>true</code> if event fully handled and other listeners should not be notified.
* @see #FULLY_HANDLED
* @see #NOT_HANDLED */
boolean onClose(WebSocket webSocket, WebSocketCloseCode code, String reason);
boolean onClose(WebSocket webSocket, int closeCode, String reason);

/** @param webSocket affected socket.
* @param packet received from the server.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ public class WebSockets {
* strings or byte arrays when using {@link WebSocket#send(Object)} method. By default, serializes objects to JSON
* format using {@link JsonSerializer}. */
public static Serializer DEFAULT_SERIALIZER = new JsonSerializer();
/**
* Close code used to indicate an abnormal, automated close of the socket
*/
public static int ABNORMAL_AUTOMATIC_CLOSE_CODE = 3000;

private WebSockets() {
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* Copyright (C) 2015 Neo Visionaries Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License")), you may not use this file except in
* Licensed under the Apache License, Version 2.0 (the "License") ; you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
Expand All @@ -10,111 +10,99 @@
* See the License for the specific language governing permissions and limitations under the License. */
package com.github.czyzby.websocket.data;

/** Official close codes. Originally from the Neo Visionaries web socket library, modified to be an enum.
/**
* Official close codes. Originally from the Neo Visionaries web socket library, modified to be an enum.
*
* @see <a href="http://tools.ietf.org/html/rfc6455#section-7.4.1" >RFC 6455, 7.4.1. Defined Status Codes</a> */
public enum WebSocketCloseCode {
/** 1000), <i> 1000 indicates a normal closure, meaning that the purpose for which the connection was established
* has been fulfilled. </i> */
NORMAL(1000),

/** 1001), <i> 1001 indicates that an endpoint is "going away", such as a server going down or a browser having
* navigated away from a page. </i> */
AWAY(1001),

/** 1002), <i> 1002 indicates that an endpoint is terminating the connection due to a protocol error. </i> */
UNCONFORMED(1002),

/** 1003; <i> 1003 indicates that an endpoint is terminating the connection because it has received a type of data
* @see <a href="http://tools.ietf.org/html/rfc6455#section-7.4.1" >RFC 6455, 7.4.1. Defined Status Codes</a>
*/
public class WebSocketCloseCode {
/**
* 1000 ; <i> 1000 indicates a normal closure, meaning that the purpose for which the connection was established
* has been fulfilled. </i>
*/
public static final int NORMAL = 1000;

/**
* 1001 ; <i> 1001 indicates that an endpoint is "going away", such as a server going down or a browser having
* navigated away from a page. </i>
*/
public static final int AWAY = 1001;

/**
* 1002 ; <i> 1002 indicates that an endpoint is terminating the connection due to a protocol error. </i>
*/
public static final int UNCONFORMED = 1002;

/**
* 1003; <i> 1003 indicates that an endpoint is terminating the connection because it has received a type of data
* it cannot accept (e&#46;g&#46;, an endpoint that understands only text data MAY send this if it receives a binary
* message). </i> */
UNACCEPTABLE(1003),
* message). </i>
*/
public static final int UNACCEPTABLE = 1003;

/** 1005; <i> 1005 is a reserved value and MUST NOT be set as a status code in a Close control frame by an
/**
* 1005; <i> 1005 is a reserved value and MUST NOT be set as a status code in a Close control frame by an
* endpoint&#46; It is designated for use in applications expecting a status code to indicate that no status code
* was actually present. </i> */
NONE(1005),
* was actually present. </i>
*/
public static final int NONE = 1005;

/** 1006; <i> 1006 is a reserved value and MUST NOT be set as a status code in a Close control frame by an
/**
* 1006; <i> 1006 is a reserved value and MUST NOT be set as a status code in a Close control frame by an
* endpoint&#46; It is designated for use in applications expecting a status code to indicate that the connection
* was closed abnormally, e&#46;g&#46;, without sending or receiving a Close control frame. </i> */
ABNORMAL(1006),
* was closed abnormally, e&#46;g&#46;, without sending or receiving a Close control frame. </i>
*/
public static final int ABNORMAL = 1006;

/** 1007; <i> 1007 indicates that an endpoint is terminating the connection because it has received data within a
/**
* 1007; <i> 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&#46;g&#46;, non-UTF-8 [
* <a href="http://tools.ietf.org/html/rfc3629">RFC3629</a>] data within a text message). </i> */
INCONSISTENT(1007),
* <a href="http://tools.ietf.org/html/rfc3629">RFC3629</a>] data within a text message). </i>
*/
public static final int INCONSISTENT = 1007;

/** 1008; <i> 1008 indicates that an endpoint is terminating the connection because it has received a message that
/**
* 1008; <i> 1008 indicates that an endpoint is terminating the connection because it has received a message that
* violates its policy&#46; This is a generic status code that can be returned when there is no other more suitable
* status code (e&#46;g&#46;, 1003 or 1009) or if there is a need to hide specific details about the policy. </i> */
VIOLATED(1008),

/** 1009), <i> 1009 indicates that an endpoint is terminating the connection because it has received a message that
* is too big for it to process. </i> */
OVERSIZE(1009),

/** 1010; <i> 1010 indicates that an endpoint (client) is terminating the connection because it has expected the
* status code (e&#46;g&#46;, 1003 or 1009) or if there is a need to hide specific details about the policy. </i>
*/
public static final int VIOLATED = 1008;

/**
* 1009 ; <i> 1009 indicates that an endpoint is terminating the connection because it has received a message that
* is too big for it to process. </i>
*/
public static final int OVERSIZE = 1009;

/**
* 1010; <i> 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&#46; The list of extensions that are needed SHOULD appear in the /reason/ part of the Close
* frame&#46; Note that this status code is not used by the server, because it can fail the WebSocket handshake
* instead. </i> */
UNEXTENDED(1010),

/** 1011), <i> 1011 indicates that a server is terminating the connection because it encountered an unexpected
* condition that prevented it from fulfilling the request. </i> */
UNEXPECTED(1011),

/** 1015; <i> 1015 is a reserved value and MUST NOT be set as a status code in a Close control frame by an
* instead. </i>
*/
public static final int UNEXTENDED = 1010;

/**
* 1011 ; <i> 1011 indicates that a server is terminating the connection because it encountered an unexpected
* condition that prevented it from fulfilling the request. </i>
*/
public static final int UNEXPECTED = 1011;

/**
* 1015; <i> 1015 is a reserved value and MUST NOT be set as a status code in a Close control frame by an
* endpoint&#46; 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&#46;g&#46;, the server certificate can't be
* verified). </i> */
INSECURE(1015);

private final int code;

private WebSocketCloseCode(final int code) {
this.code = code;
}

/** @return actual value of close code. */
public int getCode() {
return code;
}

/** @param code web socket close code. Usually in 1000-1011 range.
* @return close code enum constant connected with the passed code.
* @throws WebSocketException if invalid code is given. */
public static WebSocketCloseCode getByCode(final int code) throws WebSocketException {
// Ugly, but works without extra meta-data, like a map.
if (code == INSECURE.code) {
return INSECURE;
}
if (code < NORMAL.code || code > UNEXPECTED.code || code == 1004) {
throw new WebSocketException("Unexpected close code: " + code);
}
if (code < 1004) {
return values()[code - 1000];
}
// There's no 1004:
return values()[code - 1001];
}

/** @param code possibly valid close code.
* @param alternative returned if code is invalid.
* @return close code connected with the object or the alternative if code is invalid. */
public static WebSocketCloseCode getByCodeOrElse(final int code, final WebSocketCloseCode alternative) {
// Ugly, but works without extra meta-data, like a map.
if (code == INSECURE.code) {
return INSECURE;
}
if (code < NORMAL.code || code > UNEXPECTED.code || code == 1004) {
return alternative;
}
if (code < 1004) {
return values()[code - 1000];
* verified). </i>
*/
public static final int INSECURE = 1015;

/**
* @return true if closeCode is a code permitted to be sent by client-side
*/
public static void checkIfAllowedInClient(int closeCode) {
if (closeCode != NORMAL && (closeCode < 3000 || closeCode > 3999)) {
throw new WebSocketException("Close code not allowed in client, use NORMAL or 3000-3999");
}
// There's no 1004:
return values()[code - 1001];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ protected void postOpenEvent() {
*
* @param closeCode closing code.
* @param reason optional closing reason. */
protected void postCloseEvent(final WebSocketCloseCode closeCode, final String reason) {
protected void postCloseEvent(final int closeCode, final String reason) {
for (final WebSocketListener listener : listeners) {
if (listener.onClose(this, closeCode, reason)) {
break;
Expand Down Expand Up @@ -239,7 +239,7 @@ public void close(final String reason) throws WebSocketException {
}

@Override
public void close(final WebSocketCloseCode code) throws WebSocketException {
close(code, null);
public void close(final int closeCode) throws WebSocketException {
close(closeCode, null);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.github.czyzby.websocket.impl;

import com.github.czyzby.websocket.WebSockets;
import com.github.czyzby.websocket.data.WebSocketCloseCode;
import com.github.czyzby.websocket.data.WebSocketException;
import com.github.czyzby.websocket.data.WebSocketState;
Expand All @@ -26,7 +27,7 @@ public static native boolean areWebSocketsSupported() /*-{
@Override
public void connect() throws WebSocketException {
if (isOpen() || isConnecting()) {
close(WebSocketCloseCode.AWAY);
close(WebSockets.ABNORMAL_AUTOMATIC_CLOSE_CODE);
}
try {
open(super.getUrl());
Expand Down Expand Up @@ -77,7 +78,7 @@ protected void onOpen() {
* @param closeCode see {@link WebSocketCloseCode}.
* @param reason optional closing reason. */
protected void onClose(final int closeCode, final String reason) {
postCloseEvent(WebSocketCloseCode.getByCodeOrElse(closeCode, WebSocketCloseCode.ABNORMAL), reason);
postCloseEvent(closeCode, reason);
}

/** Invoked by native listener.
Expand Down Expand Up @@ -143,9 +144,10 @@ protected native int getStateId()/*-{
}-*/;

@Override
public void close(final WebSocketCloseCode code, final String reason) throws WebSocketException {
public void close(final int closeCode, final String reason) throws WebSocketException {
WebSocketCloseCode.checkIfAllowedInClient(closeCode);
try {
close(code.getCode(), reason);
nativeClose(closeCode, reason);
} catch (final Throwable exception) {
throw new WebSocketException("Unable to close the web socket.", exception);
}
Expand All @@ -155,7 +157,7 @@ public void close(final WebSocketCloseCode code, final String reason) throws Web
*
* @param code see {@link WebSocketCloseCode}.
* @param reason optional closing reason. */
protected native void close(int code, String reason)/*-{
protected native void nativeClose(int code, String reason)/*-{
if(this.ws){
this.ws.close(code,reason);
}
Expand Down

0 comments on commit 19a2c0c

Please sign in to comment.