11package org .java_websocket ;
22
3- import java .io .IOException ;
4- import java .net .InetSocketAddress ;
5- import java .net .Socket ;
6- import java .nio .ByteBuffer ;
7- import java .nio .channels .ByteChannel ;
8- import java .nio .channels .NotYetConnectedException ;
9- import java .nio .channels .SelectionKey ;
10- import java .util .ArrayList ;
11- import java .util .Collection ;
12- import java .util .List ;
13- import java .util .concurrent .BlockingQueue ;
14- import java .util .concurrent .LinkedBlockingQueue ;
15-
16- import org .java_websocket .drafts .Draft ;
3+ import org .java_websocket .drafts .*;
174import org .java_websocket .drafts .Draft .CloseHandshakeType ;
185import org .java_websocket .drafts .Draft .HandshakeState ;
19- import org .java_websocket .drafts .Draft_10 ;
20- import org .java_websocket .drafts .Draft_17 ;
21- import org .java_websocket .drafts .Draft_75 ;
22- import org .java_websocket .drafts .Draft_76 ;
236import org .java_websocket .exceptions .IncompleteHandshakeException ;
247import org .java_websocket .exceptions .InvalidDataException ;
258import org .java_websocket .exceptions .InvalidHandshakeException ;
2811import org .java_websocket .framing .CloseFrameBuilder ;
2912import org .java_websocket .framing .Framedata ;
3013import org .java_websocket .framing .Framedata .Opcode ;
31- import org .java_websocket .handshake .ClientHandshake ;
32- import org .java_websocket .handshake .ClientHandshakeBuilder ;
33- import org .java_websocket .handshake .Handshakedata ;
34- import org .java_websocket .handshake .ServerHandshake ;
35- import org .java_websocket .handshake .ServerHandshakeBuilder ;
14+ import org .java_websocket .handshake .*;
3615import org .java_websocket .server .WebSocketServer .WebSocketWorker ;
3716import org .java_websocket .util .Charsetfunctions ;
3817
18+ import java .io .IOException ;
19+ import java .net .InetSocketAddress ;
20+ import java .net .Socket ;
21+ import java .nio .ByteBuffer ;
22+ import java .nio .channels .ByteChannel ;
23+ import java .nio .channels .NotYetConnectedException ;
24+ import java .nio .channels .SelectionKey ;
25+ import java .util .ArrayList ;
26+ import java .util .Collection ;
27+ import java .util .List ;
28+ import java .util .concurrent .BlockingQueue ;
29+ import java .util .concurrent .LinkedBlockingQueue ;
30+
3931/**
4032 * Represents one end (client or server) of a single WebSocketImpl connection.
4133 * Takes care of the "handshake" phase, then allows for easy sending of
4234 * text frames, and receiving frames through an event-based model.
43- *
4435 */
4536public class WebSocketImpl implements WebSocket {
4637
38+ public static final List <Draft > defaultdraftlist = new ArrayList <Draft >( 4 );
4739 public static int RCVBUF = 16384 ;
40+ public static /*final*/ boolean DEBUG = false ; // must be final in the future in order to take advantage of VM optimization
4841
49- public static /*final*/ boolean DEBUG = false ; // must be final in the future in order to take advantage of VM optimization
50-
51- public static final List <Draft > defaultdraftlist = new ArrayList <Draft >( 4 );
5242 static {
5343 defaultdraftlist .add ( new Draft_17 () );
5444 defaultdraftlist .add ( new Draft_10 () );
5545 defaultdraftlist .add ( new Draft_76 () );
5646 defaultdraftlist .add ( new Draft_75 () );
5747 }
5848
59- public SelectionKey key ;
60-
61- /** the possibly wrapped channel object whose selection is controlled by {@link #key} */
62- public ByteChannel channel ;
6349 /**
6450 * Queue of buffers that need to be sent to the client.
6551 */
@@ -68,22 +54,24 @@ public class WebSocketImpl implements WebSocket {
6854 * Queue of buffers that need to be processed
6955 */
7056 public final BlockingQueue <ByteBuffer > inQueue ;
71-
57+ /**
58+ * The listener to notify of WebSocket events.
59+ */
60+ private final WebSocketListener wsl ;
61+ public SelectionKey key ;
62+ /**
63+ * the possibly wrapped channel object whose selection is controlled by {@link #key}
64+ */
65+ public ByteChannel channel ;
7266 /**
7367 * Helper variable meant to store the thread which ( exclusively ) triggers this objects decode method.
7468 **/
7569 public volatile WebSocketWorker workerThread ; // TODO reset worker?
76-
77- /** When true no further frames may be submitted to be sent */
78- private volatile boolean flushandclosestate = false ;
79-
80- private READYSTATE readystate = READYSTATE .NOT_YET_CONNECTED ;
81-
8270 /**
83- * The listener to notify of WebSocket events.
71+ * When true no further frames may be submitted to be sent
8472 */
85- private final WebSocketListener wsl ;
86-
73+ private volatile boolean flushandclosestate = false ;
74+ private READYSTATE readystate = READYSTATE . NOT_YET_CONNECTED ;
8775 private List <Draft > knownDrafts ;
8876
8977 private Draft draft = null ;
@@ -92,23 +80,27 @@ public class WebSocketImpl implements WebSocket {
9280
9381 private Opcode current_continuous_frame_opcode = null ;
9482
95- /** the bytes of an incomplete received handshake */
83+ /**
84+ * the bytes of an incomplete received handshake
85+ */
9686 private ByteBuffer tmpHandshakeBytes = ByteBuffer .allocate ( 0 );
9787
98- /** stores the handshake sent by this websocket ( Role.CLIENT only ) */
88+ /**
89+ * stores the handshake sent by this websocket ( Role.CLIENT only )
90+ */
9991 private ClientHandshake handshakerequest = null ;
10092
10193 private String closemessage = null ;
10294 private Integer closecode = null ;
10395 private Boolean closedremotely = null ;
104-
96+
10597 private String resourceDescriptor = null ;
10698
10799 /**
108100 * creates a websocket with server role
109101 */
110- public WebSocketImpl ( WebSocketListener listener , List <Draft > drafts ) {
111- this ( listener , (Draft ) null );
102+ public WebSocketImpl ( WebSocketListener listener , List <Draft > drafts ) {
103+ this ( listener , ( Draft ) null );
112104 this .role = Role .SERVER ;
113105 // draft.copyInstance will be called when the draft is first needed
114106 if ( drafts == null || drafts .isEmpty () ) {
@@ -120,11 +112,10 @@ public WebSocketImpl( WebSocketListener listener , List<Draft> drafts ) {
120112
121113 /**
122114 * creates a websocket with client role
123- *
124- * @param listener
125- * may be unbound
115+ *
116+ * @param listener may be unbound
126117 */
127- public WebSocketImpl ( WebSocketListener listener , Draft draft ) {
118+ public WebSocketImpl ( WebSocketListener listener , Draft draft ) {
128119 if ( listener == null || ( draft == null && role == Role .SERVER ) )// socket can be null because we want do be able to create the object without already having a bound channel
129120 throw new IllegalArgumentException ( "parameters must not be null" );
130121 this .outQueue = new LinkedBlockingQueue <ByteBuffer >();
@@ -136,17 +127,17 @@ public WebSocketImpl( WebSocketListener listener , Draft draft ) {
136127 }
137128
138129 @ Deprecated
139- public WebSocketImpl ( WebSocketListener listener , Draft draft , Socket socket ) {
130+ public WebSocketImpl ( WebSocketListener listener , Draft draft , Socket socket ) {
140131 this ( listener , draft );
141132 }
142133
143134 @ Deprecated
144- public WebSocketImpl ( WebSocketListener listener , List <Draft > drafts , Socket socket ) {
135+ public WebSocketImpl ( WebSocketListener listener , List <Draft > drafts , Socket socket ) {
145136 this ( listener , drafts );
146137 }
147138
148139 /**
149- *
140+ *
150141 */
151142 public void decode ( ByteBuffer socketBuffer ) {
152143 assert ( socketBuffer .hasRemaining () );
@@ -169,6 +160,7 @@ public void decode( ByteBuffer socketBuffer ) {
169160 }
170161 assert ( isClosing () || isFlushAndClose () || !socketBuffer .hasRemaining () );
171162 }
163+
172164 /**
173165 * Returns whether the handshake phase has is completed.
174166 * In case of a broken handshake this will be never the case.
@@ -214,11 +206,11 @@ private boolean decodeHandshake( ByteBuffer socketBufferNew ) {
214206 d .setParseMode ( role );
215207 socketBuffer .reset ();
216208 Handshakedata tmphandshake = d .translateHandshake ( socketBuffer );
217- if (!( tmphandshake instanceof ClientHandshake ) ) {
209+ if ( !( tmphandshake instanceof ClientHandshake ) ) {
218210 flushAndClose ( CloseFrame .PROTOCOL_ERROR , "wrong http function" , false );
219211 return false ;
220212 }
221- ClientHandshake handshake = (ClientHandshake ) tmphandshake ;
213+ ClientHandshake handshake = ( ClientHandshake ) tmphandshake ;
222214 handshakestate = d .acceptHandshakeAsServer ( handshake );
223215 if ( handshakestate == HandshakeState .MATCHED ) {
224216 resourceDescriptor = handshake .getResourceDescriptor ();
@@ -249,11 +241,11 @@ private boolean decodeHandshake( ByteBuffer socketBufferNew ) {
249241 } else {
250242 // special case for multiple step handshakes
251243 Handshakedata tmphandshake = draft .translateHandshake ( socketBuffer );
252- if (!( tmphandshake instanceof ClientHandshake ) ) {
244+ if ( !( tmphandshake instanceof ClientHandshake ) ) {
253245 flushAndClose ( CloseFrame .PROTOCOL_ERROR , "wrong http function" , false );
254246 return false ;
255247 }
256- ClientHandshake handshake = (ClientHandshake ) tmphandshake ;
248+ ClientHandshake handshake = ( ClientHandshake ) tmphandshake ;
257249 handshakestate = draft .acceptHandshakeAsServer ( handshake );
258250
259251 if ( handshakestate == HandshakeState .MATCHED ) {
@@ -267,11 +259,11 @@ private boolean decodeHandshake( ByteBuffer socketBufferNew ) {
267259 } else if ( role == Role .CLIENT ) {
268260 draft .setParseMode ( role );
269261 Handshakedata tmphandshake = draft .translateHandshake ( socketBuffer );
270- if (!( tmphandshake instanceof ServerHandshake ) ) {
262+ if ( !( tmphandshake instanceof ServerHandshake ) ) {
271263 flushAndClose ( CloseFrame .PROTOCOL_ERROR , "wrong http function" , false );
272264 return false ;
273265 }
274- ServerHandshake handshake = (ServerHandshake ) tmphandshake ;
266+ ServerHandshake handshake = ( ServerHandshake ) tmphandshake ;
275267 handshakestate = draft .acceptHandshakeAsClient ( handshakerequest , handshake );
276268 if ( handshakestate == HandshakeState .MATCHED ) {
277269 try {
@@ -325,11 +317,15 @@ private void decodeFrames( ByteBuffer socketBuffer ) {
325317 Opcode curop = f .getOpcode ();
326318 boolean fin = f .isFin ();
327319
320+ //Not evaluating any further frames if the connection is in READYSTATE CLOSE
321+ if ( readystate == READYSTATE .CLOSING )
322+ return ;
323+
328324 if ( curop == Opcode .CLOSING ) {
329325 int code = CloseFrame .NOCODE ;
330326 String reason = "" ;
331327 if ( f instanceof CloseFrame ) {
332- CloseFrame cf = (CloseFrame ) f ;
328+ CloseFrame cf = ( CloseFrame ) f ;
333329 code = cf .getCloseCode ();
334330 reason = cf .getMessage ();
335331 }
@@ -391,13 +387,14 @@ private void decodeFrames( ByteBuffer socketBuffer ) {
391387 close ( e1 );
392388 return ;
393389 }
390+
394391 }
395392
396393 private void close ( int code , String message , boolean remote ) {
397394 if ( readystate != READYSTATE .CLOSING && readystate != READYSTATE .CLOSED ) {
398395 if ( readystate == READYSTATE .OPEN ) {
399396 if ( code == CloseFrame .ABNORMAL_CLOSE ) {
400- assert (!remote );
397+ assert ( !remote );
401398 readystate = READYSTATE .CLOSING ;
402399 flushAndClose ( code , message , false );
403400 return ;
@@ -438,12 +435,10 @@ public void close( int code, String message ) {
438435 }
439436
440437 /**
441- *
442- * @param remote
443- * Indicates who "generated" <code>code</code>.<br>
444- * <code>true</code> means that this endpoint received the <code>code</code> from the other endpoint.<br>
445- * false means this endpoint decided to send the given code,<br>
446- * <code>remote</code> may also be true if this endpoint started the closing handshake since the other endpoint may not simply echo the <code>code</code> but close the connection the same time this endpoint does do but with an other <code>code</code>. <br>
438+ * @param remote Indicates who "generated" <code>code</code>.<br>
439+ * <code>true</code> means that this endpoint received the <code>code</code> from the other endpoint.<br>
440+ * false means this endpoint decided to send the given code,<br>
441+ * <code>remote</code> may also be true if this endpoint started the closing handshake since the other endpoint may not simply echo the <code>code</code> but close the connection the same time this endpoint does do but with an other <code>code</code>. <br>
447442 **/
448443
449444 protected synchronized void closeConnection ( int code , String message , boolean remote ) {
@@ -539,6 +534,7 @@ public void close( InvalidDataException e ) {
539534
540535 /**
541536 * Send Text data to the other end.
537+ *
542538 * @throws NotYetConnectedException websocket is not yet connected
543539 */
544540 @ Override
@@ -555,14 +551,14 @@ public void send( String text ) throws WebsocketNotConnectedException {
555551 * @throws NotYetConnectedException websocket is not yet connected
556552 */
557553 @ Override
558- public void send ( ByteBuffer bytes ) throws IllegalArgumentException , WebsocketNotConnectedException {
554+ public void send ( ByteBuffer bytes ) throws IllegalArgumentException , WebsocketNotConnectedException {
559555 if ( bytes == null )
560556 throw new IllegalArgumentException ( "Cannot send 'null' data to a WebSocketImpl." );
561557 send ( draft .createFrames ( bytes , role == Role .CLIENT ) );
562558 }
563559
564560 @ Override
565- public void send ( byte [] bytes ) throws IllegalArgumentException , WebsocketNotConnectedException {
561+ public void send ( byte [] bytes ) throws IllegalArgumentException , WebsocketNotConnectedException {
566562 send ( ByteBuffer .wrap ( bytes ) );
567563 }
568564
@@ -600,7 +596,7 @@ private HandshakeState isFlashEdgeCase( ByteBuffer request ) throws IncompleteHa
600596 } else {
601597
602598 for ( int flash_policy_index = 0 ; request .hasRemaining () ; flash_policy_index ++ ) {
603- if ( Draft .FLASH_POLICY_REQUEST [ flash_policy_index ] != request .get () ) {
599+ if ( Draft .FLASH_POLICY_REQUEST [flash_policy_index ] != request .get () ) {
604600 request .reset ();
605601 return HandshakeState .NOT_MATCHED ;
606602 }
@@ -616,8 +612,8 @@ public void startHandshake( ClientHandshakeBuilder handshakedata ) throws Invali
616612 this .handshakerequest = draft .postProcessHandshakeRequestAsClient ( handshakedata );
617613
618614 resourceDescriptor = handshakedata .getResourceDescriptor ();
619- assert ( resourceDescriptor != null );
620-
615+ assert ( resourceDescriptor != null );
616+
621617 // Notify Listener
622618 try {
623619 wsl .onWebsocketHandshakeSentAsClient ( this , this .handshakerequest );
@@ -667,13 +663,13 @@ private void open( Handshakedata d ) {
667663
668664 @ Override
669665 public boolean isConnecting () {
670- assert (!flushandclosestate || readystate == READYSTATE .CONNECTING );
666+ assert ( !flushandclosestate || readystate == READYSTATE .CONNECTING );
671667 return readystate == READYSTATE .CONNECTING ; // ifflushandclosestate
672668 }
673669
674670 @ Override
675671 public boolean isOpen () {
676- assert (readystate != READYSTATE .OPEN || !flushandclosestate );
672+ assert ( readystate != READYSTATE .OPEN || !flushandclosestate );
677673 return readystate == READYSTATE .OPEN ;
678674 }
679675
0 commit comments