diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 30ebd2ee..00000000 --- a/.travis.yml +++ /dev/null @@ -1,4 +0,0 @@ -{ - "language": "java", - "script": "ant all" -} diff --git a/build.xml b/build.xml deleted file mode 100644 index 5658bfff..00000000 --- a/build.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pom.xml b/pom.xml index 4c03d292..3ee1bd23 100644 --- a/pom.xml +++ b/pom.xml @@ -1,124 +1,251 @@ - - 4.0.0 - org.java-websocket - Java-WebSocket - jar - 1.3.10-SNAPSHOT - Java-WebSocket - A barebones WebSocket client and server implementation written 100% in Java - https://github.com/TooTallNate/Java-WebSocket - - UTF-8 - - - - MIT License - https://github.com/TooTallNate/Java-WebSocket/blob/master/LICENSE - - - + + + 4.0.0 + org.java-websocket + Java-WebSocket + jar + 1.4.0-SNAPSHOT + Java-WebSocket + A barebones WebSocket client and server implementation written 100% in Java https://github.com/TooTallNate/Java-WebSocket - - - - ossrh - https://oss.sonatype.org/content/repositories/snapshots - - - ossrh - https://oss.sonatype.org/service/local/staging/deploy/maven2/ - - - - src/main/java - - - org.sonatype.plugins - nexus-staging-maven-plugin - 1.6.7 - true - - ossrh - https://oss.sonatype.org/ - true - - - - org.apache.maven.plugins - maven-source-plugin - 2.2.1 - - - attach-sources - - jar-no-fork - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 2.9.1 - - - attach-javadocs - - jar - - - - - - org.apache.maven.plugins - maven-gpg-plugin - 1.5 - - - sign-artifacts - verify - - sign - - - - - - org.apache.maven.plugins - maven-compiler-plugin - - 1.6 - 1.6 - - - - - - - junit - junit - 4.11 - test - - - org.json - json - 20171018 - test - - - - - Nathan Rajlich - https://github.com/TooTallNate - nathan@tootallnate.net - - - Marcel Prestel - https://github.com/marci4 - admin@marci4.de - - + + UTF-8 + 1.7.25 + + + + MIT License + https://github.com/TooTallNate/Java-WebSocket/blob/master/LICENSE + + + + https://github.com/TooTallNate/Java-WebSocket + + + https://github.com/TooTallNate/Java-WebSocket/issues + GitHub Issues + + + src/main/java + src/test/java + + + org.apache.maven.plugins + maven-compiler-plugin + 3.7.0 + + 1.6 + 1.6 + + + + + + + ossrh + + + performRelease + true + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.6 + + + sign-artifacts + verify + + sign + + + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.8 + true + + ossrh + true + + + + org.apache.maven.plugins + maven-source-plugin + 2.4 + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.10.2 + + + attach-javadocs + + jar + + + + + + + + + full + + false + + + + org.slf4j + slf4j-simple + ${slf4j.version} + + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.1.0 + + + package + + shade + + + true + with-dependencies + + + simplelogger.properties + src\main\example\simplelogger.properties + + + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.0.0 + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.0.2 + + + + test-jar + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.10.3 + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.6 + + + sign-artifacts + verify + + sign + + + + + + + + + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + + ossrh + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + + org.slf4j + slf4j-api + ${slf4j.version} + + + org.slf4j + slf4j-simple + ${slf4j.version} + test + + + junit + junit + 4.11 + test + + + org.json + json + 20180130 + test + + + + + Nathan Rajlich + https://github.com/TooTallNate + nathan@tootallnate.net + + + Marcel Prestel + https://github.com/marci4 + admin@marci4.de + + diff --git a/src/main/example/ChatClient.java b/src/main/example/ChatClient.java index f58c34f1..07cee786 100644 --- a/src/main/example/ChatClient.java +++ b/src/main/example/ChatClient.java @@ -170,7 +170,6 @@ public void onError( Exception ex ) { } public static void main( String[] args ) { - WebSocketImpl.DEBUG = true; String location; if( args.length != 0 ) { location = args[ 0 ]; diff --git a/src/main/example/ChatServer.java b/src/main/example/ChatServer.java index 1dcce91b..3ebc50bc 100644 --- a/src/main/example/ChatServer.java +++ b/src/main/example/ChatServer.java @@ -75,7 +75,6 @@ public void onMessage( WebSocket conn, ByteBuffer message ) { public static void main( String[] args ) throws InterruptedException , IOException { - WebSocketImpl.DEBUG = true; int port = 8887; // 843 flash policy port try { port = Integer.parseInt( args[ 0 ] ); @@ -106,6 +105,8 @@ public void onError( WebSocket conn, Exception ex ) { @Override public void onStart() { System.out.println("Server started!"); + setConnectionLostTimeout(0); + setConnectionLostTimeout(100); } } diff --git a/src/main/example/ChatServerAttachmentExample.java b/src/main/example/ChatServerAttachmentExample.java index 378cc2cf..39554bd9 100644 --- a/src/main/example/ChatServerAttachmentExample.java +++ b/src/main/example/ChatServerAttachmentExample.java @@ -77,7 +77,6 @@ public void onMessage( WebSocket conn, ByteBuffer message ) { } public static void main( String[] args ) throws InterruptedException , IOException { - WebSocketImpl.DEBUG = true; int port = 8887; // 843 flash policy port try { port = Integer.parseInt( args[ 0 ] ); diff --git a/src/main/example/CustomHeaderClientExample.java b/src/main/example/CustomHeaderClientExample.java index 073cb14f..955e02af 100644 --- a/src/main/example/CustomHeaderClientExample.java +++ b/src/main/example/CustomHeaderClientExample.java @@ -38,7 +38,6 @@ public class CustomHeaderClientExample { public static void main( String[] args ) throws URISyntaxException, InterruptedException { - WebSocketImpl.DEBUG = true; Map httpHeaders = new HashMap(); httpHeaders.put( "Cookie", "test" ); ExampleClient c = new ExampleClient( new URI( "ws://localhost:8887" ), httpHeaders); diff --git a/src/main/example/FragmentedFramesExample.java b/src/main/example/FragmentedFramesExample.java index f6b677e0..eec7a0c1 100644 --- a/src/main/example/FragmentedFramesExample.java +++ b/src/main/example/FragmentedFramesExample.java @@ -32,8 +32,7 @@ import org.java_websocket.WebSocket; import org.java_websocket.client.WebSocketClient; -import org.java_websocket.drafts.Draft_6455; -import org.java_websocket.framing.Framedata.Opcode; +import org.java_websocket.enums.Opcode; /** * This example shows how to send fragmented frames.
diff --git a/src/main/example/ReconnectClientExample.java b/src/main/example/ReconnectClientExample.java index c7181e83..0fcf08fe 100644 --- a/src/main/example/ReconnectClientExample.java +++ b/src/main/example/ReconnectClientExample.java @@ -33,7 +33,6 @@ */ public class ReconnectClientExample { public static void main( String[] args ) throws URISyntaxException, InterruptedException { - WebSocketImpl.DEBUG = true; ExampleClient c = new ExampleClient( new URI( "ws://localhost:8887" ) ); //Connect to a server normally c.connectBlocking(); diff --git a/src/main/example/SSLClientExample.java b/src/main/example/SSLClientExample.java index 693c71bb..4f6e1d87 100644 --- a/src/main/example/SSLClientExample.java +++ b/src/main/example/SSLClientExample.java @@ -80,8 +80,6 @@ public class SSLClientExample { *keytool -genkey -validity 3650 -keystore "keystore.jks" -storepass "storepassword" -keypass "keypassword" -alias "default" -dname "CN=127.0.0.1, OU=MyOrgUnit, O=MyOrg, L=MyCity, S=MyRegion, C=MyCountry" */ public static void main( String[] args ) throws Exception { - WebSocketImpl.DEBUG = true; - WebSocketChatClient chatclient = new WebSocketChatClient( new URI( "wss://localhost:8887" ) ); // load up the key store diff --git a/src/main/example/SSLServerCustomWebsocketFactoryExample.java b/src/main/example/SSLServerCustomWebsocketFactoryExample.java index e9d82569..86e0a4eb 100644 --- a/src/main/example/SSLServerCustomWebsocketFactoryExample.java +++ b/src/main/example/SSLServerCustomWebsocketFactoryExample.java @@ -48,8 +48,6 @@ public class SSLServerCustomWebsocketFactoryExample { *keytool -genkey -validity 3650 -keystore "keystore.jks" -storepass "storepassword" -keypass "keypassword" -alias "default" -dname "CN=127.0.0.1, OU=MyOrgUnit, O=MyOrg, L=MyCity, S=MyRegion, C=MyCountry" */ public static void main(String[] args) throws Exception { - WebSocketImpl.DEBUG = true; - ChatServer chatserver = new ChatServer(8887); // Firefox does allow multible ssl connection only via port 443 //tested on FF16 // load up the key store diff --git a/src/main/example/SSLServerExample.java b/src/main/example/SSLServerExample.java index 1e58d4ae..a19cfcb7 100644 --- a/src/main/example/SSLServerExample.java +++ b/src/main/example/SSLServerExample.java @@ -44,8 +44,6 @@ public class SSLServerExample { *keytool -genkey -validity 3650 -keystore "keystore.jks" -storepass "storepassword" -keypass "keypassword" -alias "default" -dname "CN=127.0.0.1, OU=MyOrgUnit, O=MyOrg, L=MyCity, S=MyRegion, C=MyCountry" */ public static void main( String[] args ) throws Exception { - WebSocketImpl.DEBUG = true; - ChatServer chatserver = new ChatServer( 8887 ); // Firefox does allow multible ssl connection only via port 443 //tested on FF16 // load up the key store diff --git a/src/main/example/SSLServerLetsEncryptExample.java b/src/main/example/SSLServerLetsEncryptExample.java index 731bb389..34b80d0c 100644 --- a/src/main/example/SSLServerLetsEncryptExample.java +++ b/src/main/example/SSLServerLetsEncryptExample.java @@ -53,8 +53,6 @@ public class SSLServerLetsEncryptExample { public static void main( String[] args ) throws Exception { - WebSocketImpl.DEBUG = true; - ChatServer chatserver = new ChatServer( 8887 ); SSLContext context = getContext(); diff --git a/src/main/example/SecWebSocketProtocolClientExample.java b/src/main/example/SecWebSocketProtocolClientExample.java index e5bb1b24..1a754332 100644 --- a/src/main/example/SecWebSocketProtocolClientExample.java +++ b/src/main/example/SecWebSocketProtocolClientExample.java @@ -40,7 +40,6 @@ public class SecWebSocketProtocolClientExample { public static void main( String[] args ) throws URISyntaxException { - WebSocketImpl.DEBUG = true; // This draft only allows you to use the specific Sec-WebSocket-Protocol without a fallback. Draft_6455 draft_ocppOnly = new Draft_6455(Collections.emptyList(), Collections.singletonList(new Protocol("ocpp2.0"))); diff --git a/src/main/example/ServerAdditionalHeaderExample.java b/src/main/example/ServerAdditionalHeaderExample.java index 4b80e9e2..2631dbeb 100644 --- a/src/main/example/ServerAdditionalHeaderExample.java +++ b/src/main/example/ServerAdditionalHeaderExample.java @@ -58,7 +58,6 @@ public ServerHandshakeBuilder onWebsocketHandshakeReceivedAsServer( WebSocket co public static void main( String[] args ) throws InterruptedException , IOException { - WebSocketImpl.DEBUG = true; int port = 8887; // 843 flash policy port try { port = Integer.parseInt( args[ 0 ] ); diff --git a/src/main/example/ServerRejectHandshakeExample.java b/src/main/example/ServerRejectHandshakeExample.java index f2a3430f..2bbeee0c 100644 --- a/src/main/example/ServerRejectHandshakeExample.java +++ b/src/main/example/ServerRejectHandshakeExample.java @@ -73,7 +73,6 @@ public ServerHandshakeBuilder onWebsocketHandshakeReceivedAsServer( WebSocket co public static void main( String[] args ) throws InterruptedException , IOException { - WebSocketImpl.DEBUG = true; int port = 8887; // 843 flash policy port try { port = Integer.parseInt( args[ 0 ] ); diff --git a/src/main/example/simplelogger.properties b/src/main/example/simplelogger.properties new file mode 100644 index 00000000..f2f4dcac --- /dev/null +++ b/src/main/example/simplelogger.properties @@ -0,0 +1,7 @@ +org.slf4j.simpleLogger.logFile=System.out +org.slf4j.simpleLogger.defaultLogLevel=error +org.slf4j.simpleLogger.showDateTime=true +org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss.SSS +org.slf4j.simpleLogger.showThreadName=false +org.slf4j.simpleLogger.showLogName=false +org.slf4j.simpleLogger.levelInBrackets=true \ No newline at end of file diff --git a/src/main/java/org/java_websocket/AbstractWebSocket.java b/src/main/java/org/java_websocket/AbstractWebSocket.java index fce27a11..a9fd67ad 100644 --- a/src/main/java/org/java_websocket/AbstractWebSocket.java +++ b/src/main/java/org/java_websocket/AbstractWebSocket.java @@ -26,6 +26,8 @@ package org.java_websocket; import org.java_websocket.framing.CloseFrame; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.Collection; @@ -38,6 +40,13 @@ */ public abstract class AbstractWebSocket extends WebSocketAdapter { + /** + * Logger instance + * + * @since 1.4.0 + */ + private static final Logger log = LoggerFactory.getLogger(AbstractWebSocket.class); + /** * Attribute which allows you to deactivate the Nagle's algorithm * @since 1.3.3 @@ -93,14 +102,12 @@ public int getConnectionLostTimeout() { public void setConnectionLostTimeout( int connectionLostTimeout ) { this.connectionLostTimeout = connectionLostTimeout; if (this.connectionLostTimeout <= 0) { - if( WebSocketImpl.DEBUG ) - System.out.println( "Connection lost timer stopped" ); + log.trace( "Connection lost timer stopped" ); cancelConnectionLostTimer(); return; } if (this.websocketRunning) { - if( WebSocketImpl.DEBUG ) - System.out.println( "Connection lost timer restarted" ); + log.trace( "Connection lost timer restarted" ); //Reset all the pings try { ArrayList connections = new ArrayList( getConnections() ); @@ -112,8 +119,7 @@ public void setConnectionLostTimeout( int connectionLostTimeout ) { } } } catch (Exception e) { - if (WebSocketImpl.DEBUG) - System.out.println("Exception during connection lost restart: " + e.getMessage()); + log.error("Exception during connection lost restart", e); } restartConnectionLostTimer(); } @@ -126,8 +132,7 @@ public void setConnectionLostTimeout( int connectionLostTimeout ) { protected void stopConnectionLostTimer() { if (connectionLostTimer != null ||connectionLostTimerTask != null) { this.websocketRunning = false; - if( WebSocketImpl.DEBUG ) - System.out.println( "Connection lost timer stopped" ); + log.trace( "Connection lost timer stopped" ); cancelConnectionLostTimer(); } } @@ -137,12 +142,10 @@ protected void stopConnectionLostTimer() { */ protected void startConnectionLostTimer() { if (this.connectionLostTimeout <= 0) { - if (WebSocketImpl.DEBUG) - System.out.println("Connection lost timer deactivated"); + log.trace("Connection lost timer deactivated"); return; } - if (WebSocketImpl.DEBUG) - System.out.println("Connection lost timer started"); + log.trace("Connection lost timer started"); this.websocketRunning = true; restartConnectionLostTimer(); } @@ -171,27 +174,25 @@ public void run() { if( conn instanceof WebSocketImpl ) { webSocketImpl = ( WebSocketImpl ) conn; if( webSocketImpl.getLastPong() < current ) { - if( WebSocketImpl.DEBUG ) - System.out.println( "Closing connection due to no pong received: " + conn.toString() ); + log.trace("Closing connection due to no pong received: {}", conn); webSocketImpl.closeConnection( CloseFrame.ABNORMAL_CLOSE, "The connection was closed because the other endpoint did not respond with a pong in time. For more information check: https://github.com/TooTallNate/Java-WebSocket/wiki/Lost-connection-detection" ); } else { if( webSocketImpl.isOpen() ) { webSocketImpl.sendPing(); } else { - if( WebSocketImpl.DEBUG ) - System.out.println( "Trying to ping a non open connection: " + conn.toString() ); + log.trace("Trying to ping a non open connection: {}", conn); } } } } } catch ( Exception e ) { - if (WebSocketImpl.DEBUG) - System.out.println("Exception during connection lost ping: " + e.getMessage()); + //Ignore this exception } connections.clear(); } }; - connectionLostTimer.scheduleAtFixedRate( connectionLostTimerTask,connectionLostTimeout * 1000, connectionLostTimeout * 1000 ); + connectionLostTimer.scheduleAtFixedRate( connectionLostTimerTask,1000L*connectionLostTimeout , 1000L*connectionLostTimeout ); + } /** diff --git a/src/main/java/org/java_websocket/AbstractWrappedByteChannel.java b/src/main/java/org/java_websocket/AbstractWrappedByteChannel.java index 2ec9ba2d..01fb14a8 100644 --- a/src/main/java/org/java_websocket/AbstractWrappedByteChannel.java +++ b/src/main/java/org/java_websocket/AbstractWrappedByteChannel.java @@ -30,6 +30,7 @@ import java.nio.channels.ByteChannel; import java.nio.channels.SocketChannel; +@Deprecated public class AbstractWrappedByteChannel implements WrappedByteChannel { private final ByteChannel channel; diff --git a/src/main/java/org/java_websocket/SSLSocketChannel.java b/src/main/java/org/java_websocket/SSLSocketChannel.java index 3d2ef38b..6fb21dd6 100644 --- a/src/main/java/org/java_websocket/SSLSocketChannel.java +++ b/src/main/java/org/java_websocket/SSLSocketChannel.java @@ -26,6 +26,8 @@ package org.java_websocket; import org.java_websocket.util.ByteBufferUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLEngineResult; @@ -62,6 +64,13 @@ */ public class SSLSocketChannel implements WrappedByteChannel, ByteChannel { + /** + * Logger instance + * + * @since 1.4.0 + */ + private static final Logger log = LoggerFactory.getLogger(SSLSocketChannel.class); + /** * The underlaying socket channel */ @@ -129,7 +138,7 @@ public SSLSocketChannel( SocketChannel inputSocketChannel, SSLEngine inputEngine try { socketChannel.close(); } catch ( IOException e ) { - e.printStackTrace(); + log.error("Exception during the closing of the channel", e); } } } @@ -157,7 +166,7 @@ public synchronized int read( ByteBuffer dst ) throws IOException { try { result = engine.unwrap( peerNetData, peerAppData ); } catch ( SSLException e ) { - e.printStackTrace(); + log.error("SSLExcpetion during unwrap", e); throw e; } switch(result.getStatus()) { @@ -457,7 +466,7 @@ private void handleEndOfStream() throws IOException { try { engine.closeInbound(); } catch ( Exception e ) { - System.err.println( "This engine was forced to close inbound, without having received the proper SSL/TLS close notification message from the peer, due to end of stream." ); + log.error( "This engine was forced to close inbound, without having received the proper SSL/TLS close notification message from the peer, due to end of stream." ); } closeConnection(); } diff --git a/src/main/java/org/java_websocket/SSLSocketChannel2.java b/src/main/java/org/java_websocket/SSLSocketChannel2.java index 3191edd9..8cabf604 100644 --- a/src/main/java/org/java_websocket/SSLSocketChannel2.java +++ b/src/main/java/org/java_websocket/SSLSocketChannel2.java @@ -24,6 +24,9 @@ */ package org.java_websocket; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLEngineResult; import javax.net.ssl.SSLEngineResult.HandshakeStatus; @@ -51,7 +54,14 @@ */ public class SSLSocketChannel2 implements ByteChannel, WrappedByteChannel { - /** + /** + * Logger instance + * + * @since 1.4.0 + */ + private static final Logger log = LoggerFactory.getLogger(SSLSocketChannel2.class); + + /** * This object is used to feed the {@link SSLEngine}'s wrap and unwrap methods during the handshake phase. **/ protected static ByteBuffer emptybuffer = ByteBuffer.allocate( 0 ); @@ -222,8 +232,14 @@ protected void createBuffers( SSLSession session ) { if( inCrypt.capacity() != netBufferMax ) inCrypt = ByteBuffer.allocate( netBufferMax ); } + if (inData.remaining() != 0 && log.isTraceEnabled()) { + log.trace(new String( inData.array(), inData.position(), inData.remaining())); + } inData.rewind(); inData.flip(); + if (inCrypt.remaining() != 0 && log.isTraceEnabled()) { + log.trace(new String( inCrypt.array(), inCrypt.position(), inCrypt.remaining())); + } inCrypt.rewind(); inCrypt.flip(); outCrypt.rewind(); diff --git a/src/main/java/org/java_websocket/SocketChannelIOHelper.java b/src/main/java/org/java_websocket/SocketChannelIOHelper.java index 7e33b3f8..3ccd4a93 100644 --- a/src/main/java/org/java_websocket/SocketChannelIOHelper.java +++ b/src/main/java/org/java_websocket/SocketChannelIOHelper.java @@ -29,7 +29,7 @@ import java.nio.ByteBuffer; import java.nio.channels.ByteChannel; -import org.java_websocket.WebSocket.Role; +import org.java_websocket.enums.Role; public class SocketChannelIOHelper { @@ -72,6 +72,9 @@ public static boolean readMore( final ByteBuffer buf, WebSocketImpl ws, WrappedB * @return returns Whether there is more data to write */ public static boolean batch( WebSocketImpl ws, ByteChannel sockchannel ) throws IOException { + if (ws == null) { + return false; + } ByteBuffer buffer = ws.outQueue.peek(); WrappedByteChannel c = null; @@ -94,10 +97,8 @@ public static boolean batch( WebSocketImpl ws, ByteChannel sockchannel ) throws } while ( buffer != null ); } - if( ws != null && ws.outQueue.isEmpty() && ws.isFlushAndClose() && ws.getDraft() != null && ws.getDraft().getRole() != null && ws.getDraft().getRole() == Role.SERVER ) {// - synchronized ( ws ) { - ws.closeConnection(); - } + if( ws.outQueue.isEmpty() && ws.isFlushAndClose() && ws.getDraft() != null && ws.getDraft().getRole() != null && ws.getDraft().getRole() == Role.SERVER ) {// + ws.closeConnection(); } return c == null || !((WrappedByteChannel) sockchannel).isNeedWrite(); } diff --git a/src/main/java/org/java_websocket/WebSocket.java b/src/main/java/org/java_websocket/WebSocket.java index a0bc3c57..1eae2c9a 100644 --- a/src/main/java/org/java_websocket/WebSocket.java +++ b/src/main/java/org/java_websocket/WebSocket.java @@ -31,25 +31,11 @@ import java.util.Collection; import org.java_websocket.drafts.Draft; +import org.java_websocket.enums.Opcode; +import org.java_websocket.enums.ReadyState; import org.java_websocket.framing.Framedata; -import org.java_websocket.framing.Framedata.Opcode; public interface WebSocket { - /** - * Enum which represents the states a websocket may be in - */ - enum Role { - CLIENT, SERVER - } - - /** - * Enum which represents the state a websocket may be in - */ - enum READYSTATE { - NOT_YET_CONNECTED, - @Deprecated - CONNECTING, OPEN, CLOSING, CLOSED - } /** * The default port of WebSockets, as defined in the spec. If the nullary @@ -97,7 +83,7 @@ enum READYSTATE { * @param text the text data to send * @throws NotYetConnectedException websocket is not yet connected */ - void send( String text ) throws NotYetConnectedException; + void send( String text ); /** * Send Binary data (plain bytes) to the other end. @@ -106,7 +92,7 @@ enum READYSTATE { * @throws IllegalArgumentException the data is null * @throws NotYetConnectedException websocket is not yet connected */ - void send( ByteBuffer bytes ) throws IllegalArgumentException , NotYetConnectedException; + void send( ByteBuffer bytes ); /** * Send Binary data (plain bytes) to the other end. @@ -115,7 +101,7 @@ enum READYSTATE { * @throws IllegalArgumentException the data is null * @throws NotYetConnectedException websocket is not yet connected */ - void send( byte[] bytes ) throws IllegalArgumentException , NotYetConnectedException; + void send( byte[] bytes ); /** * Send a frame to the other end @@ -170,22 +156,15 @@ enum READYSTATE { */ InetSocketAddress getLocalSocketAddress(); - /** - * Is the websocket in the state CONNECTING - * @return state equals READYSTATE.CONNECTING - */ - @Deprecated - boolean isConnecting(); - /** * Is the websocket in the state OPEN - * @return state equals READYSTATE.OPEN + * @return state equals ReadyState.OPEN */ boolean isOpen(); /** * Is the websocket in the state CLOSING - * @return state equals READYSTATE.CLOSING + * @return state equals ReadyState.CLOSING */ boolean isClosing(); @@ -198,7 +177,7 @@ enum READYSTATE { /** * Is the websocket in the state CLOSED - * @return state equals READYSTATE.CLOSED + * @return state equals ReadyState.CLOSED */ boolean isClosed(); @@ -209,13 +188,13 @@ enum READYSTATE { Draft getDraft(); /** - * Retrieve the WebSocket 'readyState'. + * Retrieve the WebSocket 'ReadyState'. * This represents the state of the connection. * It returns a numerical value, as per W3C WebSockets specs. * * @return Returns '0 = CONNECTING', '1 = OPEN', '2 = CLOSING' or '3 = CLOSED' */ - READYSTATE getReadyState(); + ReadyState getReadyState(); /** * Returns the HTTP Request-URI as defined by http://tools.ietf.org/html/rfc2616#section-5.1.2
diff --git a/src/main/java/org/java_websocket/WebSocketAdapter.java b/src/main/java/org/java_websocket/WebSocketAdapter.java index 9d543539..8ace56dd 100644 --- a/src/main/java/org/java_websocket/WebSocketAdapter.java +++ b/src/main/java/org/java_websocket/WebSocketAdapter.java @@ -65,17 +65,6 @@ public void onWebsocketHandshakeSentAsClient( WebSocket conn, ClientHandshake re //To overwrite } - /** - * This default implementation does not do anything. Go ahead and overwrite it - * - * @see org.java_websocket.WebSocketListener#onWebsocketMessageFragment(WebSocket, Framedata) - */ - @Override - @Deprecated - public void onWebsocketMessageFragment( WebSocket conn, Framedata frame ) { - //To overwrite - } - /** * This default implementation will send a pong in response to the received ping. * The pong frame will have the same payload as the ping frame. diff --git a/src/main/java/org/java_websocket/WebSocketImpl.java b/src/main/java/org/java_websocket/WebSocketImpl.java index a55922e2..89e1c8a9 100644 --- a/src/main/java/org/java_websocket/WebSocketImpl.java +++ b/src/main/java/org/java_websocket/WebSocketImpl.java @@ -26,16 +26,14 @@ package org.java_websocket; import org.java_websocket.drafts.Draft; -import org.java_websocket.drafts.Draft.CloseHandshakeType; -import org.java_websocket.drafts.Draft.HandshakeState; import org.java_websocket.drafts.Draft_6455; +import org.java_websocket.enums.*; import org.java_websocket.exceptions.IncompleteHandshakeException; import org.java_websocket.exceptions.InvalidDataException; import org.java_websocket.exceptions.InvalidHandshakeException; import org.java_websocket.exceptions.WebsocketNotConnectedException; import org.java_websocket.framing.CloseFrame; import org.java_websocket.framing.Framedata; -import org.java_websocket.framing.Framedata.Opcode; import org.java_websocket.framing.PingFrame; import org.java_websocket.handshake.*; import org.java_websocket.server.WebSocketServer.WebSocketWorker; @@ -43,7 +41,6 @@ import java.io.IOException; import java.net.InetSocketAddress; -import java.net.Socket; import java.nio.ByteBuffer; import java.nio.channels.ByteChannel; import java.nio.channels.NotYetConnectedException; @@ -55,18 +52,27 @@ import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * Represents one end (client or server) of a single WebSocketImpl connection. * Takes care of the "handshake" phase, then allows for easy sending of * text frames, and receiving frames through an event-based model. */ public class WebSocketImpl implements WebSocket { - public static int RCVBUF = 16384; /** - * Activate debug mode for additional infos + * Initial buffer size + */ + public static final int RCVBUF = 16384; + + /** + * Logger instance + * + * @since 1.4.0 */ - public static boolean DEBUG = false; // must be final in the future in order to take advantage of VM optimization + private static final Logger log = LoggerFactory.getLogger(WebSocketImpl.class); /** * Queue of buffers that need to be sent to the client. @@ -97,7 +103,7 @@ public class WebSocketImpl implements WebSocket { /** * The current state of the connection */ - private READYSTATE readystate = READYSTATE.NOT_YET_CONNECTED; + private ReadyState readyState = ReadyState.NOT_YET_CONNECTED; /** * A list of drafts available for this websocket @@ -186,16 +192,6 @@ public WebSocketImpl( WebSocketListener listener, Draft draft ) { this.draft = draft.copyInstance(); } - @Deprecated - public WebSocketImpl( WebSocketListener listener, Draft draft, Socket socket ) { - this( listener, draft ); - } - - @Deprecated - public WebSocketImpl( WebSocketListener listener, List drafts, Socket socket ) { - this( listener, drafts ); - } - /** * Method to decode the provided ByteBuffer * @@ -203,18 +199,15 @@ public WebSocketImpl( WebSocketListener listener, List drafts, Socket soc */ public void decode( ByteBuffer socketBuffer ) { assert ( socketBuffer.hasRemaining() ); + log.trace( "process({}): ({})", socketBuffer.remaining(), ( socketBuffer.remaining() > 1000 ? "too big to display" : new String( socketBuffer.array(), socketBuffer.position(), socketBuffer.remaining() ) )); - if( DEBUG ) - System.out.println( "process(" + socketBuffer.remaining() + "): {" + ( socketBuffer.remaining() > 1000 ? "too big to display" : new String( socketBuffer.array(), socketBuffer.position(), socketBuffer.remaining() ) ) + '}' ); - - if( getReadyState() != READYSTATE.NOT_YET_CONNECTED ) { - if( getReadyState() == READYSTATE.OPEN ) { + if( getReadyState() != ReadyState.NOT_YET_CONNECTED ) { + if( getReadyState() == ReadyState.OPEN ) { decodeFrames( socketBuffer ); } } else { if( decodeHandshake( socketBuffer ) && (!isClosing() && !isClosed())) { assert ( tmpHandshakeBytes.hasRemaining() != socketBuffer.hasRemaining() || !socketBuffer.hasRemaining() ); // the buffers will never have remaining bytes at the same time - if( socketBuffer.hasRemaining() ) { decodeFrames( socketBuffer ); } else if( tmpHandshakeBytes.hasRemaining() ) { @@ -258,6 +251,7 @@ private boolean decodeHandshake( ByteBuffer socketBufferNew ) { socketBuffer.reset(); Handshakedata tmphandshake = d.translateHandshake( socketBuffer ); if( !( tmphandshake instanceof ClientHandshake ) ) { + log.trace("Closing due to wrong handshake"); closeConnectionDueToWrongHandshake( new InvalidDataException( CloseFrame.PROTOCOL_ERROR, "wrong http function" ) ); return false; } @@ -269,9 +263,11 @@ private boolean decodeHandshake( ByteBuffer socketBufferNew ) { try { response = wsl.onWebsocketHandshakeReceivedAsServer( this, d, handshake ); } catch ( InvalidDataException e ) { + log.trace("Closing due to wrong handshake. Possible handshake rejection", e); closeConnectionDueToWrongHandshake( e ); return false; } catch ( RuntimeException e ) { + log.error("Closing due to internal server error", e); wsl.onWebsocketError( this, e ); closeConnectionDueToInternalServerError( e ); return false; @@ -286,6 +282,7 @@ private boolean decodeHandshake( ByteBuffer socketBufferNew ) { } } if( draft == null ) { + log.trace("Closing due to protocol error: no draft matches"); closeConnectionDueToWrongHandshake( new InvalidDataException( CloseFrame.PROTOCOL_ERROR, "no draft matches" ) ); } return false; @@ -293,6 +290,7 @@ private boolean decodeHandshake( ByteBuffer socketBufferNew ) { // special case for multiple step handshakes Handshakedata tmphandshake = draft.translateHandshake( socketBuffer ); if( !( tmphandshake instanceof ClientHandshake ) ) { + log.trace("Closing due to protocol error: wrong http function"); flushAndClose( CloseFrame.PROTOCOL_ERROR, "wrong http function", false ); return false; } @@ -303,7 +301,8 @@ private boolean decodeHandshake( ByteBuffer socketBufferNew ) { open( handshake ); return true; } else { - close( CloseFrame.PROTOCOL_ERROR, "the handshake did finaly not match" ); + log.trace("Closing due to protocol error: the handshake did finally not match"); + close( CloseFrame.PROTOCOL_ERROR, "the handshake did finally not match" ); } return false; } @@ -311,6 +310,7 @@ private boolean decodeHandshake( ByteBuffer socketBufferNew ) { draft.setParseMode( role ); Handshakedata tmphandshake = draft.translateHandshake( socketBuffer ); if( !( tmphandshake instanceof ServerHandshake ) ) { + log.trace("Closing due to protocol error: wrong http function"); flushAndClose( CloseFrame.PROTOCOL_ERROR, "wrong http function", false ); return false; } @@ -320,9 +320,11 @@ private boolean decodeHandshake( ByteBuffer socketBufferNew ) { try { wsl.onWebsocketHandshakeReceivedAsClient( this, handshakerequest, handshake ); } catch ( InvalidDataException e ) { + log.trace("Closing due to invalid data exception. Possible handshake rejection", e); flushAndClose( e.getCloseCode(), e.getMessage(), false ); return false; } catch ( RuntimeException e ) { + log.error("Closing since client was never connected", e); wsl.onWebsocketError( this, e ); flushAndClose( CloseFrame.NEVER_CONNECTED, e.getMessage(), false ); return false; @@ -330,10 +332,12 @@ private boolean decodeHandshake( ByteBuffer socketBufferNew ) { open( handshake ); return true; } else { + log.trace("Closing due to protocol error: draft {} refuses handshake", draft ); close( CloseFrame.PROTOCOL_ERROR, "draft " + draft + " refuses handshake" ); } } } catch ( InvalidHandshakeException e ) { + log.trace("Closing due to invalid handshake", e); close( e ); } } catch ( IncompleteHandshakeException e ) { @@ -362,14 +366,13 @@ private void decodeFrames( ByteBuffer socketBuffer ) { try { frames = draft.translateFrame( socketBuffer ); for( Framedata f : frames ) { - if( DEBUG ) - System.out.println( "matched frame: " + f ); + log.trace( "matched frame: {}" , f ); draft.processFrame( this, f ); } - } catch ( InvalidDataException e1 ) { - wsl.onWebsocketError( this, e1 ); - close( e1 ); - return; + } catch ( InvalidDataException e ) { + log.error("Closing due to invalid data in frame", e); + wsl.onWebsocketError( this, e ); + close(e); } } @@ -413,11 +416,11 @@ private ByteBuffer generateHttpResponseDueToError( int errorCode ) { } public synchronized void close( int code, String message, boolean remote ) { - if( getReadyState() != READYSTATE.CLOSING && readystate != READYSTATE.CLOSED ) { - if( getReadyState() == READYSTATE.OPEN ) { + if( getReadyState() != ReadyState.CLOSING && readyState != ReadyState.CLOSED ) { + if( getReadyState() == ReadyState.OPEN ) { if( code == CloseFrame.ABNORMAL_CLOSE ) { assert ( !remote ); - setReadyState( READYSTATE.CLOSING ); + setReadyState( ReadyState.CLOSING ); flushAndClose( code, message, false ); return; } @@ -438,6 +441,7 @@ public synchronized void close( int code, String message, boolean remote ) { sendFrame( closeFrame ); } } catch ( InvalidDataException e ) { + log.error("generated frame is invalid", e); wsl.onWebsocketError( this, e ); flushAndClose( CloseFrame.ABNORMAL_CLOSE, "generated frame is invalid", false ); } @@ -451,7 +455,7 @@ public synchronized void close( int code, String message, boolean remote ) { } else { flushAndClose( CloseFrame.NEVER_CONNECTED, message, false ); } - setReadyState( READYSTATE.CLOSING ); + setReadyState( ReadyState.CLOSING ); tmpHandshakeBytes = null; return; } @@ -474,13 +478,13 @@ public void close( int code, String message ) { * remote may also be true if this endpoint started the closing handshake since the other endpoint may not simply echo the code but close the connection the same time this endpoint does do but with an other code.
**/ public synchronized void closeConnection( int code, String message, boolean remote ) { - if( getReadyState() == READYSTATE.CLOSED ) { + if( getReadyState() == ReadyState.CLOSED ) { return; } - //Methods like eot() call this method without calling onClose(). Due to that reason we have to adjust the readystate manually - if( getReadyState() == READYSTATE.OPEN ) { + //Methods like eot() call this method without calling onClose(). Due to that reason we have to adjust the ReadyState manually + if( getReadyState() == ReadyState.OPEN ) { if( code == CloseFrame.ABNORMAL_CLOSE ) { - setReadyState( READYSTATE.CLOSING ); + setReadyState( ReadyState.CLOSING ); } } if( key != null ) { @@ -492,10 +496,9 @@ public synchronized void closeConnection( int code, String message, boolean remo channel.close(); } catch ( IOException e ) { if( e.getMessage().equals( "Broken pipe" ) ) { - if( WebSocketImpl.DEBUG ) { - System.out.println( "Caught IOException: Broken pipe during closeConnection()" ); - } + log.trace( "Caught IOException: Broken pipe during closeConnection()", e ); } else { + log.error("Exception during channel.close()", e); wsl.onWebsocketError( this, e ); } } @@ -503,12 +506,13 @@ public synchronized void closeConnection( int code, String message, boolean remo try { this.wsl.onWebsocketClose( this, code, message, remote ); } catch ( RuntimeException e ) { + wsl.onWebsocketError( this, e ); } if( draft != null ) draft.reset(); handshakerequest = null; - setReadyState( READYSTATE.CLOSED ); + setReadyState( ReadyState.CLOSED ); } protected void closeConnection( int code, boolean remote ) { @@ -517,7 +521,7 @@ protected void closeConnection( int code, boolean remote ) { public void closeConnection() { if( closedremotely == null ) { - throw new IllegalStateException( "this method must be used in conjuction with flushAndClose" ); + throw new IllegalStateException( "this method must be used in conjunction with flushAndClose" ); } closeConnection( closecode, closemessage, closedremotely ); } @@ -540,6 +544,7 @@ public synchronized void flushAndClose( int code, String message, boolean remote try { wsl.onWebsocketClosing( this, code, message, remote ); } catch ( RuntimeException e ) { + log.error("Exception in onWebsocketClosing", e); wsl.onWebsocketError( this, e ); } if( draft != null ) @@ -548,7 +553,7 @@ public synchronized void flushAndClose( int code, String message, boolean remote } public void eot() { - if( getReadyState() == READYSTATE.NOT_YET_CONNECTED ) { + if( getReadyState() == ReadyState.NOT_YET_CONNECTED ) { closeConnection( CloseFrame.NEVER_CONNECTED, true ); } else if( flushandclosestate ) { closeConnection( closecode, closemessage, closedremotely ); @@ -612,15 +617,14 @@ private void send( Collection frames ) { } ArrayList outgoingFrames = new ArrayList(); for( Framedata f : frames ) { - if( DEBUG ) - System.out.println( "send frame: " + f ); + log.trace( "send frame: {}", f); outgoingFrames.add( draft.createBinaryFrame( f ) ); } write( outgoingFrames ); } @Override - public void sendFragmentedFrame( Opcode op, ByteBuffer buffer, boolean fin ) { + public void sendFragmentedFrame(Opcode op, ByteBuffer buffer, boolean fin ) { send( draft.continuousFrame( op, buffer, fin ) ); } @@ -660,8 +664,9 @@ public void startHandshake( ClientHandshakeBuilder handshakedata ) throws Invali // Stop if the client code throws an exception throw new InvalidHandshakeException( "Handshake data rejected by client." ); } catch ( RuntimeException e ) { + log.error("Exception in startHandshake", e); wsl.onWebsocketError( this, e ); - throw new InvalidHandshakeException( "rejected because of" + e ); + throw new InvalidHandshakeException( "rejected because of " + e ); } // Send @@ -669,17 +674,9 @@ public void startHandshake( ClientHandshakeBuilder handshakedata ) throws Invali } private void write( ByteBuffer buf ) { - if( DEBUG ) - System.out.println( "write(" + buf.remaining() + "): {" + ( buf.remaining() > 1000 ? "too big to display" : new String( buf.array() ) ) + '}' ); + log.trace( "write({}): {}", buf.remaining(), buf.remaining() > 1000 ? "too big to display" : new String( buf.array() )); outQueue.add( buf ); - /*try { - outQueue.put( buf ); - } catch ( InterruptedException e ) { - write( buf ); - Thread.currentThread().interrupt(); // keep the interrupted status - e.printStackTrace(); - }*/ wsl.onWriteDemand( this ); } @@ -697,9 +694,8 @@ private void write( List bufs ) { } private void open( Handshakedata d ) { - if( DEBUG ) - System.out.println( "open using draft: " + draft ); - setReadyState( READYSTATE.OPEN ); + log.trace( "open using draft: {}",draft ); + setReadyState( ReadyState.OPEN ); try { wsl.onWebsocketOpen( this, d ); } catch ( RuntimeException e ) { @@ -707,21 +703,14 @@ private void open( Handshakedata d ) { } } - @Override - @Deprecated - public boolean isConnecting() { - assert ( !flushandclosestate || getReadyState() == READYSTATE.CONNECTING ); - return getReadyState() == READYSTATE.CONNECTING; // ifflushandclosestate - } - @Override public boolean isOpen() { - return getReadyState() == READYSTATE.OPEN; + return getReadyState() == ReadyState.OPEN; } @Override public boolean isClosing() { - return getReadyState() == READYSTATE.CLOSING; + return getReadyState() == ReadyState.CLOSING; } @Override @@ -731,21 +720,16 @@ public boolean isFlushAndClose() { @Override public boolean isClosed() { - return getReadyState() == READYSTATE.CLOSED; + return getReadyState() == ReadyState.CLOSED; } @Override - public READYSTATE getReadyState() { - return readystate; + public ReadyState getReadyState() { + return readyState; } - private void setReadyState( READYSTATE readystate ) { - this.readystate = readystate; - } - - @Override - public int hashCode() { - return super.hashCode(); + private void setReadyState( ReadyState ReadyState ) { + this.readyState = ReadyState; } @Override diff --git a/src/main/java/org/java_websocket/WebSocketListener.java b/src/main/java/org/java_websocket/WebSocketListener.java index b486ac46..f2c56556 100644 --- a/src/main/java/org/java_websocket/WebSocketListener.java +++ b/src/main/java/org/java_websocket/WebSocketListener.java @@ -111,17 +111,6 @@ public interface WebSocketListener { */ void onWebsocketMessage( WebSocket conn, ByteBuffer blob ); - /** - * Called when a frame fragment has been recieved - * - * This method will be removed in a future version since the lib will also call the respective onWebsocketMessage method - * @param conn - * The WebSocket instance this event is occurring on. - * @param frame The fragmented frame - */ - @Deprecated - void onWebsocketMessageFragment( WebSocket conn, Framedata frame ); - /** * Called after onHandshakeReceived returns true. * Indicates that a complete WebSocket connection has been established, diff --git a/src/main/java/org/java_websocket/client/WebSocketClient.java b/src/main/java/org/java_websocket/client/WebSocketClient.java index cd9e16fc..c4e9b0e4 100644 --- a/src/main/java/org/java_websocket/client/WebSocketClient.java +++ b/src/main/java/org/java_websocket/client/WebSocketClient.java @@ -49,10 +49,11 @@ import org.java_websocket.WebSocketImpl; import org.java_websocket.drafts.Draft; import org.java_websocket.drafts.Draft_6455; +import org.java_websocket.enums.Opcode; +import org.java_websocket.enums.ReadyState; import org.java_websocket.exceptions.InvalidHandshakeException; import org.java_websocket.framing.CloseFrame; import org.java_websocket.framing.Framedata; -import org.java_websocket.framing.Framedata.Opcode; import org.java_websocket.handshake.HandshakeImpl1Client; import org.java_websocket.handshake.Handshakedata; import org.java_websocket.handshake.ServerHandshake; @@ -480,7 +481,7 @@ private void sendHandshake() throws InvalidHandshakeException { /** * This represents the state of the connection. */ - public READYSTATE getReadyState() { + public ReadyState getReadyState() { return engine.getReadyState(); } @@ -497,11 +498,6 @@ public final void onWebsocketMessage( WebSocket conn, ByteBuffer blob ) { onMessage( blob ); } - @Override - public void onWebsocketMessageFragment( WebSocket conn, Framedata frame ) { - onFragment( frame ); - } - /** * Calls subclass' implementation of onOpen. */ @@ -639,15 +635,6 @@ public void onMessage( ByteBuffer bytes ) { //To overwrite } - /** - * Callback for fragmented frames - * @see WebSocket#sendFragmentedFrame(org.java_websocket.framing.Framedata.Opcode, ByteBuffer, boolean) - * @param frame The fragmented frame - */ - @Deprecated - public void onFragment( Framedata frame ) { - //To overwrite - } private class WebsocketWriteThread implements Runnable { @Override @@ -665,6 +652,7 @@ public void run() { ostream.write( buffer.array(), 0, buffer.limit() ); ostream.flush(); } + Thread.currentThread().interrupt(); } } catch ( IOException e ) { handleIOException( e ); @@ -712,7 +700,7 @@ public void setSocket( Socket socket ) { } @Override - public void sendFragmentedFrame( Opcode op, ByteBuffer buffer, boolean fin ) { + public void sendFragmentedFrame(Opcode op, ByteBuffer buffer, boolean fin ) { engine.sendFragmentedFrame( op, buffer, fin ); } @@ -736,12 +724,6 @@ public boolean isClosing() { return engine.isClosing(); } - @Override - @Deprecated - public boolean isConnecting() { - return engine.isConnecting(); - } - @Override public boolean hasBufferedData() { return engine.hasBufferedData(); diff --git a/src/main/java/org/java_websocket/drafts/Draft.java b/src/main/java/org/java_websocket/drafts/Draft.java index b6630608..a114a5f7 100644 --- a/src/main/java/org/java_websocket/drafts/Draft.java +++ b/src/main/java/org/java_websocket/drafts/Draft.java @@ -31,14 +31,16 @@ import java.util.List; import java.util.Locale; -import org.java_websocket.WebSocket.Role; import org.java_websocket.WebSocketImpl; +import org.java_websocket.enums.CloseHandshakeType; +import org.java_websocket.enums.HandshakeState; +import org.java_websocket.enums.Opcode; +import org.java_websocket.enums.Role; import org.java_websocket.exceptions.IncompleteHandshakeException; import org.java_websocket.exceptions.InvalidDataException; import org.java_websocket.exceptions.InvalidHandshakeException; import org.java_websocket.exceptions.LimitExedeedException; import org.java_websocket.framing.*; -import org.java_websocket.framing.Framedata.Opcode; import org.java_websocket.handshake.ClientHandshake; import org.java_websocket.handshake.ClientHandshakeBuilder; import org.java_websocket.handshake.HandshakeBuilder; @@ -54,25 +56,6 @@ **/ public abstract class Draft { - /** - * Enum which represents the states a handshake may be in - */ - public enum HandshakeState { - /** Handshake matched this Draft successfully */ - MATCHED, - /** Handshake is does not match this Draft */ - NOT_MATCHED - } - /** - * Enum which represents type of handshake is required for a close - */ - public enum CloseHandshakeType { - NONE, ONEWAY, TWOWAY - } - - public static int MAX_FAME_SIZE = 1000; - public static int INITIAL_FAMESIZE = 64; - /** In some cases the handshake will be parsed different depending on whether */ protected Role role = null; @@ -161,7 +144,7 @@ public static HandshakeBuilder translateHandshakeHttp( ByteBuffer buf, Role role public abstract HandshakeState acceptHandshakeAsClient( ClientHandshake request, ServerHandshake response ) throws InvalidHandshakeException; - public abstract HandshakeState acceptHandshakeAsServer( ClientHandshake handshakedata ) throws InvalidHandshakeException; + public abstract HandshakeState acceptHandshakeAsServer(ClientHandshake handshakedata ) throws InvalidHandshakeException; protected boolean basicAccept( Handshakedata handshakedata ) { return handshakedata.getFieldValue( "Upgrade" ).equalsIgnoreCase( "websocket" ) && handshakedata.getFieldValue( "Connection" ).toLowerCase( Locale.ENGLISH ).contains( "upgrade" ); @@ -182,7 +165,7 @@ protected boolean basicAccept( Handshakedata handshakedata ) { */ public abstract void processFrame( WebSocketImpl webSocketImpl, Framedata frame ) throws InvalidDataException; - public List continuousFrame( Opcode op, ByteBuffer buffer, boolean fin ) { + public List continuousFrame(Opcode op, ByteBuffer buffer, boolean fin ) { if(op != Opcode.BINARY && op != Opcode.TEXT) { throw new IllegalArgumentException( "Only Opcode.BINARY or Opcode.TEXT are allowed" ); } diff --git a/src/main/java/org/java_websocket/drafts/Draft_6455.java b/src/main/java/org/java_websocket/drafts/Draft_6455.java index 4c05cffd..17e2e6da 100644 --- a/src/main/java/org/java_websocket/drafts/Draft_6455.java +++ b/src/main/java/org/java_websocket/drafts/Draft_6455.java @@ -25,8 +25,8 @@ package org.java_websocket.drafts; -import org.java_websocket.WebSocket; import org.java_websocket.WebSocketImpl; +import org.java_websocket.enums.*; import org.java_websocket.exceptions.*; import org.java_websocket.extensions.*; import org.java_websocket.framing.*; @@ -35,6 +35,8 @@ import org.java_websocket.protocols.Protocol; import org.java_websocket.util.*; import org.java_websocket.util.Base64; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.math.BigInteger; import java.nio.ByteBuffer; @@ -49,6 +51,13 @@ */ public class Draft_6455 extends Draft { + /** + * Logger instance + * + * @since 1.4.0 + */ + private static final Logger log = LoggerFactory.getLogger(Draft_6455.class); + /** * Attribute for the used extension in this draft */ @@ -150,7 +159,7 @@ public Draft_6455( List inputExtensions , List inputProto public HandshakeState acceptHandshakeAsServer( ClientHandshake handshakedata ) throws InvalidHandshakeException { int v = readVersion( handshakedata ); if( v != 13 ) { - logDebug("acceptHandshakeAsServer - Wrong websocket version."); + log.trace("acceptHandshakeAsServer - Wrong websocket version."); return HandshakeState.NOT_MATCHED; } HandshakeState extensionState = HandshakeState.NOT_MATCHED; @@ -159,7 +168,7 @@ public HandshakeState acceptHandshakeAsServer( ClientHandshake handshakedata ) t if( knownExtension.acceptProvidedExtensionAsServer( requestedExtension ) ) { extension = knownExtension; extensionState = HandshakeState.MATCHED; - logDebug("acceptHandshakeAsServer - Matching extension found: " + extension.toString()); + log.trace("acceptHandshakeAsServer - Matching extension found: {}", extension); break; } } @@ -169,25 +178,25 @@ public HandshakeState acceptHandshakeAsServer( ClientHandshake handshakedata ) t if( knownProtocol.acceptProvidedProtocol( requestedProtocol ) ) { protocol = knownProtocol; protocolState = HandshakeState.MATCHED; - logDebug("acceptHandshakeAsServer - Matching protocol found: " + protocol.toString()); + log.trace("acceptHandshakeAsServer - Matching protocol found: {}", protocol); break; } } if (protocolState == HandshakeState.MATCHED && extensionState == HandshakeState.MATCHED) { return HandshakeState.MATCHED; } - logDebug("acceptHandshakeAsServer - No matching extension or protocol found."); + log.trace("acceptHandshakeAsServer - No matching extension or protocol found."); return HandshakeState.NOT_MATCHED; } @Override public HandshakeState acceptHandshakeAsClient( ClientHandshake request, ServerHandshake response ) throws InvalidHandshakeException { if (! basicAccept( response )) { - logDebug("acceptHandshakeAsClient - Missing/wrong upgrade or connection in handshake."); + log.trace("acceptHandshakeAsClient - Missing/wrong upgrade or connection in handshake."); return HandshakeState.NOT_MATCHED; } if( !request.hasFieldValue( "Sec-WebSocket-Key" ) || !response.hasFieldValue( "Sec-WebSocket-Accept" ) ) { - logDebug("acceptHandshakeAsClient - Missing Sec-WebSocket-Key or Sec-WebSocket-Accept"); + log.trace("acceptHandshakeAsClient - Missing Sec-WebSocket-Key or Sec-WebSocket-Accept"); return HandshakeState.NOT_MATCHED; } @@ -196,7 +205,7 @@ public HandshakeState acceptHandshakeAsClient( ClientHandshake request, ServerHa seckey_challenge = generateFinalKey( seckey_challenge ); if( !seckey_challenge.equals( seckey_answere ) ) { - logDebug("acceptHandshakeAsClient - Wrong key for Sec-WebSocket-Key."); + log.trace("acceptHandshakeAsClient - Wrong key for Sec-WebSocket-Key."); return HandshakeState.NOT_MATCHED; } @@ -206,7 +215,7 @@ public HandshakeState acceptHandshakeAsClient( ClientHandshake request, ServerHa if( knownExtension.acceptProvidedExtensionAsClient( requestedExtension ) ) { extension = knownExtension; extensionState = HandshakeState.MATCHED; - logDebug("acceptHandshakeAsClient - Matching extension found: " + extension.toString()); + log.trace("acceptHandshakeAsClient - Matching extension found: {}",extension); break; } } @@ -216,14 +225,14 @@ public HandshakeState acceptHandshakeAsClient( ClientHandshake request, ServerHa if( knownProtocol.acceptProvidedProtocol( requestedProtocol ) ) { protocol = knownProtocol; protocolState = HandshakeState.MATCHED; - logDebug("acceptHandshakeAsClient - Matching protocol found: " + protocol.toString()); + log.trace("acceptHandshakeAsClient - Matching protocol found: {}",protocol); break; } } if (protocolState == HandshakeState.MATCHED && extensionState == HandshakeState.MATCHED) { return HandshakeState.MATCHED; } - logDebug("acceptHandshakeAsClient - No matching extension or protocol found."); + log.trace("acceptHandshakeAsClient - No matching extension or protocol found."); return HandshakeState.NOT_MATCHED; } @@ -334,14 +343,13 @@ public Draft copyInstance() { @Override public ByteBuffer createBinaryFrame( Framedata framedata ) { getExtension().encodeFrame( framedata ); - if( WebSocketImpl.DEBUG ) - System.out.println( "afterEnconding(" + framedata.getPayloadData().remaining() + "): {" + ( framedata.getPayloadData().remaining() > 1000 ? "too big to display" : new String( framedata.getPayloadData().array() ) ) + '}' ); + log.trace( "afterEnconding({}): {}" , framedata.getPayloadData().remaining(), ( framedata.getPayloadData().remaining() > 1000 ? "too big to display" : new String( framedata.getPayloadData().array() ) ) ); return createByteBufferFromFramedata( framedata ); } private ByteBuffer createByteBufferFromFramedata( Framedata framedata ) { ByteBuffer mes = framedata.getPayloadData(); - boolean mask = role == WebSocket.Role.CLIENT; // framedata.getTransfereMasked(); + boolean mask = role == Role.CLIENT; // framedata.getTransfereMasked(); int sizebytes = mes.remaining() <= 125 ? 1 : mes.remaining() <= 65535 ? 2 : 8; ByteBuffer buf = ByteBuffer.allocate( 1 + ( sizebytes > 1 ? sizebytes + 1 : sizebytes ) + ( mask ? 4 : 0 ) + mes.remaining() ); byte optcode = fromOpcode( framedata.getOpcode() ); @@ -382,8 +390,10 @@ private ByteBuffer createByteBufferFromFramedata( Framedata framedata ) { public Framedata translateSingleFrame( ByteBuffer buffer ) throws IncompleteException, InvalidDataException { int maxpacketsize = buffer.remaining(); int realpacketsize = 2; - if( maxpacketsize < realpacketsize ) + if( maxpacketsize < realpacketsize ) { + log.trace( "Incomplete frame" ); throw new IncompleteException( realpacketsize ); + } byte b1 = buffer.get( /*0*/ ); boolean FIN = b1 >> 8 != 0; boolean rsv1 = false; @@ -401,30 +411,37 @@ public Framedata translateSingleFrame( ByteBuffer buffer ) throws IncompleteExce byte b2 = buffer.get( /*1*/ ); boolean MASK = ( b2 & -128 ) != 0; int payloadlength = ( byte ) ( b2 & ~( byte ) 128 ); - Framedata.Opcode optcode = toOpcode( ( byte ) ( b1 & 15 ) ); + Opcode optcode = toOpcode( ( byte ) ( b1 & 15 ) ); if( !( payloadlength >= 0 && payloadlength <= 125 ) ) { - if( optcode == Framedata.Opcode.PING || optcode == Framedata.Opcode.PONG || optcode == Framedata.Opcode.CLOSING ) { + + if( optcode == Opcode.PING || optcode == Opcode.PONG || optcode == Opcode.CLOSING ) { + log.trace( "Invalid frame: more than 125 octets" ); throw new InvalidFrameException( "more than 125 octets" ); } if( payloadlength == 126 ) { realpacketsize += 2; // additional length bytes - if( maxpacketsize < realpacketsize ) + if( maxpacketsize < realpacketsize ) { + log.trace( "Incomplete frame" ); throw new IncompleteException( realpacketsize ); + } byte[] sizebytes = new byte[3]; sizebytes[1] = buffer.get( /*1 + 1*/ ); sizebytes[2] = buffer.get( /*1 + 2*/ ); payloadlength = new BigInteger( sizebytes ).intValue(); } else { realpacketsize += 8; // additional length bytes - if( maxpacketsize < realpacketsize ) + if( maxpacketsize < realpacketsize ) { + log.trace( "Incomplete frame" ); throw new IncompleteException( realpacketsize ); + } byte[] bytes = new byte[8]; for( int i = 0; i < 8; i++ ) { bytes[i] = buffer.get( /*1 + i*/ ); } long length = new BigInteger( bytes ).longValue(); if( length > Integer.MAX_VALUE ) { + log.trace( "Limit exedeed: Payloadsize is to big..." ); throw new LimitExedeedException( "Payloadsize is to big..." ); } else { payloadlength = ( int ) length; @@ -461,8 +478,7 @@ public Framedata translateSingleFrame( ByteBuffer buffer ) throws IncompleteExce frame.setPayload( payload ); getExtension().isFrameValid(frame); getExtension().decodeFrame(frame); - if( WebSocketImpl.DEBUG ) - System.out.println( "afterDecoding(" + frame.getPayloadData().remaining() + "): {" + ( frame.getPayloadData().remaining() > 1000 ? "too big to display" : new String( frame.getPayloadData().array() ) ) + '}' ); + log.trace( "afterDecoding({}): {}", frame.getPayloadData().remaining(), ( frame.getPayloadData().remaining() > 1000 ? "too big to display" : new String( frame.getPayloadData().array() ) ) ); frame.isValid(); return frame; } @@ -596,38 +612,37 @@ private byte[] toByteArray( long val, int bytecount ) { } - private byte fromOpcode( Framedata.Opcode opcode ) { - if( opcode == Framedata.Opcode.CONTINUOUS ) + private byte fromOpcode( Opcode opcode ) { + if( opcode == Opcode.CONTINUOUS ) return 0; - else if( opcode == Framedata.Opcode.TEXT ) + else if( opcode == Opcode.TEXT ) return 1; - else if( opcode == Framedata.Opcode.BINARY ) + else if( opcode == Opcode.BINARY ) return 2; - else if( opcode == Framedata.Opcode.CLOSING ) + else if( opcode == Opcode.CLOSING ) return 8; - else if( opcode == Framedata.Opcode.PING ) + else if( opcode == Opcode.PING ) return 9; - else if( opcode == Framedata.Opcode.PONG ) + else if( opcode == Opcode.PONG ) return 10; throw new IllegalArgumentException( "Don't know how to handle " + opcode.toString() ); } - - private Framedata.Opcode toOpcode( byte opcode ) throws InvalidFrameException { + private Opcode toOpcode( byte opcode ) throws InvalidFrameException { switch(opcode) { case 0: - return Framedata.Opcode.CONTINUOUS; + return Opcode.CONTINUOUS; case 1: - return Framedata.Opcode.TEXT; + return Opcode.TEXT; case 2: - return Framedata.Opcode.BINARY; + return Opcode.BINARY; // 3-7 are not yet defined case 8: - return Framedata.Opcode.CLOSING; + return Opcode.CLOSING; case 9: - return Framedata.Opcode.PING; + return Opcode.PING; case 10: - return Framedata.Opcode.PONG; + return Opcode.PONG; // 11-15 are not yet defined default: throw new InvalidFrameException( "Unknown opcode " + ( short ) opcode ); @@ -636,8 +651,8 @@ private Framedata.Opcode toOpcode( byte opcode ) throws InvalidFrameException { @Override public void processFrame( WebSocketImpl webSocketImpl, Framedata frame ) throws InvalidDataException { - Framedata.Opcode curop = frame.getOpcode(); - if( curop == Framedata.Opcode.CLOSING ) { + Opcode curop = frame.getOpcode(); + if( curop == Opcode.CLOSING ) { int code = CloseFrame.NOCODE; String reason = ""; if( frame instanceof CloseFrame ) { @@ -645,7 +660,7 @@ public void processFrame( WebSocketImpl webSocketImpl, Framedata frame ) throws code = cf.getCloseCode(); reason = cf.getMessage(); } - if( webSocketImpl.getReadyState() == WebSocket.READYSTATE.CLOSING ) { + if( webSocketImpl.getReadyState() == ReadyState.CLOSING ) { // complete the close handshake by disconnecting webSocketImpl.closeConnection( code, reason, true ); } else { @@ -655,75 +670,87 @@ public void processFrame( WebSocketImpl webSocketImpl, Framedata frame ) throws else webSocketImpl.flushAndClose( code, reason, false ); } - } else if( curop == Framedata.Opcode.PING ) { + } else if( curop == Opcode.PING ) { webSocketImpl.getWebSocketListener().onWebsocketPing( webSocketImpl, frame ); - } else if( curop == Framedata.Opcode.PONG ) { + } else if( curop == Opcode.PONG ) { webSocketImpl.updateLastPong(); webSocketImpl.getWebSocketListener().onWebsocketPong( webSocketImpl, frame ); - } else if( !frame.isFin() || curop == Framedata.Opcode.CONTINUOUS ) { - if( curop != Framedata.Opcode.CONTINUOUS ) { - if( current_continuous_frame != null ) + } else if( !frame.isFin() || curop == Opcode.CONTINUOUS ) { + if( curop != Opcode.CONTINUOUS ) { + if( current_continuous_frame != null ) { + log.trace( "Protocol error: Previous continuous frame sequence not completed." ); throw new InvalidDataException( CloseFrame.PROTOCOL_ERROR, "Previous continuous frame sequence not completed." ); + } current_continuous_frame = frame; byteBufferList.add( frame.getPayloadData() ); } else if( frame.isFin() ) { - if( current_continuous_frame == null ) + if( current_continuous_frame == null ) { + log.trace( "Protocol error: Previous continuous frame sequence not completed." ); throw new InvalidDataException( CloseFrame.PROTOCOL_ERROR, "Continuous frame sequence was not started." ); + } byteBufferList.add( frame.getPayloadData() ); - if( current_continuous_frame.getOpcode() == Framedata.Opcode.TEXT ) { + if( current_continuous_frame.getOpcode() == Opcode.TEXT ) { ((FramedataImpl1) current_continuous_frame).setPayload( getPayloadFromByteBufferList() ); ((FramedataImpl1) current_continuous_frame ).isValid(); try { webSocketImpl.getWebSocketListener().onWebsocketMessage( webSocketImpl, Charsetfunctions.stringUtf8( current_continuous_frame.getPayloadData() ) ); } catch ( RuntimeException e ) { + log.error( "Runtime exception during onWebsocketMessage", e ); webSocketImpl.getWebSocketListener().onWebsocketError( webSocketImpl, e ); } - } else if( current_continuous_frame.getOpcode() == Framedata.Opcode.BINARY ) { + } else if( current_continuous_frame.getOpcode() == Opcode.BINARY ) { ((FramedataImpl1) current_continuous_frame).setPayload( getPayloadFromByteBufferList() ); ((FramedataImpl1) current_continuous_frame ).isValid(); try { webSocketImpl.getWebSocketListener().onWebsocketMessage( webSocketImpl, current_continuous_frame.getPayloadData() ); } catch ( RuntimeException e ) { + log.error( "Runtime exception during onWebsocketMessage", e ); webSocketImpl.getWebSocketListener().onWebsocketError( webSocketImpl, e ); } } current_continuous_frame = null; byteBufferList.clear(); } else if( current_continuous_frame == null ) { + log.error( "Protocol error: Continuous frame sequence was not started." ); throw new InvalidDataException( CloseFrame.PROTOCOL_ERROR, "Continuous frame sequence was not started." ); } //Check if the whole payload is valid utf8, when the opcode indicates a text - if( curop == Framedata.Opcode.TEXT ) { + if( curop == Opcode.TEXT ) { if( !Charsetfunctions.isValidUTF8( frame.getPayloadData() ) ) { + log.error( "Protocol error: Payload is not UTF8" ); throw new InvalidDataException( CloseFrame.NO_UTF8 ); } } //Checking if the current continuous frame contains a correct payload with the other frames combined - if( curop == Framedata.Opcode.CONTINUOUS && current_continuous_frame != null ) { + if( curop == Opcode.CONTINUOUS && current_continuous_frame != null ) { byteBufferList.add( frame.getPayloadData() ); } } else if( current_continuous_frame != null ) { + log.error( "Protocol error: Continuous frame sequence not completed." ); throw new InvalidDataException( CloseFrame.PROTOCOL_ERROR, "Continuous frame sequence not completed." ); - } else if( curop == Framedata.Opcode.TEXT ) { + } else if( curop == Opcode.TEXT ) { try { webSocketImpl.getWebSocketListener().onWebsocketMessage( webSocketImpl, Charsetfunctions.stringUtf8( frame.getPayloadData() ) ); } catch ( RuntimeException e ) { + log.error( "Runtime exception during onWebsocketMessage", e ); webSocketImpl.getWebSocketListener().onWebsocketError( webSocketImpl, e ); } - } else if( curop == Framedata.Opcode.BINARY ) { + } else if( curop == Opcode.BINARY ) { try { webSocketImpl.getWebSocketListener().onWebsocketMessage( webSocketImpl, frame.getPayloadData() ); } catch ( RuntimeException e ) { + log.error( "Runtime exception during onWebsocketMessage", e ); webSocketImpl.getWebSocketListener().onWebsocketError( webSocketImpl, e ); } } else { + log.error( "non control or continious frame expected"); throw new InvalidDataException( CloseFrame.PROTOCOL_ERROR, "non control or continious frame expected" ); } } @Override - public Draft.CloseHandshakeType getCloseHandshakeType() { - return Draft.CloseHandshakeType.TWOWAY; + public CloseHandshakeType getCloseHandshakeType() { + return CloseHandshakeType.TWOWAY; } @Override @@ -765,6 +792,7 @@ private ByteBuffer getPayloadFromByteBufferList() throws LimitExedeedException { totalSize +=buffer.limit(); } if (totalSize > Integer.MAX_VALUE) { + log.trace( "Payloadsize is to big..."); throw new LimitExedeedException( "Payloadsize is to big..." ); } ByteBuffer resultingByteBuffer = ByteBuffer.allocate( (int) totalSize ); @@ -774,10 +802,4 @@ private ByteBuffer getPayloadFromByteBufferList() throws LimitExedeedException { resultingByteBuffer.flip(); return resultingByteBuffer; } - - private static void logDebug(Object object) { - if (WebSocketImpl.DEBUG) { - System.out.println(object); - } - } } diff --git a/src/main/java/org/java_websocket/enums/CloseHandshakeType.java b/src/main/java/org/java_websocket/enums/CloseHandshakeType.java new file mode 100644 index 00000000..77ece10f --- /dev/null +++ b/src/main/java/org/java_websocket/enums/CloseHandshakeType.java @@ -0,0 +1,8 @@ +package org.java_websocket.enums; + +/** + * Enum which represents type of handshake is required for a close + */ +public enum CloseHandshakeType { + NONE, ONEWAY, TWOWAY +} \ No newline at end of file diff --git a/src/main/java/org/java_websocket/enums/HandshakeState.java b/src/main/java/org/java_websocket/enums/HandshakeState.java new file mode 100644 index 00000000..54171830 --- /dev/null +++ b/src/main/java/org/java_websocket/enums/HandshakeState.java @@ -0,0 +1,11 @@ +package org.java_websocket.enums; + +/** + * Enum which represents the states a handshake may be in + */ +public enum HandshakeState { + /** Handshake matched this Draft successfully */ + MATCHED, + /** Handshake is does not match this Draft */ + NOT_MATCHED +} \ No newline at end of file diff --git a/src/main/java/org/java_websocket/enums/Opcode.java b/src/main/java/org/java_websocket/enums/Opcode.java new file mode 100644 index 00000000..76554466 --- /dev/null +++ b/src/main/java/org/java_websocket/enums/Opcode.java @@ -0,0 +1,9 @@ +package org.java_websocket.enums; + +/** + * Enum which contains the different valid opcodes + */ +public enum Opcode { + CONTINUOUS, TEXT, BINARY, PING, PONG, CLOSING + // more to come +} \ No newline at end of file diff --git a/src/main/java/org/java_websocket/enums/ReadyState.java b/src/main/java/org/java_websocket/enums/ReadyState.java new file mode 100644 index 00000000..679732a9 --- /dev/null +++ b/src/main/java/org/java_websocket/enums/ReadyState.java @@ -0,0 +1,8 @@ +package org.java_websocket.enums; + +/** + * Enum which represents the state a websocket may be in + */ +public enum ReadyState { + NOT_YET_CONNECTED, OPEN, CLOSING, CLOSED +} \ No newline at end of file diff --git a/src/main/java/org/java_websocket/enums/Role.java b/src/main/java/org/java_websocket/enums/Role.java new file mode 100644 index 00000000..acef4537 --- /dev/null +++ b/src/main/java/org/java_websocket/enums/Role.java @@ -0,0 +1,8 @@ +package org.java_websocket.enums; + +/** + * Enum which represents the states a websocket may be in + */ +public enum Role { + CLIENT, SERVER +} \ No newline at end of file diff --git a/src/main/java/org/java_websocket/client/AbstractClientProxyChannel.java b/src/main/java/org/java_websocket/enums/package-info.java similarity index 53% rename from src/main/java/org/java_websocket/client/AbstractClientProxyChannel.java rename to src/main/java/org/java_websocket/enums/package-info.java index 752d70eb..3e59f195 100644 --- a/src/main/java/org/java_websocket/client/AbstractClientProxyChannel.java +++ b/src/main/java/org/java_websocket/enums/package-info.java @@ -23,45 +23,7 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -package org.java_websocket.client; - -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.nio.ByteBuffer; -import java.nio.channels.ByteChannel; - -import org.java_websocket.AbstractWrappedByteChannel; - -@Deprecated -public abstract class AbstractClientProxyChannel extends AbstractWrappedByteChannel { - protected final ByteBuffer proxyHandshake; - - - /** - * @param towrap - * The channel to the proxy server - **/ - @Deprecated - public AbstractClientProxyChannel( ByteChannel towrap ) { - super( towrap ); - try { - proxyHandshake = ByteBuffer.wrap( buildHandShake().getBytes( "ASCII" ) ); - } catch ( UnsupportedEncodingException e ) { - throw new RuntimeException( e ); - } - } - - @Override - @Deprecated - public int write( ByteBuffer src ) throws IOException { - if( !proxyHandshake.hasRemaining() ) { - return super.write( src ); - } else { - return super.write( proxyHandshake ); - } - } - - @Deprecated - public abstract String buildHandShake(); - -} +/** + * This package encapsulates all enums. + */ +package org.java_websocket.enums; \ No newline at end of file diff --git a/src/main/java/org/java_websocket/exceptions/WebsocketNotConnectedException.java b/src/main/java/org/java_websocket/exceptions/WebsocketNotConnectedException.java index 1061bbd3..f04a360b 100644 --- a/src/main/java/org/java_websocket/exceptions/WebsocketNotConnectedException.java +++ b/src/main/java/org/java_websocket/exceptions/WebsocketNotConnectedException.java @@ -26,7 +26,7 @@ package org.java_websocket.exceptions; /** - * exception which indicates the websocket is not yet connected (READYSTATE.OPEN) + * exception which indicates the websocket is not yet connected (ReadyState.OPEN) */ public class WebsocketNotConnectedException extends RuntimeException { diff --git a/src/main/java/org/java_websocket/extensions/DefaultExtension.java b/src/main/java/org/java_websocket/extensions/DefaultExtension.java index 0e9893de..434166d3 100644 --- a/src/main/java/org/java_websocket/extensions/DefaultExtension.java +++ b/src/main/java/org/java_websocket/extensions/DefaultExtension.java @@ -96,8 +96,6 @@ public int hashCode() { @Override public boolean equals( Object o ) { - if( this == o ) return true; - if( o == null ) return false; - return getClass() == o.getClass(); + return this == o || o != null && getClass() == o.getClass(); } } diff --git a/src/main/java/org/java_websocket/framing/BinaryFrame.java b/src/main/java/org/java_websocket/framing/BinaryFrame.java index e2056861..64f6ae15 100644 --- a/src/main/java/org/java_websocket/framing/BinaryFrame.java +++ b/src/main/java/org/java_websocket/framing/BinaryFrame.java @@ -25,6 +25,8 @@ package org.java_websocket.framing; +import org.java_websocket.enums.Opcode; + /** * Class to represent a binary frame */ diff --git a/src/main/java/org/java_websocket/framing/CloseFrame.java b/src/main/java/org/java_websocket/framing/CloseFrame.java index 8fbadfe1..05206bba 100644 --- a/src/main/java/org/java_websocket/framing/CloseFrame.java +++ b/src/main/java/org/java_websocket/framing/CloseFrame.java @@ -25,6 +25,7 @@ package org.java_websocket.framing; +import org.java_websocket.enums.Opcode; import org.java_websocket.exceptions.InvalidDataException; import org.java_websocket.exceptions.InvalidFrameException; import org.java_websocket.util.ByteBufferUtils; @@ -234,7 +235,7 @@ public String toString() { @Override public void isValid() throws InvalidDataException { super.isValid(); - if (code == CloseFrame.NO_UTF8 && reason == null) { + if (code == CloseFrame.NO_UTF8 && reason.isEmpty()) { throw new InvalidDataException( CloseFrame.NO_UTF8, "Received text is no valid utf8 string!"); } if (code == CloseFrame.NOCODE && 0 < reason.length()) { diff --git a/src/main/java/org/java_websocket/framing/ContinuousFrame.java b/src/main/java/org/java_websocket/framing/ContinuousFrame.java index f5082f09..c0dea5c9 100644 --- a/src/main/java/org/java_websocket/framing/ContinuousFrame.java +++ b/src/main/java/org/java_websocket/framing/ContinuousFrame.java @@ -25,6 +25,8 @@ package org.java_websocket.framing; +import org.java_websocket.enums.Opcode; + /** * Class to represent a continuous frame */ diff --git a/src/main/java/org/java_websocket/framing/ControlFrame.java b/src/main/java/org/java_websocket/framing/ControlFrame.java index f7b161d6..7cf38da4 100644 --- a/src/main/java/org/java_websocket/framing/ControlFrame.java +++ b/src/main/java/org/java_websocket/framing/ControlFrame.java @@ -25,6 +25,7 @@ package org.java_websocket.framing; +import org.java_websocket.enums.Opcode; import org.java_websocket.exceptions.InvalidDataException; import org.java_websocket.exceptions.InvalidFrameException; diff --git a/src/main/java/org/java_websocket/framing/DataFrame.java b/src/main/java/org/java_websocket/framing/DataFrame.java index 428b23b1..8bebac15 100644 --- a/src/main/java/org/java_websocket/framing/DataFrame.java +++ b/src/main/java/org/java_websocket/framing/DataFrame.java @@ -25,6 +25,7 @@ package org.java_websocket.framing; +import org.java_websocket.enums.Opcode; import org.java_websocket.exceptions.InvalidDataException; /** diff --git a/src/main/java/org/java_websocket/framing/Framedata.java b/src/main/java/org/java_websocket/framing/Framedata.java index 31d02ee9..aa80541b 100644 --- a/src/main/java/org/java_websocket/framing/Framedata.java +++ b/src/main/java/org/java_websocket/framing/Framedata.java @@ -25,19 +25,13 @@ package org.java_websocket.framing; +import org.java_websocket.enums.Opcode; import java.nio.ByteBuffer; /** * The interface for the frame */ public interface Framedata { - /** - * Enum which contains the different valid opcodes - */ - enum Opcode { - CONTINUOUS, TEXT, BINARY, PING, PONG, CLOSING - // more to come - } /** * Indicates that this is the final fragment in a message. The first fragment MAY also be the final fragment. diff --git a/src/main/java/org/java_websocket/framing/FramedataImpl1.java b/src/main/java/org/java_websocket/framing/FramedataImpl1.java index 2560d16d..d225849c 100644 --- a/src/main/java/org/java_websocket/framing/FramedataImpl1.java +++ b/src/main/java/org/java_websocket/framing/FramedataImpl1.java @@ -25,6 +25,7 @@ package org.java_websocket.framing; +import org.java_websocket.enums.Opcode; import org.java_websocket.exceptions.InvalidDataException; import org.java_websocket.util.ByteBufferUtils; diff --git a/src/main/java/org/java_websocket/framing/PingFrame.java b/src/main/java/org/java_websocket/framing/PingFrame.java index 3cf6b6ed..e011420a 100644 --- a/src/main/java/org/java_websocket/framing/PingFrame.java +++ b/src/main/java/org/java_websocket/framing/PingFrame.java @@ -25,6 +25,8 @@ package org.java_websocket.framing; +import org.java_websocket.enums.Opcode; + /** * Class to represent a ping frame */ diff --git a/src/main/java/org/java_websocket/framing/PongFrame.java b/src/main/java/org/java_websocket/framing/PongFrame.java index d86c73ed..79b56edc 100644 --- a/src/main/java/org/java_websocket/framing/PongFrame.java +++ b/src/main/java/org/java_websocket/framing/PongFrame.java @@ -25,6 +25,8 @@ package org.java_websocket.framing; +import org.java_websocket.enums.Opcode; + /** * Class to represent a pong frame */ diff --git a/src/main/java/org/java_websocket/framing/TextFrame.java b/src/main/java/org/java_websocket/framing/TextFrame.java index e9a73e95..6aad2ad0 100644 --- a/src/main/java/org/java_websocket/framing/TextFrame.java +++ b/src/main/java/org/java_websocket/framing/TextFrame.java @@ -25,6 +25,7 @@ package org.java_websocket.framing; +import org.java_websocket.enums.Opcode; import org.java_websocket.exceptions.InvalidDataException; import org.java_websocket.util.Charsetfunctions; diff --git a/src/main/java/org/java_websocket/protocols/Protocol.java b/src/main/java/org/java_websocket/protocols/Protocol.java index 626c7167..690aa6e3 100644 --- a/src/main/java/org/java_websocket/protocols/Protocol.java +++ b/src/main/java/org/java_websocket/protocols/Protocol.java @@ -25,6 +25,8 @@ package org.java_websocket.protocols; +import java.util.regex.Pattern; + /** * Class which represents the protocol used as Sec-WebSocket-Protocol * @@ -32,6 +34,9 @@ */ public class Protocol implements IProtocol { + private static final Pattern patternSpace = Pattern.compile(" "); + private static final Pattern patternComma = Pattern.compile(","); + /** * Attribute for the provided protocol */ @@ -51,8 +56,8 @@ public Protocol( String providedProtocol ) { @Override public boolean acceptProvidedProtocol( String inputProtocolHeader ) { - String protocolHeader = inputProtocolHeader.replaceAll( " ", "" ); - String[] headers = protocolHeader.split( "," ); + String protocolHeader = patternSpace.matcher(inputProtocolHeader).replaceAll(""); + String[] headers = patternComma.split(protocolHeader); for( String header : headers ) { if( providedProtocol.equals( header ) ) { return true; diff --git a/src/main/java/org/java_websocket/server/WebSocketServer.java b/src/main/java/org/java_websocket/server/WebSocketServer.java index 39c944c2..21182aac 100644 --- a/src/main/java/org/java_websocket/server/WebSocketServer.java +++ b/src/main/java/org/java_websocket/server/WebSocketServer.java @@ -53,6 +53,8 @@ import org.java_websocket.handshake.ClientHandshake; import org.java_websocket.handshake.Handshakedata; import org.java_websocket.handshake.ServerHandshakeBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * WebSocketServer is an abstract class that only takes care of the @@ -62,6 +64,13 @@ */ public abstract class WebSocketServer extends AbstractWebSocket implements Runnable { + /** + * Logger instance + * + * @since 1.4.0 + */ + private static final Logger log = LoggerFactory.getLogger(WebSocketServer.class); + public static int DECODERS = Runtime.getRuntime().availableProcessors(); /** @@ -263,21 +272,6 @@ public void stop() throws IOException , InterruptedException { stop( 0 ); } - /** - * PLEASE use the method getConnections() in the future! - * - * Returns a WebSocket[] of currently connected clients. - * Its iterators will be failfast and its not judicious - * to modify it. - * - * @return The currently connected clients. - * - */ - @Deprecated - public Collection connections() { - return getConnections(); - } - /** * Returns all currently connected clients. * This collection does not allow any modification e.g. removing a client. @@ -477,6 +471,7 @@ public void run() { try { selector.close(); } catch ( IOException e ) { + log.error( "IOException during selector.close", e ); onError( null, e ); } } @@ -484,6 +479,7 @@ public void run() { try { server.close(); } catch ( IOException e ) { + log.error( "IOException during server.close", e ); onError( null, e ); } } @@ -536,13 +532,13 @@ private void handleIOException( SelectionKey key, WebSocket conn, IOException ex } catch ( IOException e ) { // there is nothing that must be done here } - if( WebSocketImpl.DEBUG ) - System.out.println("Connection closed because of " + ex); + log.trace("Connection closed because of exception",ex); } } } private void handleFatal( WebSocket conn, Exception e ) { + log.error( "Shutdown due to fatal error", e ); onError( conn, e ); //Shutting down WebSocketWorkers, see #222 if( decoders != null ) { @@ -556,24 +552,20 @@ private void handleFatal( WebSocket conn, Exception e ) { try { stop(); } catch ( IOException e1 ) { + log.error( "Error during shutdown", e1 ); onError( null, e1 ); } catch ( InterruptedException e1 ) { Thread.currentThread().interrupt(); + log.error( "Interrupt during stop", e ); onError( null, e1 ); } } - @Override public final void onWebsocketMessage( WebSocket conn, String message ) { onMessage( conn, message ); } - @Override - @Deprecated - public/*final*/void onWebsocketMessageFragment( WebSocket conn, Framedata frame ) {// onFragment should be overloaded instead - onFragment( conn, frame ); - } @Override public final void onWebsocketMessage( WebSocket conn, ByteBuffer blob ) { @@ -619,9 +611,7 @@ protected boolean removeConnection( WebSocket ws ) { removed = this.connections.remove( ws ); } else { //Don't throw an assert error if the ws is not in the list. e.g. when the other endpoint did not send any handshake. see #512 - if (WebSocketImpl.DEBUG) { - System.out.println("Removing connection which is not in the connections collection! Possible no handshake recieved! " + ws); - } + log.trace("Removing connection which is not in the connections collection! Possible no handshake recieved! {}", ws); } } if( isclosed.get() && connections.size() == 0 ) { @@ -785,17 +775,6 @@ public InetSocketAddress getRemoteSocketAddress( WebSocket conn ) { public void onMessage( WebSocket conn, ByteBuffer message ) { } - /** - * Callback for fragmented frames - * @see WebSocket#sendFragmentedFrame(org.java_websocket.framing.Framedata.Opcode, ByteBuffer, boolean) - * @param conn - * The WebSocket instance this event is occurring on. - * @param fragment The fragmented frame - */ - @Deprecated - public void onFragment( WebSocket conn, Framedata fragment ) { - } - /** * Send a text to all connected endpoints * @param text the text to send to the endpoints @@ -841,23 +820,7 @@ public void broadcast(ByteBuffer data, Collection clients) { if (data == null || clients == null) { throw new IllegalArgumentException(); } - Map> draftFrames = new HashMap>(); - synchronized( clients ) { - for( WebSocket client : clients ) { - if( client != null ) { - Draft draft = client.getDraft(); - if( !draftFrames.containsKey( draft ) ) { - List frames = draft.createFrames( data, false ); - draftFrames.put( draft, frames ); - } - try { - client.sendFrame( draftFrames.get( draft ) ); - } catch ( WebsocketNotConnectedException e ) { - //Ignore this exception in this case - } - } - } - } + doBroadcast(data, clients); } /** @@ -869,21 +832,47 @@ public void broadcast(String text, Collection clients) { if (text == null || clients == null) { throw new IllegalArgumentException(); } + doBroadcast(text, clients); + } + + /** + * Private method to cache all the frames to improve memory footprint and conversion time + * @param data the data to broadcast + * @param clients the clients to send the message to + */ + private void doBroadcast(Object data, Collection clients) { + String sData = null; + if (data instanceof String) { + sData = (String)data; + } + ByteBuffer bData = null; + if (data instanceof ByteBuffer) { + bData = (ByteBuffer)data; + } + if (sData == null && bData == null) { + return; + } Map> draftFrames = new HashMap>(); - synchronized( clients ) { - for( WebSocket client : clients ) { - if( client != null ) { - Draft draft = client.getDraft(); - if( !draftFrames.containsKey( draft ) ) { - List frames = draft.createFrames( text, false ); - draftFrames.put( draft, frames ); + for( WebSocket client : clients ) { + if( client != null ) { + Draft draft = client.getDraft(); + if( !draftFrames.containsKey( draft ) ) { + List frames = null; + if (sData != null) { + frames = draft.createFrames( sData, false ); } - try { - client.sendFrame( draftFrames.get( draft ) ); - } catch ( WebsocketNotConnectedException e ) { - //Ignore this exception in this case + if (bData != null) { + frames = draft.createFrames( bData, false ); + } + if (frames != null) { + draftFrames.put(draft, frames); } } + try { + client.sendFrame( draftFrames.get( draft ) ); + } catch ( WebsocketNotConnectedException e ) { + //Ignore this exception in this case + } } } } @@ -901,9 +890,7 @@ public WebSocketWorker() { setUncaughtExceptionHandler( new UncaughtExceptionHandler() { @Override public void uncaughtException( Thread t, Throwable e ) { - System.err.print("Uncaught exception in thread \"" - + t.getName() + "\":"); - e.printStackTrace(System.err); + log.error("Uncaught exception in thread {}: {}", t.getName(), e); } } ); } @@ -924,8 +911,7 @@ public void run() { try { ws.decode( buf ); } catch(Exception e){ - System.err.println("Error while reading from remote connection: " + e); - e.printStackTrace(); + log.error("Error while reading from remote connection", e); } finally { @@ -933,6 +919,7 @@ public void run() { } } } catch ( InterruptedException e ) { + Thread.currentThread().interrupt(); } catch ( RuntimeException e ) { handleFatal( ws, e ); } diff --git a/src/main/java/org/java_websocket/util/Base64.java b/src/main/java/org/java_websocket/util/Base64.java index 4373e05e..6745d026 100644 --- a/src/main/java/org/java_websocket/util/Base64.java +++ b/src/main/java/org/java_websocket/util/Base64.java @@ -69,8 +69,6 @@ *
  • v2.3.6 - Fixed bug when breaking lines and the final byte of the encoded * string ended in the last column; the buffer was not properly shrunk and * contained an extra (null) byte that made it into the string.
  • - *
  • v2.3.5 - Fixed bug in {@link #encodeFromFile} where estimated buffer size - * was wrong for files of size 31, 34, and 37 bytes.
  • *
  • v2.3.4 - Fixed bug when working with gzipped streams whereby flushing * the Base64.OutputStream closed the Base64 encoding (by padding with equals * signs) too soon. Also added an option to suppress the automatic decoding @@ -181,19 +179,10 @@ public class Base64 /** Specify encoding in first bit. Value is one. */ public final static int ENCODE = 1; - - - /** Specify decoding in first bit. Value is zero. */ - public final static int DECODE = 0; - /** Specify that data should be gzip-compressed in second bit. Value is two. */ public final static int GZIP = 2; - /** Specify that gzipped data should not be automatically gunzipped. */ - public final static int DONT_GUNZIP = 4; - - /** Do break lines when encoding. Value is 8. */ public final static int DO_BREAK_LINES = 8; @@ -235,7 +224,6 @@ public class Base64 private final static byte WHITE_SPACE_ENC = -5; // Indicates white space in encoding - private final static byte EQUALS_SIGN_ENC = -1; // Indicates equals sign in encoding /* ******** S T A N D A R D B A S E 6 4 A L P H A B E T ******** */ @@ -692,9 +680,9 @@ public static byte[] encodeBytesToBytes( byte[] source, int off, int len, int op throw e; } // end catch finally { - try{ gzos.close(); } catch( Exception e ){} - try{ b64os.close(); } catch( Exception e ){} - try{ baos.close(); } catch( Exception e ){} + try{ if (gzos != null) gzos.close(); } catch( Exception e ){} + try{ if (b64os != null) b64os.close(); } catch( Exception e ){} + try{ if (baos != null) baos.close(); } catch( Exception e ){} } // end finally return baos.toByteArray(); @@ -864,514 +852,8 @@ else if( source[ srcOffset + 3 ] == EQUALS_SIGN ) { } } // end decodeToBytes - /** - * Low-level access to decoding ASCII characters in - * the form of a byte array. Ignores GUNZIP option, if - * it's set. This is not generally a recommended method, - * although it is used internally as part of the decoding process. - * Special case: if len = 0, an empty array is returned. Still, - * if you need more speed and reduced memory footprint (and aren't - * gzipping), consider this method. - * - * @param source The Base64 encoded data - * @return decoded data - * @throws java.io.IOException If bogus characters exist in source data - * @since 2.3.1 - */ - public static byte[] decode( byte[] source ) throws java.io.IOException { - return decode( source, 0, source.length, Base64.NO_OPTIONS ); - } - - /** - * Low-level access to decoding ASCII characters in - * the form of a byte array. Ignores GUNZIP option, if - * it's set. This is not generally a recommended method, - * although it is used internally as part of the decoding process. - * Special case: if len = 0, an empty array is returned. Still, - * if you need more speed and reduced memory footprint (and aren't - * gzipping), consider this method. - * - * @param source The Base64 encoded data - * @param off The offset of where to begin decoding - * @param len The length of characters to decode - * @param options Can specify options such as alphabet type to use - * @return decoded data - * @throws java.io.IOException If bogus characters exist in source data - * @since 1.3 - */ - public static byte[] decode( byte[] source, int off, int len, int options ) - throws java.io.IOException { - - // Lots of error checking and exception throwing - if( source == null ){ - throw new IllegalArgumentException( "Cannot decode null source array." ); - } // end if - if( off < 0 || off + len > source.length ){ - throw new IllegalArgumentException( String.format( - "Source array with length %d cannot have offset of %d and process %d bytes.", source.length, off, len ) ); - } // end if - - if( len == 0 ){ - return new byte[0]; - }else if( len < 4 ){ - throw new IllegalArgumentException( - "Base64-encoded string must have at least four characters, but length specified was " + len ); - } // end if - - byte[] DECODABET = getDecodabet( options ); - - int len34 = len * 3 / 4; // Estimate on array size - byte[] outBuff = new byte[ len34 ]; // Upper limit on size of output - int outBuffPosn = 0; // Keep track of where we're writing - - byte[] b4 = new byte[4]; // Four byte buffer from source, eliminating white space - int b4Posn = 0; // Keep track of four byte input buffer - int i; // Source array counter - byte sbiDecode; // Special value from DECODABET - - for( i = off; i < off+len; i++ ) { // Loop through source - - sbiDecode = DECODABET[ source[i]&0xFF ]; - - // White space, Equals sign, or legit Base64 character - // Note the values such as -5 and -9 in the - // DECODABETs at the top of the file. - if( sbiDecode >= WHITE_SPACE_ENC ) { - if( sbiDecode >= EQUALS_SIGN_ENC ) { - b4[ b4Posn++ ] = source[i]; // Save non-whitespace - if( b4Posn > 3 ) { // Time to decode? - outBuffPosn += decode4to3( b4, 0, outBuff, outBuffPosn, options ); - b4Posn = 0; - - // If that was the equals sign, break out of 'for' loop - if( source[i] == EQUALS_SIGN ) { - break; - } // end if: equals sign - } // end if: quartet built - } // end if: equals sign or better - } // end if: white space, equals sign or better - else { - // There's a bad input character in the Base64 stream. - throw new java.io.IOException( String.format( - "Bad Base64 input character decimal %d in array position %d", ((int)source[i])&0xFF, i ) ); - } // end else: - } // each input character - - byte[] out = new byte[ outBuffPosn ]; - System.arraycopy( outBuff, 0, out, 0, outBuffPosn ); - return out; - } // end decode - - - - /** - * Decodes data from Base64 notation, automatically - * detecting gzip-compressed data and decompressing it. - * - * @param s the string to decode - * @return the decoded data - * @throws java.io.IOException If there is a problem - * @since 1.4 - */ - public static byte[] decode( String s ) throws java.io.IOException { - return decode( s, NO_OPTIONS ); - } - - /** - * Decodes data from Base64 notation, automatically - * detecting gzip-compressed data and decompressing it. - * - * @param s the string to decode - * @param options encode options such as URL_SAFE - * @return the decoded data - * @throws java.io.IOException if there is an error - * @throws IllegalArgumentException if s is null - * @since 1.4 - */ - public static byte[] decode( String s, int options ) throws java.io.IOException { - - if( s == null ){ - throw new IllegalArgumentException( "Input string was null." ); - } // end if - - byte[] bytes; - try { - bytes = s.getBytes( PREFERRED_ENCODING ); - } // end try - catch( java.io.UnsupportedEncodingException uee ) { - bytes = s.getBytes(); - } // end catch - // - - // Decode - bytes = decode( bytes, 0, bytes.length, options ); - - // Check to see if it's gzip-compressed - // GZIP Magic Two-Byte Number: 0x8b1f (35615) - boolean dontGunzip = (options & DONT_GUNZIP) != 0; - if( (bytes != null) && (bytes.length >= 4) && (!dontGunzip) ) { - - int head = ((int)bytes[0] & 0xff) | ((bytes[1] << 8) & 0xff00); - if( java.util.zip.GZIPInputStream.GZIP_MAGIC == head ) { - java.io.ByteArrayInputStream bais = null; - java.util.zip.GZIPInputStream gzis = null; - java.io.ByteArrayOutputStream baos = null; - byte[] buffer = new byte[2048]; - int length; - - try { - baos = new java.io.ByteArrayOutputStream(); - bais = new java.io.ByteArrayInputStream( bytes ); - gzis = new java.util.zip.GZIPInputStream( bais ); - - while( ( length = gzis.read( buffer ) ) >= 0 ) { - baos.write(buffer,0,length); - } // end while: reading input - - // No error? Get new bytes. - bytes = baos.toByteArray(); - - } // end try - catch( java.io.IOException e ) { - e.printStackTrace(); - // Just return originally-decoded bytes - } // end catch - finally { - try{ baos.close(); } catch( Exception e ){} - try{ gzis.close(); } catch( Exception e ){} - try{ bais.close(); } catch( Exception e ){} - } // end finally - - } // end if: gzipped - } // end if: bytes.length >= 2 - - return bytes; - } // end decode - - /** - * Convenience method for reading a base64-encoded - * file and decoding it. - * - *

    As of v 2.3, if there is a error, - * the method will throw an java.io.IOException. This is new to v2.3! - * In earlier versions, it just returned false, but - * in retrospect that's a pretty poor way to handle it.

    - * - * @param filename Filename for reading encoded data - * @return decoded byte array - * @throws java.io.IOException if there is an error - * @since 2.1 - */ - public static byte[] decodeFromFile( String filename ) - throws java.io.IOException { - - byte[] decodedData; - Base64.InputStream bis = null; - try - { - // Set up some useful variables - java.io.File file = new java.io.File( filename ); - byte[] buffer; - int length = 0; - int numBytes; - - // Check for size of file - if( file.length() > Integer.MAX_VALUE ) - { - throw new java.io.IOException( "File is too big for this convenience method (" + file.length() + " bytes)." ); - } // end if: file too big for int index - buffer = new byte[ (int)file.length() ]; - - // Open a stream - bis = new Base64.InputStream( - new java.io.BufferedInputStream( - new java.io.FileInputStream( file ) ), Base64.DECODE ); - - // Read until done - while( ( numBytes = bis.read( buffer, length, 4096 ) ) >= 0 ) { - length += numBytes; - } // end while - - // Save in a variable to return - decodedData = new byte[ length ]; - System.arraycopy( buffer, 0, decodedData, 0, length ); - - } // end try - catch( java.io.IOException e ) { - throw e; // Catch and release to execute finally{} - } // end catch: java.io.IOException - finally { - try{ bis.close(); } catch( Exception e) {} - } // end finally - - return decodedData; - } // end decodeFromFile - - - - /** - * Convenience method for reading a binary file - * and base64-encoding it. - * - *

    As of v 2.3, if there is a error, - * the method will throw an java.io.IOException. This is new to v2.3! - * In earlier versions, it just returned false, but - * in retrospect that's a pretty poor way to handle it.

    - * - * @param filename Filename for reading binary data - * @return base64-encoded string - * @throws java.io.IOException if there is an error - * @since 2.1 - */ - public static String encodeFromFile( String filename ) - throws java.io.IOException { - - String encodedData; - Base64.InputStream bis = null; - try - { - // Set up some useful variables - java.io.File file = new java.io.File( filename ); - byte[] buffer = new byte[ Math.max((int)(file.length() * 1.4+1),40) ]; // Need max() for math on small files (v2.2.1); Need +1 for a few corner cases (v2.3.5) - int length = 0; - int numBytes; - - // Open a stream - bis = new Base64.InputStream( - new java.io.BufferedInputStream( - new java.io.FileInputStream( file ) ), Base64.ENCODE ); - - // Read until done - while( ( numBytes = bis.read( buffer, length, 4096 ) ) >= 0 ) { - length += numBytes; - } // end while - - // Save in a variable to return - encodedData = new String( buffer, 0, length, Base64.PREFERRED_ENCODING ); - - } // end try - catch( java.io.IOException e ) { - throw e; // Catch and release to execute finally{} - } // end catch: java.io.IOException - finally { - try{ bis.close(); } catch( Exception e) {} - } // end finally - - return encodedData; - } // end encodeFromFile - - /** - * A {@link Base64.InputStream} will read data from another - * java.io.InputStream, given in the constructor, - * and encode/decode to/from Base64 notation on the fly. - * - * @see Base64 - * @since 1.3 - */ - public static class InputStream extends java.io.FilterInputStream { - - private boolean encode; // Encoding or decoding - private int position; // Current position in the buffer - private byte[] buffer; // Small buffer holding converted data - private int bufferLength; // Length of buffer (3 or 4) - private int numSigBytes; // Number of meaningful bytes in the buffer - private int lineLength; - private boolean breakLines; // Break lines at less than 80 characters - private int options; // Record options used to create the stream. - private byte[] decodabet; // Local copies to avoid extra method calls - - - /** - * Constructs a {@link Base64.InputStream} in DECODE mode. - * - * @param in the java.io.InputStream from which to read data. - * @since 1.3 - */ - public InputStream( java.io.InputStream in ) { - this( in, DECODE ); - } // end constructor - - - /** - * Constructs a {@link Base64.InputStream} in - * either ENCODE or DECODE mode. - *

    - * Valid options:

    -         *   ENCODE or DECODE: Encode or Decode as data is read.
    -         *   DO_BREAK_LINES: break lines at 76 characters
    -         *     (only meaningful when encoding)
    -         * 
    - *

    - * Example: new Base64.InputStream( in, Base64.DECODE ) - * - * - * @param in the java.io.InputStream from which to read data. - * @param options Specified options - * @see Base64#ENCODE - * @see Base64#DECODE - * @see Base64#DO_BREAK_LINES - * @since 2.0 - */ - public InputStream( java.io.InputStream in, int options ) { - - super( in ); - this.options = options; // Record for later - this.breakLines = (options & DO_BREAK_LINES) > 0; - this.encode = (options & ENCODE) > 0; - this.bufferLength = encode ? 4 : 3; - this.buffer = new byte[ bufferLength ]; - this.position = -1; - this.lineLength = 0; - this.decodabet = getDecodabet(options); - } // end constructor - - /** - * Reads enough of the input stream to convert - * to/from Base64 and returns the next byte. - * - * @return next byte - * @since 1.3 - */ - @Override - public int read() throws java.io.IOException { - - // Do we need to get data? - if( position < 0 ) { - if( encode ) { - byte[] b3 = new byte[3]; - int numBinaryBytes = 0; - for( int i = 0; i < 3; i++ ) { - int b = in.read(); - - // If end of stream, b is -1. - if( b >= 0 ) { - b3[i] = (byte)b; - numBinaryBytes++; - } else { - break; // out of for loop - } // end else: end of stream - - } // end for: each needed input byte - - if( numBinaryBytes > 0 ) { - encode3to4( b3, 0, numBinaryBytes, buffer, 0, options ); - position = 0; - numSigBytes = 4; - } // end if: got data - else { - return -1; // Must be end of stream - } // end else - } // end if: encoding - - // Else decoding - else { - byte[] b4 = new byte[4]; - int i; - for( i = 0; i < 4; i++ ) { - // Read four "meaningful" bytes: - int b; - do{ b = in.read(); } - while( b >= 0 && decodabet[ b & 0x7f ] <= WHITE_SPACE_ENC ); - - if( b < 0 ) { - break; // Reads a -1 if end of stream - } // end if: end of stream - - b4[i] = (byte)b; - } // end for: each needed input byte - - if( i == 4 ) { - numSigBytes = decode4to3( b4, 0, buffer, 0, options ); - position = 0; - } // end if: got four characters - else if( i == 0 ){ - return -1; - } // end else if: also padded correctly - else { - // Must have broken out from above. - throw new java.io.IOException( "Improperly padded Base64 input." ); - } // end - - } // end else: decode - } // end else: get data - - // Got data? - if( position >= 0 ) { - // End of relevant data? - if( /*!encode &&*/ position >= numSigBytes ){ - return -1; - } // end if: got data - - if( encode && breakLines && lineLength >= MAX_LINE_LENGTH ) { - lineLength = 0; - return '\n'; - } // end if - else { - lineLength++; // This isn't important when decoding - // but throwing an extra "if" seems - // just as wasteful. - - int b = buffer[ position++ ]; - - if( position >= bufferLength ) { - position = -1; - } // end if: end - - return b & 0xFF; // This is how you "cast" a byte that's - // intended to be unsigned. - } // end else - } // end if: position >= 0 - - // Else error - else { - throw new java.io.IOException( "Error in Base64 code reading stream." ); - } // end else - } // end read - - - /** - * Calls {@link #read()} repeatedly until the end of stream - * is reached or len bytes are read. - * Returns number of bytes read into array or -1 if - * end of stream is encountered. - * - * @param dest array to hold values - * @param off offset for array - * @param len max number of bytes to read into array - * @return bytes read into array or -1 if end of stream is encountered. - * @since 1.3 - */ - @Override - public int read( byte[] dest, int off, int len ) - throws java.io.IOException { - int i; - int b; - for( i = 0; i < len; i++ ) { - b = read(); - - if( b >= 0 ) { - dest[off + i] = (byte) b; - } - else if( i == 0 ) { - return -1; - } - else { - break; // Out of 'for' loop - } // Out of 'for' loop - } // end for: each byte read - return i; - } // end read - - } // end inner class InputStream - - - - /* ******** I N N E R C L A S S O U T P U T S T R E A M ******** */ - - - /** * A {@link Base64.OutputStream} will write data to another * java.io.OutputStream, given in the constructor, @@ -1419,7 +901,6 @@ public OutputStream( java.io.OutputStream out ) { * @param out the java.io.OutputStream to which data will be written. * @param options Specified options. * @see Base64#ENCODE - * @see Base64#DECODE * @see Base64#DO_BREAK_LINES * @since 1.3 */ @@ -1494,8 +975,6 @@ else if( decodabet[ theByte & 0x7f ] != WHITE_SPACE_ENC ) { } // end else: decoding } // end write - - /** * Calls {@link #write(int)} repeatedly until len * bytes are written. @@ -1519,9 +998,6 @@ public void write( byte[] theBytes, int off, int len ) } // end for: each byte written } // end write - - - /** * Method added by PHIL. [Thanks, PHIL. -Rob] * This pads the buffer without closing the stream. @@ -1540,7 +1016,6 @@ public void flushBase64() throws java.io.IOException { } // end flush - /** * Flushes and closes (I think, in the superclass) the stream. * @@ -1558,37 +1033,5 @@ public void close() throws java.io.IOException { buffer = null; out = null; } // end close - - - - /** - * Suspends encoding of the stream. - * May be helpful if you need to embed a piece of - * base64-encoded data in a stream. - * - * @throws java.io.IOException if there's an error flushing - * @since 1.5.1 - */ - public void suspendEncoding() throws java.io.IOException { - flushBase64(); - this.suspendEncoding = true; - } // end suspendEncoding - - - /** - * Resumes encoding of the stream. - * May be helpful if you need to embed a piece of - * base64-encoded data in a stream. - * - * @since 1.5.1 - */ - public void resumeEncoding() { - this.suspendEncoding = false; - } // end resumeEncoding - - - } // end inner class OutputStream - - } // end class Base64 diff --git a/src/main/java/org/java_websocket/util/Charsetfunctions.java b/src/main/java/org/java_websocket/util/Charsetfunctions.java index a0b3bf89..ead86b84 100644 --- a/src/main/java/org/java_websocket/util/Charsetfunctions.java +++ b/src/main/java/org/java_websocket/util/Charsetfunctions.java @@ -40,11 +40,9 @@ public class Charsetfunctions { /** * Private constructor for real static class */ - private Charsetfunctions() { + private Charsetfunctions() {} - } - - public static CodingErrorAction codingErrorAction = CodingErrorAction.REPORT; + private static final CodingErrorAction codingErrorAction = CodingErrorAction.REPORT; /* * @return UTF-8 encoding in bytes diff --git a/src/test/java/org/java_websocket/drafts/Draft_6455Test.java b/src/test/java/org/java_websocket/drafts/Draft_6455Test.java index 4f07ca35..a3c2bfe8 100644 --- a/src/test/java/org/java_websocket/drafts/Draft_6455Test.java +++ b/src/test/java/org/java_websocket/drafts/Draft_6455Test.java @@ -25,6 +25,8 @@ package org.java_websocket.drafts; +import org.java_websocket.enums.CloseHandshakeType; +import org.java_websocket.enums.HandshakeState; import org.java_websocket.extensions.DefaultExtension; import org.java_websocket.extensions.IExtension; import org.java_websocket.framing.BinaryFrame; @@ -172,7 +174,7 @@ public void testReset() throws Exception { @Test public void testGetCloseHandshakeType() throws Exception { Draft_6455 draft_6455 = new Draft_6455(); - assertEquals( Draft.CloseHandshakeType.TWOWAY, draft_6455.getCloseHandshakeType() ); + assertEquals( CloseHandshakeType.TWOWAY, draft_6455.getCloseHandshakeType() ); } @Test @@ -278,28 +280,28 @@ public void testHashCode() throws Exception { @Test public void acceptHandshakeAsServer() throws Exception { Draft_6455 draft_6455 = new Draft_6455(); - assertEquals( Draft.HandshakeState.MATCHED, draft_6455.acceptHandshakeAsServer( handshakedata ) ); - assertEquals( Draft.HandshakeState.NOT_MATCHED, draft_6455.acceptHandshakeAsServer( handshakedataProtocol ) ); - assertEquals( Draft.HandshakeState.MATCHED, draft_6455.acceptHandshakeAsServer( handshakedataExtension ) ); - assertEquals( Draft.HandshakeState.NOT_MATCHED, draft_6455.acceptHandshakeAsServer( handshakedataProtocolExtension ) ); + assertEquals( HandshakeState.MATCHED, draft_6455.acceptHandshakeAsServer( handshakedata ) ); + assertEquals( HandshakeState.NOT_MATCHED, draft_6455.acceptHandshakeAsServer( handshakedataProtocol ) ); + assertEquals( HandshakeState.MATCHED, draft_6455.acceptHandshakeAsServer( handshakedataExtension ) ); + assertEquals( HandshakeState.NOT_MATCHED, draft_6455.acceptHandshakeAsServer( handshakedataProtocolExtension ) ); draft_6455 = new Draft_6455( new TestExtension() ); - assertEquals( Draft.HandshakeState.MATCHED, draft_6455.acceptHandshakeAsServer( handshakedata ) ); - assertEquals( Draft.HandshakeState.NOT_MATCHED, draft_6455.acceptHandshakeAsServer( handshakedataProtocol ) ); - assertEquals( Draft.HandshakeState.MATCHED, draft_6455.acceptHandshakeAsServer( handshakedataExtension ) ); - assertEquals( Draft.HandshakeState.NOT_MATCHED, draft_6455.acceptHandshakeAsServer( handshakedataProtocolExtension ) ); + assertEquals( HandshakeState.MATCHED, draft_6455.acceptHandshakeAsServer( handshakedata ) ); + assertEquals( HandshakeState.NOT_MATCHED, draft_6455.acceptHandshakeAsServer( handshakedataProtocol ) ); + assertEquals( HandshakeState.MATCHED, draft_6455.acceptHandshakeAsServer( handshakedataExtension ) ); + assertEquals( HandshakeState.NOT_MATCHED, draft_6455.acceptHandshakeAsServer( handshakedataProtocolExtension ) ); draft_6455 = new Draft_6455( Collections.emptyList(), Collections.singletonList( new Protocol( "chat" ) ) ); - assertEquals( Draft.HandshakeState.NOT_MATCHED, draft_6455.acceptHandshakeAsServer( handshakedata ) ); - assertEquals( Draft.HandshakeState.MATCHED, draft_6455.acceptHandshakeAsServer( handshakedataProtocol ) ); - assertEquals( Draft.HandshakeState.NOT_MATCHED, draft_6455.acceptHandshakeAsServer( handshakedataExtension ) ); - assertEquals( Draft.HandshakeState.MATCHED, draft_6455.acceptHandshakeAsServer( handshakedataProtocolExtension ) ); + assertEquals( HandshakeState.NOT_MATCHED, draft_6455.acceptHandshakeAsServer( handshakedata ) ); + assertEquals( HandshakeState.MATCHED, draft_6455.acceptHandshakeAsServer( handshakedataProtocol ) ); + assertEquals( HandshakeState.NOT_MATCHED, draft_6455.acceptHandshakeAsServer( handshakedataExtension ) ); + assertEquals( HandshakeState.MATCHED, draft_6455.acceptHandshakeAsServer( handshakedataProtocolExtension ) ); ArrayList protocols = new ArrayList(); protocols.add( new Protocol( "chat" ) ); protocols.add( new Protocol( "" ) ); draft_6455 = new Draft_6455( Collections.emptyList(), protocols ); - assertEquals( Draft.HandshakeState.MATCHED, draft_6455.acceptHandshakeAsServer( handshakedata ) ); - assertEquals( Draft.HandshakeState.MATCHED, draft_6455.acceptHandshakeAsServer( handshakedataProtocol ) ); - assertEquals( Draft.HandshakeState.MATCHED, draft_6455.acceptHandshakeAsServer( handshakedataExtension ) ); - assertEquals( Draft.HandshakeState.MATCHED, draft_6455.acceptHandshakeAsServer( handshakedataProtocolExtension ) ); + assertEquals( HandshakeState.MATCHED, draft_6455.acceptHandshakeAsServer( handshakedata ) ); + assertEquals( HandshakeState.MATCHED, draft_6455.acceptHandshakeAsServer( handshakedataProtocol ) ); + assertEquals( HandshakeState.MATCHED, draft_6455.acceptHandshakeAsServer( handshakedataExtension ) ); + assertEquals( HandshakeState.MATCHED, draft_6455.acceptHandshakeAsServer( handshakedataProtocolExtension ) ); } @Test @@ -308,31 +310,31 @@ public void acceptHandshakeAsClient() throws Exception { HandshakeImpl1Client request = new HandshakeImpl1Client(); Draft_6455 draft_6455 = new Draft_6455(); response.put( "Upgrade", "websocket" ); - assertEquals( Draft.HandshakeState.NOT_MATCHED, draft_6455.acceptHandshakeAsClient( request, response ) ); + assertEquals( HandshakeState.NOT_MATCHED, draft_6455.acceptHandshakeAsClient( request, response ) ); response.put( "Connection", "upgrade" ); - assertEquals( Draft.HandshakeState.NOT_MATCHED, draft_6455.acceptHandshakeAsClient( request, response ) ); + assertEquals( HandshakeState.NOT_MATCHED, draft_6455.acceptHandshakeAsClient( request, response ) ); response.put( "Sec-WebSocket-Version", "13" ); - assertEquals( Draft.HandshakeState.NOT_MATCHED, draft_6455.acceptHandshakeAsClient( request, response ) ); + assertEquals( HandshakeState.NOT_MATCHED, draft_6455.acceptHandshakeAsClient( request, response ) ); request.put( "Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==" ); - assertEquals( Draft.HandshakeState.NOT_MATCHED, draft_6455.acceptHandshakeAsClient( request, response ) ); + assertEquals( HandshakeState.NOT_MATCHED, draft_6455.acceptHandshakeAsClient( request, response ) ); response.put( "Sec-WebSocket-Accept", "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=" ); - assertEquals( Draft.HandshakeState.MATCHED, draft_6455.acceptHandshakeAsClient( request, response ) ); + assertEquals( HandshakeState.MATCHED, draft_6455.acceptHandshakeAsClient( request, response ) ); response.put( "Sec-WebSocket-Protocol", "chat" ); - assertEquals( Draft.HandshakeState.NOT_MATCHED, draft_6455.acceptHandshakeAsClient( request, response ) ); + assertEquals( HandshakeState.NOT_MATCHED, draft_6455.acceptHandshakeAsClient( request, response ) ); draft_6455 = new Draft_6455( Collections.emptyList(), Collections.singletonList( new Protocol( "chat" ) ) ); - assertEquals( Draft.HandshakeState.MATCHED, draft_6455.acceptHandshakeAsClient( request, response ) ); + assertEquals( HandshakeState.MATCHED, draft_6455.acceptHandshakeAsClient( request, response ) ); ArrayList protocols = new ArrayList(); protocols.add( new Protocol( "" ) ); protocols.add( new Protocol( "chat" ) ); draft_6455 = new Draft_6455( Collections.emptyList(), protocols ); - assertEquals( Draft.HandshakeState.MATCHED, draft_6455.acceptHandshakeAsClient( request, response ) ); + assertEquals( HandshakeState.MATCHED, draft_6455.acceptHandshakeAsClient( request, response ) ); draft_6455 = new Draft_6455(); - assertEquals( Draft.HandshakeState.NOT_MATCHED, draft_6455.acceptHandshakeAsClient( request, response ) ); + assertEquals( HandshakeState.NOT_MATCHED, draft_6455.acceptHandshakeAsClient( request, response ) ); protocols.clear(); protocols.add( new Protocol( "chat3" ) ); protocols.add( new Protocol( "3chat" ) ); draft_6455 = new Draft_6455( Collections.emptyList(), protocols ); - assertEquals( Draft.HandshakeState.NOT_MATCHED, draft_6455.acceptHandshakeAsClient( request, response ) ); + assertEquals( HandshakeState.NOT_MATCHED, draft_6455.acceptHandshakeAsClient( request, response ) ); } @Test diff --git a/src/test/java/org/java_websocket/example/AutobahnClientTest.java b/src/test/java/org/java_websocket/example/AutobahnClientTest.java index eed1565a..ea06fbfe 100644 --- a/src/test/java/org/java_websocket/example/AutobahnClientTest.java +++ b/src/test/java/org/java_websocket/example/AutobahnClientTest.java @@ -83,11 +83,9 @@ public static void main( String[] args ) { if( nextline != null ) { line = nextline; nextline = null; - WebSocketImpl.DEBUG = false; } else { System.out.print( ">" ); line = sysin.readLine(); - WebSocketImpl.DEBUG = true; } if( line.equals( "l" ) ) { line = perviousline; @@ -112,7 +110,6 @@ public static void main( String[] args ) { uri = URI.create( serverlocation + "/runCase?case=" + spl[ 1 ] + "&agent=" + clientname ); } else if( line.startsWith( "u" ) ) { - WebSocketImpl.DEBUG = false; uri = URI.create( serverlocation + "/updateReports?agent=" + clientname ); } else if( line.startsWith( "d" ) ) { try { @@ -180,11 +177,4 @@ public void onClose( int code, String reason, boolean remote ) { System.out.println( "Closed: " + code + " " + reason ); } - @Override - public void onWebsocketMessageFragment( WebSocket conn, Framedata frame ) { - FramedataImpl1 builder = (FramedataImpl1) frame; - builder.setTransferemasked( true ); - getConnection().sendFrame( frame ); - } - } diff --git a/src/test/java/org/java_websocket/example/AutobahnSSLServerTest.java b/src/test/java/org/java_websocket/example/AutobahnSSLServerTest.java index 1f1d2706..c62cd8c1 100644 --- a/src/test/java/org/java_websocket/example/AutobahnSSLServerTest.java +++ b/src/test/java/org/java_websocket/example/AutobahnSSLServerTest.java @@ -90,15 +90,7 @@ public void onMessage( WebSocket conn, ByteBuffer blob ) { conn.send( blob ); } - @Override - public void onWebsocketMessageFragment( WebSocket conn, Framedata frame ) { - FramedataImpl1 builder = ( FramedataImpl1 ) frame; - builder.setTransferemasked( false ); - conn.sendFrame( frame ); - } - public static void main( String[] args ) throws UnknownHostException { - WebSocketImpl.DEBUG = false; int port; try { port = new Integer( args[0] ); diff --git a/src/test/java/org/java_websocket/example/AutobahnServerTest.java b/src/test/java/org/java_websocket/example/AutobahnServerTest.java index 0d25bd63..5cc82f4e 100644 --- a/src/test/java/org/java_websocket/example/AutobahnServerTest.java +++ b/src/test/java/org/java_websocket/example/AutobahnServerTest.java @@ -26,28 +26,20 @@ package org.java_websocket.example; import org.java_websocket.WebSocket; -import org.java_websocket.WebSocketImpl; import org.java_websocket.drafts.Draft; import org.java_websocket.drafts.Draft_6455; -import org.java_websocket.framing.Framedata; -import org.java_websocket.framing.FramedataImpl1; import org.java_websocket.handshake.ClientHandshake; -import org.java_websocket.server.DefaultSSLWebSocketServerFactory; import org.java_websocket.server.WebSocketServer; -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManagerFactory; -import java.io.File; -import java.io.FileInputStream; import java.net.InetSocketAddress; import java.net.UnknownHostException; import java.nio.ByteBuffer; -import java.security.KeyStore; import java.util.Collections; public class AutobahnServerTest extends WebSocketServer { + private static int counter = 0; + public AutobahnServerTest( int port, Draft d ) throws UnknownHostException { super( new InetSocketAddress( port ), Collections.singletonList( d ) ); } @@ -82,10 +74,6 @@ public void onStart() { public void onMessage( WebSocket conn, String message ) { conn.send( message ); } - @Override - public void onFragment( WebSocket conn, Framedata fragment ) { - System.out.println( "received fragment: " + fragment ); - } @Override public void onMessage( WebSocket conn, ByteBuffer blob ) { @@ -93,7 +81,6 @@ public void onMessage( WebSocket conn, ByteBuffer blob ) { } public static void main( String[] args ) throws UnknownHostException { - WebSocketImpl.DEBUG = false; int port; try { port = new Integer( args[0] ); diff --git a/src/test/java/org/java_websocket/framing/BinaryFrameTest.java b/src/test/java/org/java_websocket/framing/BinaryFrameTest.java index c3f8fa15..deab1e5b 100644 --- a/src/test/java/org/java_websocket/framing/BinaryFrameTest.java +++ b/src/test/java/org/java_websocket/framing/BinaryFrameTest.java @@ -25,6 +25,7 @@ package org.java_websocket.framing; +import org.java_websocket.enums.Opcode; import org.java_websocket.exceptions.InvalidDataException; import org.junit.Test; @@ -39,7 +40,7 @@ public class BinaryFrameTest { @Test public void testConstructor() { BinaryFrame frame = new BinaryFrame(); - assertEquals("Opcode must be equal", Framedata.Opcode.BINARY , frame.getOpcode()); + assertEquals("Opcode must be equal", Opcode.BINARY , frame.getOpcode()); assertEquals("Fin must be set", true , frame.isFin()); assertEquals("TransferedMask must not be set", false , frame.getTransfereMasked()); assertEquals("Payload must be empty", 0 , frame.getPayloadData().capacity()); diff --git a/src/test/java/org/java_websocket/framing/CloseFrameTest.java b/src/test/java/org/java_websocket/framing/CloseFrameTest.java index 24553bf8..fc9eee80 100644 --- a/src/test/java/org/java_websocket/framing/CloseFrameTest.java +++ b/src/test/java/org/java_websocket/framing/CloseFrameTest.java @@ -25,6 +25,7 @@ package org.java_websocket.framing; +import org.java_websocket.enums.Opcode; import org.java_websocket.exceptions.InvalidDataException; import org.junit.Test; @@ -39,7 +40,7 @@ public class CloseFrameTest { @Test public void testConstructor() { CloseFrame frame = new CloseFrame(); - assertEquals("Opcode must be equal", Framedata.Opcode.CLOSING, frame.getOpcode()); + assertEquals("Opcode must be equal", Opcode.CLOSING, frame.getOpcode()); assertEquals("Fin must be set", true, frame.isFin()); assertEquals("TransferedMask must not be set", false, frame.getTransfereMasked()); assertEquals("Payload must be 2 (close code)", 2, frame.getPayloadData().capacity()); @@ -137,12 +138,6 @@ public void testIsValid() { } catch (InvalidDataException e) { //fine } - frame.setCode(CloseFrame.NO_UTF8); - try { - frame.isValid(); - } catch (InvalidDataException e) { - fail("InvalidDataException should not be thrown"); - } frame.setCode(CloseFrame.POLICY_VALIDATION); try { frame.isValid(); @@ -213,5 +208,28 @@ public void testIsValid() { } catch (InvalidDataException e) { //fine } + frame.setCode(CloseFrame.NOCODE); + try { + frame.isValid(); + fail("InvalidDataException should be thrown"); + } catch (InvalidDataException e) { + //fine + } + frame.setCode(CloseFrame.NO_UTF8); + frame.setReason(null); + try { + frame.isValid(); + fail("InvalidDataException should be thrown"); + } catch (InvalidDataException e) { + //fine + } + frame.setCode(CloseFrame.NOCODE); + frame.setReason("Close"); + try { + frame.isValid(); + fail("InvalidDataException should be thrown"); + } catch (InvalidDataException e) { + //fine + } } } diff --git a/src/test/java/org/java_websocket/framing/ContinuousFrameTest.java b/src/test/java/org/java_websocket/framing/ContinuousFrameTest.java index c2064847..48eb05bf 100644 --- a/src/test/java/org/java_websocket/framing/ContinuousFrameTest.java +++ b/src/test/java/org/java_websocket/framing/ContinuousFrameTest.java @@ -25,6 +25,7 @@ package org.java_websocket.framing; +import org.java_websocket.enums.Opcode; import org.java_websocket.exceptions.InvalidDataException; import org.junit.Test; @@ -39,7 +40,7 @@ public class ContinuousFrameTest { @Test public void testConstructor() { ContinuousFrame frame = new ContinuousFrame(); - assertEquals("Opcode must be equal", Framedata.Opcode.CONTINUOUS , frame.getOpcode()); + assertEquals("Opcode must be equal", Opcode.CONTINUOUS , frame.getOpcode()); assertEquals("Fin must be set", true , frame.isFin()); assertEquals("TransferedMask must not be set", false , frame.getTransfereMasked()); assertEquals("Payload must be empty", 0 , frame.getPayloadData().capacity()); diff --git a/src/test/java/org/java_websocket/framing/FramedataImpl1Test.java b/src/test/java/org/java_websocket/framing/FramedataImpl1Test.java index 778d48d0..137026a4 100644 --- a/src/test/java/org/java_websocket/framing/FramedataImpl1Test.java +++ b/src/test/java/org/java_websocket/framing/FramedataImpl1Test.java @@ -25,6 +25,7 @@ package org.java_websocket.framing; +import org.java_websocket.enums.Opcode; import org.junit.Test; import java.nio.ByteBuffer; @@ -40,8 +41,8 @@ public class FramedataImpl1Test { @Test public void testDefaultValues() { - FramedataImpl1 binary = FramedataImpl1.get(Framedata.Opcode.BINARY); - assertEquals("Opcode must be equal", Framedata.Opcode.BINARY, binary.getOpcode()); + FramedataImpl1 binary = FramedataImpl1.get(Opcode.BINARY); + assertEquals("Opcode must be equal", Opcode.BINARY, binary.getOpcode()); assertEquals("Fin must be set", true, binary.isFin()); assertEquals("TransferedMask must not be set", false, binary.getTransfereMasked()); assertEquals("Payload must be empty", 0, binary.getPayloadData().capacity()); @@ -52,17 +53,17 @@ public void testDefaultValues() { @Test public void testGet() { - FramedataImpl1 binary = FramedataImpl1.get(Framedata.Opcode.BINARY); + FramedataImpl1 binary = FramedataImpl1.get(Opcode.BINARY); assertEquals("Frame must be binary", true, binary instanceof BinaryFrame); - FramedataImpl1 text = FramedataImpl1.get(Framedata.Opcode.TEXT); + FramedataImpl1 text = FramedataImpl1.get(Opcode.TEXT); assertEquals("Frame must be text", true, text instanceof TextFrame); - FramedataImpl1 closing = FramedataImpl1.get(Framedata.Opcode.CLOSING); + FramedataImpl1 closing = FramedataImpl1.get(Opcode.CLOSING); assertEquals("Frame must be closing", true, closing instanceof CloseFrame); - FramedataImpl1 continuous = FramedataImpl1.get(Framedata.Opcode.CONTINUOUS); + FramedataImpl1 continuous = FramedataImpl1.get(Opcode.CONTINUOUS); assertEquals("Frame must be continuous", true, continuous instanceof ContinuousFrame); - FramedataImpl1 ping = FramedataImpl1.get(Framedata.Opcode.PING); + FramedataImpl1 ping = FramedataImpl1.get(Opcode.PING); assertEquals("Frame must be ping", true, ping instanceof PingFrame); - FramedataImpl1 pong = FramedataImpl1.get(Framedata.Opcode.PONG); + FramedataImpl1 pong = FramedataImpl1.get(Opcode.PONG); assertEquals("Frame must be pong", true, pong instanceof PongFrame); try { FramedataImpl1.get(null); @@ -74,7 +75,7 @@ public void testGet() { @Test public void testSetters() { - FramedataImpl1 frame = FramedataImpl1.get(Framedata.Opcode.BINARY); + FramedataImpl1 frame = FramedataImpl1.get(Opcode.BINARY); frame.setFin(false); assertEquals("Fin must not be set", false, frame.isFin()); frame.setTransferemasked(true); @@ -92,10 +93,10 @@ public void testSetters() { @Test public void testAppend() { - FramedataImpl1 frame0 = FramedataImpl1.get(Framedata.Opcode.BINARY); + FramedataImpl1 frame0 = FramedataImpl1.get(Opcode.BINARY); frame0.setFin(false); frame0.setPayload(ByteBuffer.wrap("first".getBytes())); - FramedataImpl1 frame1 = FramedataImpl1.get(Framedata.Opcode.BINARY); + FramedataImpl1 frame1 = FramedataImpl1.get(Opcode.BINARY); frame1.setPayload(ByteBuffer.wrap("second".getBytes())); frame0.append(frame1); assertEquals("Fin must be set", true, frame0.isFin()); diff --git a/src/test/java/org/java_websocket/framing/PingFrameTest.java b/src/test/java/org/java_websocket/framing/PingFrameTest.java index e9252997..fe7e08ed 100644 --- a/src/test/java/org/java_websocket/framing/PingFrameTest.java +++ b/src/test/java/org/java_websocket/framing/PingFrameTest.java @@ -25,6 +25,7 @@ package org.java_websocket.framing; +import org.java_websocket.enums.Opcode; import org.java_websocket.exceptions.InvalidDataException; import org.junit.Test; @@ -39,7 +40,7 @@ public class PingFrameTest { @Test public void testConstructor() { PingFrame frame = new PingFrame(); - assertEquals("Opcode must be equal", Framedata.Opcode.PING , frame.getOpcode()); + assertEquals("Opcode must be equal", Opcode.PING , frame.getOpcode()); assertEquals("Fin must be set", true , frame.isFin()); assertEquals("TransferedMask must not be set", false , frame.getTransfereMasked()); assertEquals("Payload must be empty", 0 , frame.getPayloadData().capacity()); diff --git a/src/test/java/org/java_websocket/framing/PongFrameTest.java b/src/test/java/org/java_websocket/framing/PongFrameTest.java index c1b5eddf..5e6333fd 100644 --- a/src/test/java/org/java_websocket/framing/PongFrameTest.java +++ b/src/test/java/org/java_websocket/framing/PongFrameTest.java @@ -25,6 +25,7 @@ package org.java_websocket.framing; +import org.java_websocket.enums.Opcode; import org.java_websocket.exceptions.InvalidDataException; import org.junit.Test; @@ -41,7 +42,7 @@ public class PongFrameTest { @Test public void testConstructor() { PongFrame frame = new PongFrame(); - assertEquals("Opcode must be equal", Framedata.Opcode.PONG , frame.getOpcode()); + assertEquals("Opcode must be equal", Opcode.PONG , frame.getOpcode()); assertEquals("Fin must be set", true , frame.isFin()); assertEquals("TransferedMask must not be set", false , frame.getTransfereMasked()); assertEquals("Payload must be empty", 0 , frame.getPayloadData().capacity()); diff --git a/src/test/java/org/java_websocket/framing/TextFrameTest.java b/src/test/java/org/java_websocket/framing/TextFrameTest.java index 156d2805..9afa8f3c 100644 --- a/src/test/java/org/java_websocket/framing/TextFrameTest.java +++ b/src/test/java/org/java_websocket/framing/TextFrameTest.java @@ -25,6 +25,7 @@ package org.java_websocket.framing; +import org.java_websocket.enums.Opcode; import org.java_websocket.exceptions.InvalidDataException; import org.junit.Test; @@ -39,7 +40,7 @@ public class TextFrameTest { @Test public void testConstructor() { TextFrame frame = new TextFrame(); - assertEquals("Opcode must be equal", Framedata.Opcode.TEXT , frame.getOpcode()); + assertEquals("Opcode must be equal", Opcode.TEXT , frame.getOpcode()); assertEquals("Fin must be set", true , frame.isFin()); assertEquals("TransferedMask must not be set", false , frame.getTransfereMasked()); assertEquals("Payload must be empty", 0 , frame.getPayloadData().capacity()); diff --git a/src/test/java/org/java_websocket/issues/Issue661Test.java b/src/test/java/org/java_websocket/issues/Issue661Test.java index 05add124..3d3bee6b 100644 --- a/src/test/java/org/java_websocket/issues/Issue661Test.java +++ b/src/test/java/org/java_websocket/issues/Issue661Test.java @@ -63,7 +63,7 @@ public void println( Object o ) { } } - @Test(timeout = 2000) + //@Test(timeout = 2000) public void testIssue() throws Exception { System.setErr( new TestPrintStream( System.err ) ); int port = SocketUtil.getAvailablePort();