From bfe8813d5578d676caf7fa1b4bac7542e0bf3deb Mon Sep 17 00:00:00 2001 From: marci4 Date: Wed, 16 Aug 2017 20:37:07 +0200 Subject: [PATCH 1/2] Move processing of frames to draft All deprecated drafts have no implementation --- .../org/java_websocket/WebSocketImpl.java | 188 +++++------------- .../java/org/java_websocket/drafts/Draft.java | 9 + .../org/java_websocket/drafts/Draft_10.java | 5 + .../org/java_websocket/drafts/Draft_6455.java | 103 +++++++++- .../drafts/Draft_6455_WebRTC.java | 61 +++++- .../org/java_websocket/drafts/Draft_75.java | 5 + 6 files changed, 227 insertions(+), 144 deletions(-) diff --git a/src/main/java/org/java_websocket/WebSocketImpl.java b/src/main/java/org/java_websocket/WebSocketImpl.java index 4bf0645a..05675c28 100644 --- a/src/main/java/org/java_websocket/WebSocketImpl.java +++ b/src/main/java/org/java_websocket/WebSocketImpl.java @@ -35,7 +35,6 @@ import org.java_websocket.framing.CloseFrame; import org.java_websocket.framing.Framedata; import org.java_websocket.framing.Framedata.Opcode; -import org.java_websocket.framing.FramedataImpl1; import org.java_websocket.framing.PingFrame; import org.java_websocket.handshake.*; import org.java_websocket.server.WebSocketServer.WebSocketWorker; @@ -48,10 +47,7 @@ import java.nio.channels.ByteChannel; import java.nio.channels.NotYetConnectedException; import java.nio.channels.SelectionKey; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; +import java.util.*; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; @@ -63,9 +59,9 @@ public class WebSocketImpl implements WebSocket { public static int RCVBUF = 16384; - /** - * Activate debug mode for additional infos - */ + /** + * Activate debug mode for additional infos + */ public static boolean DEBUG = false; // must be final in the future in order to take advantage of VM optimization /** @@ -95,26 +91,21 @@ public class WebSocketImpl implements WebSocket { private volatile boolean flushandclosestate = false; private READYSTATE readystate = READYSTATE.NOT_YET_CONNECTED; - /** - * A list of drafts available for this websocket - */ + /** + * A list of drafts available for this websocket + */ private List knownDrafts; - /** - * The draft which is used by this websocket - */ + /** + * The draft which is used by this websocket + */ private Draft draft = null; - /** - * The role which this websocket takes in the connection - */ + /** + * The role which this websocket takes in the connection + */ private Role role; - /** - * The frame which had the opcode Continous set - */ - private Framedata current_continuous_frame = null; - /** * the bytes of an incomplete received handshake */ @@ -359,6 +350,22 @@ private boolean decodeHandshake( ByteBuffer socketBufferNew ) { return false; } + private void decodeFrames( ByteBuffer socketBuffer ) { + List frames; + try { + frames = draft.translateFrame( socketBuffer ); + for( Framedata f : frames ) { + if( DEBUG ) + System.out.println( "matched frame: " + f ); + draft.processFrame( this, f ); + } + } catch ( InvalidDataException e1 ) { + wsl.onWebsocketError( this, e1 ); + close( e1 ); + return; + } + } + /** * Close the connection if the received handshake was not correct * @param exception the InvalidDataException causing this problem @@ -395,115 +402,7 @@ private ByteBuffer generateHttpResponseDueToError(int errorCode) { return ByteBuffer.wrap( Charsetfunctions.asciiBytes( "HTTP/1.1 "+ errorCodeDescription +"\r\nContent-Type: text/html\nServer: TooTallNate Java-WebSocket\r\nContent-Length: " + (48 + errorCodeDescription.length()) +"\r\n\r\n

" + errorCodeDescription + "

" )); } - private void decodeFrames( ByteBuffer socketBuffer ) { - - List frames; - try { - frames = draft.translateFrame( socketBuffer ); - for( Framedata f : frames ) { - if( DEBUG ) - System.out.println( "matched frame: " + f ); - Opcode curop = f.getOpcode(); - boolean fin = f.isFin(); - //Not evaluating any further frames if the connection is in READYSTATE CLOSE - if( readystate == READYSTATE.CLOSING ) - return; - - if( curop == Opcode.CLOSING ) { - int code = CloseFrame.NOCODE; - String reason = ""; - if( f instanceof CloseFrame ) { - CloseFrame cf = ( CloseFrame ) f; - code = cf.getCloseCode(); - reason = cf.getMessage(); - } - if( readystate == READYSTATE.CLOSING ) { - // complete the close handshake by disconnecting - closeConnection( code, reason, true ); - } else { - // echo close handshake - if( draft.getCloseHandshakeType() == CloseHandshakeType.TWOWAY ) - close( code, reason, true ); - else - flushAndClose( code, reason, false ); - } - continue; - } else if( curop == Opcode.PING ) { - wsl.onWebsocketPing( this, f ); - continue; - } else if( curop == Opcode.PONG ) { - lastPong = System.currentTimeMillis(); - wsl.onWebsocketPong( this, f ); - continue; - } else if( !fin || curop == Opcode.CONTINUOUS ) { - if( curop != Opcode.CONTINUOUS ) { - if( current_continuous_frame != null ) - throw new InvalidDataException( CloseFrame.PROTOCOL_ERROR, "Previous continuous frame sequence not completed." ); - current_continuous_frame = f; - } else if( fin ) { - if( current_continuous_frame == null ) - 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( current_continuous_frame.getOpcode() == Opcode.TEXT ) { - //Checking a bit more from the frame before this one just to make sure all the code points are correct - int off = Math.max( current_continuous_frame.getPayloadData().limit() - 64, 0 ); - current_continuous_frame.append( f ); - if( !Charsetfunctions.isValidUTF8( current_continuous_frame.getPayloadData(), off ) ) { - throw new InvalidDataException( CloseFrame.NO_UTF8 ); - } - } - current_continuous_frame = null; - } else if( current_continuous_frame == null ) { - 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 == Opcode.TEXT ) { - if( !Charsetfunctions.isValidUTF8( f.getPayloadData() ) ) { - throw new InvalidDataException( CloseFrame.NO_UTF8 ); - } - } - //Checking if the current continous frame contains a correct payload with the other frames combined - if( curop == Opcode.CONTINUOUS && current_continuous_frame != null && current_continuous_frame.getOpcode() == Opcode.TEXT ) { - //Checking a bit more from the frame before this one just to make sure all the code points are correct - int off = Math.max( current_continuous_frame.getPayloadData().limit() - 64, 0 ); - current_continuous_frame.append( f ); - if( !Charsetfunctions.isValidUTF8( current_continuous_frame.getPayloadData(), off ) ) { - throw new InvalidDataException( CloseFrame.NO_UTF8 ); - } - } - try { - wsl.onWebsocketMessageFragment( this, f ); - } catch ( RuntimeException e ) { - wsl.onWebsocketError( this, e ); - } - - } else if( current_continuous_frame != null ) { - throw new InvalidDataException( CloseFrame.PROTOCOL_ERROR, "Continuous frame sequence not completed." ); - } else if( curop == Opcode.TEXT ) { - try { - wsl.onWebsocketMessage( this, Charsetfunctions.stringUtf8( f.getPayloadData() ) ); - } catch ( RuntimeException e ) { - wsl.onWebsocketError( this, e ); - } - } else if( curop == Opcode.BINARY ) { - try { - wsl.onWebsocketMessage( this, f.getPayloadData() ); - } catch ( RuntimeException e ) { - wsl.onWebsocketError( this, e ); - } - } else { - throw new InvalidDataException( CloseFrame.PROTOCOL_ERROR, "non control or continious frame expected" ); - } - } - } catch ( InvalidDataException e1 ) { - wsl.onWebsocketError( this, e1 ); - close( e1 ); - return; - } - - } - - private void close( int code, String message, boolean remote ) { + public void close( int code, String message, boolean remote ) { if( readystate != READYSTATE.CLOSING && readystate != READYSTATE.CLOSED ) { if( readystate == READYSTATE.OPEN ) { if( code == CloseFrame.ABNORMAL_CLOSE ) { @@ -524,13 +423,8 @@ private void close( int code, String message, boolean remote ) { CloseFrame closeFrame = new CloseFrame(); closeFrame.setReason(message); closeFrame.setCode(code); - try { - closeFrame.isValid(); - sendFrame(closeFrame); - } catch (InvalidDataException e) { - //Rethrow invalid data exception - throw e; - } + closeFrame.isValid(); + sendFrame(closeFrame); } catch ( InvalidDataException e ) { wsl.onWebsocketError( this, e ); flushAndClose( CloseFrame.ABNORMAL_CLOSE, "generated frame is invalid", false ); @@ -566,7 +460,7 @@ public void close( int code, String message ) { * false means this endpoint decided to send the given code,
* 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.
**/ - protected synchronized void closeConnection( int code, String message, boolean remote ) { + public synchronized void closeConnection( int code, String message, boolean remote ) { if( readystate == READYSTATE.CLOSED ) { return; } @@ -610,7 +504,7 @@ public void closeConnection( int code, String message ) { closeConnection( code, message, false ); } - protected synchronized void flushAndClose( int code, String message, boolean remote ) { + public synchronized void flushAndClose( int code, String message, boolean remote ) { if( flushandclosestate ) { return; } @@ -694,7 +588,7 @@ private void send( Collection frames ) { for (Framedata f : frames) { if( DEBUG ) System.out.println( "send frame: " + f ); - outgoingFrames.add( draft.createBinaryFrame( f ) ); + outgoingFrames.add( draft.createBinaryFrame( f ) ); } write( outgoingFrames ); } @@ -868,4 +762,16 @@ public String getResourceDescriptor() { long getLastPong() { return lastPong; } + + public void setLastPong( long lastPong ) { + this.lastPong = lastPong; + } + + /** + * Getter for the websocket listener + * @return the websocket listener associated with this instance + */ + public WebSocketListener getWebSocketListener() { + return wsl; + } } diff --git a/src/main/java/org/java_websocket/drafts/Draft.java b/src/main/java/org/java_websocket/drafts/Draft.java index fb281310..7e30cacc 100644 --- a/src/main/java/org/java_websocket/drafts/Draft.java +++ b/src/main/java/org/java_websocket/drafts/Draft.java @@ -32,6 +32,7 @@ import java.util.Locale; import org.java_websocket.WebSocket.Role; +import org.java_websocket.WebSocketImpl; import org.java_websocket.exceptions.IncompleteHandshakeException; import org.java_websocket.exceptions.InvalidDataException; import org.java_websocket.exceptions.InvalidHandshakeException; @@ -161,6 +162,14 @@ protected boolean basicAccept( Handshakedata handshakedata ) { public abstract List createFrames( String text, boolean mask ); + + /** + * Handle the frame specific to the draft + * @param webSocketImpl the websocketimpl used for this draft + * @param frame the frame which is supposed to be handled + */ + public abstract void processFrame( WebSocketImpl webSocketImpl, Framedata frame ) throws InvalidDataException; + 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_10.java b/src/main/java/org/java_websocket/drafts/Draft_10.java index da67a4ae..8376e75f 100644 --- a/src/main/java/org/java_websocket/drafts/Draft_10.java +++ b/src/main/java/org/java_websocket/drafts/Draft_10.java @@ -26,6 +26,7 @@ package org.java_websocket.drafts; import org.java_websocket.WebSocket.Role; +import org.java_websocket.WebSocketImpl; import org.java_websocket.exceptions.*; import org.java_websocket.framing.*; import org.java_websocket.framing.Framedata.Opcode; @@ -170,6 +171,10 @@ public List createFrames( String text, boolean mask ) { return Collections.singletonList( ( Framedata ) curframe ); } + public void processFrame( WebSocketImpl webSocketImpl, Framedata frame ) throws InvalidDataException { + throw new UnsupportedOperationException( "This draft is not supported any more. Please use Draft_6455." ); + } + private byte fromOpcode( Opcode opcode ) { if( opcode == Opcode.CONTINUOUS ) return 0; 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 be5de505..7efad503 100644 --- a/src/main/java/org/java_websocket/drafts/Draft_6455.java +++ b/src/main/java/org/java_websocket/drafts/Draft_6455.java @@ -25,6 +25,7 @@ package org.java_websocket.drafts; +import org.java_websocket.WebSocket; import org.java_websocket.WebSocketImpl; import org.java_websocket.exceptions.InvalidDataException; import org.java_websocket.exceptions.InvalidFrameException; @@ -32,9 +33,11 @@ import org.java_websocket.exceptions.LimitExedeedException; import org.java_websocket.extensions.DefaultExtension; import org.java_websocket.extensions.IExtension; +import org.java_websocket.framing.CloseFrame; import org.java_websocket.framing.Framedata; import org.java_websocket.framing.FramedataImpl1; import org.java_websocket.handshake.*; +import org.java_websocket.util.Charsetfunctions; import java.math.BigInteger; import java.nio.ByteBuffer; @@ -56,7 +59,12 @@ public class Draft_6455 extends Draft_17 { /** * Attribute for all available extension in this draft */ - private List knownExtensions; + List knownExtensions; + + /** + * Attribute for the current continuous frame + */ + private Framedata current_continuous_frame; /** * Constructor for the websocket protocol specified by RFC 6455 with default extensions @@ -325,7 +333,7 @@ public List translateFrame( ByteBuffer buffer ) throws InvalidDataExc @Override public void reset() { super.reset(); - if (extension != null) { + if( extension != null ) { extension.reset(); } extension = null; @@ -344,6 +352,97 @@ private String getServerTime() { return dateFormat.format( calendar.getTime() ); } + @Override + public void processFrame( WebSocketImpl webSocketImpl, Framedata frame ) throws InvalidDataException { + Framedata.Opcode curop = frame.getOpcode(); + if( curop == Framedata.Opcode.CLOSING ) { + int code = CloseFrame.NOCODE; + String reason = ""; + if( frame instanceof CloseFrame ) { + CloseFrame cf = ( CloseFrame ) frame; + code = cf.getCloseCode(); + reason = cf.getMessage(); + } + if( webSocketImpl.getReadyState() == WebSocket.READYSTATE.CLOSING ) { + // complete the close handshake by disconnecting + webSocketImpl.closeConnection( code, reason, true ); + } else { + // echo close handshake + if( getCloseHandshakeType() == CloseHandshakeType.TWOWAY ) + webSocketImpl.close( code, reason, true ); + else + webSocketImpl.flushAndClose( code, reason, false ); + } + return; + } else if( curop == Framedata.Opcode.PING ) { + webSocketImpl.getWebSocketListener().onWebsocketPing( webSocketImpl, frame ); + return; + } else if( curop == Framedata.Opcode.PONG ) { + webSocketImpl.setLastPong( System.currentTimeMillis() ); + webSocketImpl.getWebSocketListener().onWebsocketPong( webSocketImpl, frame ); + return; + } else if( !frame.isFin() || curop == Framedata.Opcode.CONTINUOUS ) { + if( curop != Framedata.Opcode.CONTINUOUS ) { + if( current_continuous_frame != null ) + throw new InvalidDataException( CloseFrame.PROTOCOL_ERROR, "Previous continuous frame sequence not completed." ); + current_continuous_frame = frame; + } else if( frame.isFin() ) { + if( current_continuous_frame == null ) + 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( current_continuous_frame.getOpcode() == Framedata.Opcode.TEXT ) { + //Checking a bit more from the frame before this one just to make sure all the code points are correct + int off = Math.max( current_continuous_frame.getPayloadData().limit() - 64, 0 ); + current_continuous_frame.append( frame ); + if( !Charsetfunctions.isValidUTF8( current_continuous_frame.getPayloadData(), off ) ) { + throw new InvalidDataException( CloseFrame.NO_UTF8 ); + } + } + current_continuous_frame = null; + } else if( current_continuous_frame == null ) { + 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( !Charsetfunctions.isValidUTF8( frame.getPayloadData() ) ) { + throw new InvalidDataException( CloseFrame.NO_UTF8 ); + } + } + //Checking if the current continous frame contains a correct payload with the other frames combined + if( curop == Framedata.Opcode.CONTINUOUS && current_continuous_frame != null && current_continuous_frame.getOpcode() == Framedata.Opcode.TEXT ) { + //Checking a bit more from the frame before this one just to make sure all the code points are correct + int off = Math.max( current_continuous_frame.getPayloadData().limit() - 64, 0 ); + current_continuous_frame.append( frame ); + if( !Charsetfunctions.isValidUTF8( current_continuous_frame.getPayloadData(), off ) ) { + throw new InvalidDataException( CloseFrame.NO_UTF8 ); + } + } + try { + webSocketImpl.getWebSocketListener().onWebsocketMessageFragment( webSocketImpl, frame ); + } catch ( RuntimeException e ) { + webSocketImpl.getWebSocketListener().onWebsocketError( webSocketImpl, e ); + } + return; + } else if( current_continuous_frame != null ) { + throw new InvalidDataException( CloseFrame.PROTOCOL_ERROR, "Continuous frame sequence not completed." ); + } else if( curop == Framedata.Opcode.TEXT ) { + try { + webSocketImpl.getWebSocketListener().onWebsocketMessage( webSocketImpl, Charsetfunctions.stringUtf8( frame.getPayloadData() ) ); + } catch ( RuntimeException e ) { + webSocketImpl.getWebSocketListener().onWebsocketError( webSocketImpl, e ); + } + return; + } else if( curop == Framedata.Opcode.BINARY ) { + try { + webSocketImpl.getWebSocketListener().onWebsocketMessage( webSocketImpl, frame.getPayloadData() ); + } catch ( RuntimeException e ) { + webSocketImpl.getWebSocketListener().onWebsocketError( webSocketImpl, e ); + } + } else { + throw new InvalidDataException( CloseFrame.PROTOCOL_ERROR, "non control or continious frame expected" ); + } + } + @Override public String toString() { String result = super.toString(); diff --git a/src/main/java/org/java_websocket/drafts/Draft_6455_WebRTC.java b/src/main/java/org/java_websocket/drafts/Draft_6455_WebRTC.java index 1a2045ac..dbe0e38b 100644 --- a/src/main/java/org/java_websocket/drafts/Draft_6455_WebRTC.java +++ b/src/main/java/org/java_websocket/drafts/Draft_6455_WebRTC.java @@ -1,7 +1,37 @@ +/* + * Copyright (c) 2010-2017 Nathan Rajlich + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + package org.java_websocket.drafts; +import org.java_websocket.extensions.IExtension; import org.java_websocket.handshake.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + /** * Description: * Base on Draft_6455 @@ -15,6 +45,31 @@ public class Draft_6455_WebRTC extends Draft_6455 { + /** + * Constructor for the websocket protocol specified by RFC 6455 with default extensions for the WebRTC Candidate server(WebSocket) + */ + public Draft_6455_WebRTC() { + this( Collections.emptyList() ); + } + + /** + * Constructor for the websocket protocol specified by RFC 6455 with custom extensions for the WebRTC Candidate server(WebSocket) + * + * @param inputExtension the extension which should be used for this draft + */ + public Draft_6455_WebRTC( IExtension inputExtension ) { + this( Collections.singletonList( inputExtension ) ); + } + + /** + * Constructor for the websocket protocol specified by RFC 6455 with custom extensions for the WebRTC Candidate server(WebSocket) + * + * @param inputExtensions the extensions which should be used for this draft + */ + public Draft_6455_WebRTC( List inputExtensions ) { + super(inputExtensions); + } + @Override public ClientHandshakeBuilder postProcessHandshakeRequestAsClient(ClientHandshakeBuilder request) { super.postProcessHandshakeRequestAsClient(request); @@ -24,6 +79,10 @@ public ClientHandshakeBuilder postProcessHandshakeRequestAsClient(ClientHandshak @Override public Draft copyInstance() { - return new Draft_6455_WebRTC(); + ArrayList newExtensions = new ArrayList(); + for( IExtension extension : knownExtensions ) { + newExtensions.add( extension.copyInstance() ); + } + return new Draft_6455_WebRTC( newExtensions ); } } \ No newline at end of file diff --git a/src/main/java/org/java_websocket/drafts/Draft_75.java b/src/main/java/org/java_websocket/drafts/Draft_75.java index 7c559273..1b75f44f 100644 --- a/src/main/java/org/java_websocket/drafts/Draft_75.java +++ b/src/main/java/org/java_websocket/drafts/Draft_75.java @@ -25,6 +25,7 @@ package org.java_websocket.drafts; +import org.java_websocket.WebSocketImpl; import org.java_websocket.exceptions.*; import org.java_websocket.framing.CloseFrame; import org.java_websocket.framing.Framedata; @@ -117,6 +118,10 @@ public List createFrames( String text, boolean mask ) { return Collections.singletonList( ( Framedata ) frame ); } + public void processFrame( WebSocketImpl webSocketImpl, Framedata frame ) throws InvalidDataException { + throw new UnsupportedOperationException( "This draft is not supported any more. Please use Draft_6455." ); + } + @Override public ClientHandshakeBuilder postProcessHandshakeRequestAsClient( ClientHandshakeBuilder request ) throws InvalidHandshakeException { request.put( "Upgrade", "WebSocket" ); From ada0bf40b40bf03d5778383dfffe684a622ca838 Mon Sep 17 00:00:00 2001 From: marci4 Date: Wed, 16 Aug 2017 21:52:52 +0200 Subject: [PATCH 2/2] Improve handling of IOExceptions causing eot() #516 SSLException will call onError and then call eot() --- .../client/WebSocketClient.java | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/java_websocket/client/WebSocketClient.java b/src/main/java/org/java_websocket/client/WebSocketClient.java index d2c94e21..79a23e9a 100644 --- a/src/main/java/org/java_websocket/client/WebSocketClient.java +++ b/src/main/java/org/java_websocket/client/WebSocketClient.java @@ -40,6 +40,7 @@ import java.util.concurrent.CountDownLatch; import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLException; import javax.net.ssl.SSLSocketFactory; import org.java_websocket.AbstractWebSocket; @@ -278,7 +279,7 @@ public void run() { } engine.eot(); } catch ( IOException e ) { - engine.eot(); + handleIOException(e); } catch ( RuntimeException e ) { // this catch case covers internal errors only and indicates a bug in this websocket implementation onError( e ); @@ -286,6 +287,7 @@ public void run() { } assert ( socket.isClosed() ); } + private int getPort() { int port = uri.getPort(); if( port == -1 ) { @@ -457,13 +459,13 @@ private class WebsocketWriteThread implements Runnable { public void run() { Thread.currentThread().setName( "WebsocketWriteThread" ); try { - while ( !Thread.interrupted() ) { + while( !Thread.interrupted() ) { ByteBuffer buffer = engine.outQueue.take(); ostream.write( buffer.array(), 0, buffer.limit() ); ostream.flush(); } } catch ( IOException e ) { - engine.eot(); + handleIOException(e); } catch ( InterruptedException e ) { // this thread is regularly terminated via an interrupt } @@ -562,4 +564,16 @@ public InetSocketAddress getRemoteSocketAddress() { public String getResourceDescriptor() { return uri.getPath(); } + + + /** + * Method to give some additional info for specific IOExceptions + * @param e the IOException causing a eot. + */ + private void handleIOException( IOException e ) { + if (e instanceof SSLException) { + onError( e ); + } + engine.eot(); + } }