3535import org .java_websocket .framing .CloseFrame ;
3636import org .java_websocket .framing .Framedata ;
3737import org .java_websocket .framing .Framedata .Opcode ;
38- import org .java_websocket .framing .FramedataImpl1 ;
3938import org .java_websocket .framing .PingFrame ;
4039import org .java_websocket .handshake .*;
4140import org .java_websocket .server .WebSocketServer .WebSocketWorker ;
4847import java .nio .channels .ByteChannel ;
4948import java .nio .channels .NotYetConnectedException ;
5049import java .nio .channels .SelectionKey ;
51- import java .util .ArrayList ;
52- import java .util .Collection ;
53- import java .util .Collections ;
54- import java .util .List ;
50+ import java .util .*;
5551import java .util .concurrent .BlockingQueue ;
5652import java .util .concurrent .LinkedBlockingQueue ;
5753
6359public class WebSocketImpl implements WebSocket {
6460 public static int RCVBUF = 16384 ;
6561
66- /**
67- * Activate debug mode for additional infos
68- */
62+ /**
63+ * Activate debug mode for additional infos
64+ */
6965 public static boolean DEBUG = false ; // must be final in the future in order to take advantage of VM optimization
7066
7167 /**
@@ -95,26 +91,21 @@ public class WebSocketImpl implements WebSocket {
9591 private volatile boolean flushandclosestate = false ;
9692 private READYSTATE readystate = READYSTATE .NOT_YET_CONNECTED ;
9793
98- /**
99- * A list of drafts available for this websocket
100- */
94+ /**
95+ * A list of drafts available for this websocket
96+ */
10197 private List <Draft > knownDrafts ;
10298
103- /**
104- * The draft which is used by this websocket
105- */
99+ /**
100+ * The draft which is used by this websocket
101+ */
106102 private Draft draft = null ;
107103
108- /**
109- * The role which this websocket takes in the connection
110- */
104+ /**
105+ * The role which this websocket takes in the connection
106+ */
111107 private Role role ;
112108
113- /**
114- * The frame which had the opcode Continous set
115- */
116- private Framedata current_continuous_frame = null ;
117-
118109 /**
119110 * the bytes of an incomplete received handshake
120111 */
@@ -359,6 +350,22 @@ private boolean decodeHandshake( ByteBuffer socketBufferNew ) {
359350 return false ;
360351 }
361352
353+ private void decodeFrames ( ByteBuffer socketBuffer ) {
354+ List <Framedata > frames ;
355+ try {
356+ frames = draft .translateFrame ( socketBuffer );
357+ for ( Framedata f : frames ) {
358+ if ( DEBUG )
359+ System .out .println ( "matched frame: " + f );
360+ draft .processFrame ( this , f );
361+ }
362+ } catch ( InvalidDataException e1 ) {
363+ wsl .onWebsocketError ( this , e1 );
364+ close ( e1 );
365+ return ;
366+ }
367+ }
368+
362369 /**
363370 * Close the connection if the received handshake was not correct
364371 * @param exception the InvalidDataException causing this problem
@@ -395,115 +402,7 @@ private ByteBuffer generateHttpResponseDueToError(int errorCode) {
395402 return ByteBuffer .wrap ( Charsetfunctions .asciiBytes ( "HTTP/1.1 " + errorCodeDescription +"\r \n Content-Type: text/html\n Server: TooTallNate Java-WebSocket\r \n Content-Length: " + (48 + errorCodeDescription .length ()) +"\r \n \r \n <html><head></head><body><h1>" + errorCodeDescription + "</h1></body></html>" ));
396403 }
397404
398- private void decodeFrames ( ByteBuffer socketBuffer ) {
399-
400- List <Framedata > frames ;
401- try {
402- frames = draft .translateFrame ( socketBuffer );
403- for ( Framedata f : frames ) {
404- if ( DEBUG )
405- System .out .println ( "matched frame: " + f );
406- Opcode curop = f .getOpcode ();
407- boolean fin = f .isFin ();
408- //Not evaluating any further frames if the connection is in READYSTATE CLOSE
409- if ( readystate == READYSTATE .CLOSING )
410- return ;
411-
412- if ( curop == Opcode .CLOSING ) {
413- int code = CloseFrame .NOCODE ;
414- String reason = "" ;
415- if ( f instanceof CloseFrame ) {
416- CloseFrame cf = ( CloseFrame ) f ;
417- code = cf .getCloseCode ();
418- reason = cf .getMessage ();
419- }
420- if ( readystate == READYSTATE .CLOSING ) {
421- // complete the close handshake by disconnecting
422- closeConnection ( code , reason , true );
423- } else {
424- // echo close handshake
425- if ( draft .getCloseHandshakeType () == CloseHandshakeType .TWOWAY )
426- close ( code , reason , true );
427- else
428- flushAndClose ( code , reason , false );
429- }
430- continue ;
431- } else if ( curop == Opcode .PING ) {
432- wsl .onWebsocketPing ( this , f );
433- continue ;
434- } else if ( curop == Opcode .PONG ) {
435- lastPong = System .currentTimeMillis ();
436- wsl .onWebsocketPong ( this , f );
437- continue ;
438- } else if ( !fin || curop == Opcode .CONTINUOUS ) {
439- if ( curop != Opcode .CONTINUOUS ) {
440- if ( current_continuous_frame != null )
441- throw new InvalidDataException ( CloseFrame .PROTOCOL_ERROR , "Previous continuous frame sequence not completed." );
442- current_continuous_frame = f ;
443- } else if ( fin ) {
444- if ( current_continuous_frame == null )
445- throw new InvalidDataException ( CloseFrame .PROTOCOL_ERROR , "Continuous frame sequence was not started." );
446- //Check if the whole payload is valid utf8, when the opcode indicates a text
447- if ( current_continuous_frame .getOpcode () == Opcode .TEXT ) {
448- //Checking a bit more from the frame before this one just to make sure all the code points are correct
449- int off = Math .max ( current_continuous_frame .getPayloadData ().limit () - 64 , 0 );
450- current_continuous_frame .append ( f );
451- if ( !Charsetfunctions .isValidUTF8 ( current_continuous_frame .getPayloadData (), off ) ) {
452- throw new InvalidDataException ( CloseFrame .NO_UTF8 );
453- }
454- }
455- current_continuous_frame = null ;
456- } else if ( current_continuous_frame == null ) {
457- throw new InvalidDataException ( CloseFrame .PROTOCOL_ERROR , "Continuous frame sequence was not started." );
458- }
459- //Check if the whole payload is valid utf8, when the opcode indicates a text
460- if ( curop == Opcode .TEXT ) {
461- if ( !Charsetfunctions .isValidUTF8 ( f .getPayloadData () ) ) {
462- throw new InvalidDataException ( CloseFrame .NO_UTF8 );
463- }
464- }
465- //Checking if the current continous frame contains a correct payload with the other frames combined
466- if ( curop == Opcode .CONTINUOUS && current_continuous_frame != null && current_continuous_frame .getOpcode () == Opcode .TEXT ) {
467- //Checking a bit more from the frame before this one just to make sure all the code points are correct
468- int off = Math .max ( current_continuous_frame .getPayloadData ().limit () - 64 , 0 );
469- current_continuous_frame .append ( f );
470- if ( !Charsetfunctions .isValidUTF8 ( current_continuous_frame .getPayloadData (), off ) ) {
471- throw new InvalidDataException ( CloseFrame .NO_UTF8 );
472- }
473- }
474- try {
475- wsl .onWebsocketMessageFragment ( this , f );
476- } catch ( RuntimeException e ) {
477- wsl .onWebsocketError ( this , e );
478- }
479-
480- } else if ( current_continuous_frame != null ) {
481- throw new InvalidDataException ( CloseFrame .PROTOCOL_ERROR , "Continuous frame sequence not completed." );
482- } else if ( curop == Opcode .TEXT ) {
483- try {
484- wsl .onWebsocketMessage ( this , Charsetfunctions .stringUtf8 ( f .getPayloadData () ) );
485- } catch ( RuntimeException e ) {
486- wsl .onWebsocketError ( this , e );
487- }
488- } else if ( curop == Opcode .BINARY ) {
489- try {
490- wsl .onWebsocketMessage ( this , f .getPayloadData () );
491- } catch ( RuntimeException e ) {
492- wsl .onWebsocketError ( this , e );
493- }
494- } else {
495- throw new InvalidDataException ( CloseFrame .PROTOCOL_ERROR , "non control or continious frame expected" );
496- }
497- }
498- } catch ( InvalidDataException e1 ) {
499- wsl .onWebsocketError ( this , e1 );
500- close ( e1 );
501- return ;
502- }
503-
504- }
505-
506- private void close ( int code , String message , boolean remote ) {
405+ public void close ( int code , String message , boolean remote ) {
507406 if ( readystate != READYSTATE .CLOSING && readystate != READYSTATE .CLOSED ) {
508407 if ( readystate == READYSTATE .OPEN ) {
509408 if ( code == CloseFrame .ABNORMAL_CLOSE ) {
@@ -524,13 +423,8 @@ private void close( int code, String message, boolean remote ) {
524423 CloseFrame closeFrame = new CloseFrame ();
525424 closeFrame .setReason (message );
526425 closeFrame .setCode (code );
527- try {
528- closeFrame .isValid ();
529- sendFrame (closeFrame );
530- } catch (InvalidDataException e ) {
531- //Rethrow invalid data exception
532- throw e ;
533- }
426+ closeFrame .isValid ();
427+ sendFrame (closeFrame );
534428 } catch ( InvalidDataException e ) {
535429 wsl .onWebsocketError ( this , e );
536430 flushAndClose ( CloseFrame .ABNORMAL_CLOSE , "generated frame is invalid" , false );
@@ -566,7 +460,7 @@ public void close( int code, String message ) {
566460 * false means this endpoint decided to send the given code,<br>
567461 * <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>
568462 **/
569- protected synchronized void closeConnection ( int code , String message , boolean remote ) {
463+ public synchronized void closeConnection ( int code , String message , boolean remote ) {
570464 if ( readystate == READYSTATE .CLOSED ) {
571465 return ;
572466 }
@@ -610,7 +504,7 @@ public void closeConnection( int code, String message ) {
610504 closeConnection ( code , message , false );
611505 }
612506
613- protected synchronized void flushAndClose ( int code , String message , boolean remote ) {
507+ public synchronized void flushAndClose ( int code , String message , boolean remote ) {
614508 if ( flushandclosestate ) {
615509 return ;
616510 }
@@ -694,7 +588,7 @@ private void send( Collection<Framedata> frames ) {
694588 for (Framedata f : frames ) {
695589 if ( DEBUG )
696590 System .out .println ( "send frame: " + f );
697- outgoingFrames .add ( draft .createBinaryFrame ( f ) );
591+ outgoingFrames .add ( draft .createBinaryFrame ( f ) );
698592 }
699593 write ( outgoingFrames );
700594 }
@@ -868,4 +762,16 @@ public String getResourceDescriptor() {
868762 long getLastPong () {
869763 return lastPong ;
870764 }
765+
766+ public void setLastPong ( long lastPong ) {
767+ this .lastPong = lastPong ;
768+ }
769+
770+ /**
771+ * Getter for the websocket listener
772+ * @return the websocket listener associated with this instance
773+ */
774+ public WebSocketListener getWebSocketListener () {
775+ return wsl ;
776+ }
871777}
0 commit comments