2222import org .java_websocket .drafts .Draft_76 ;
2323import org .java_websocket .exceptions .IncompleteHandshakeException ;
2424import org .java_websocket .exceptions .InvalidDataException ;
25- import org .java_websocket .exceptions .InvalidFrameException ;
2625import org .java_websocket .exceptions .InvalidHandshakeException ;
2726import org .java_websocket .exceptions .WebsocketNotConnectedException ;
2827import org .java_websocket .framing .CloseFrame ;
@@ -89,8 +88,7 @@ public class WebSocketImpl extends WebSocket {
8988
9089 private Role role ;
9190
92- /** used to join continuous frames */
93- private Framedata tempContiniousFrame ;// FIXME out of mem risk
91+ private Opcode current_continuous_frame_opcode = null ;
9492
9593 /** the bytes of an incomplete received handshake */
9694 private ByteBuffer tmpHandshakeBytes ;
@@ -292,7 +290,7 @@ private boolean decodeHandshake( ByteBuffer socketBufferNew ) {
292290 private void decodeFrames ( ByteBuffer socketBuffer ) {
293291 if ( flushandclosestate )
294292 return ;
295- assert ( ! isClosed () );
293+
296294 List <Framedata > frames ;
297295 try {
298296 frames = draft .translateFrame ( socketBuffer );
@@ -302,6 +300,8 @@ private void decodeFrames( ByteBuffer socketBuffer ) {
302300 if ( flushandclosestate )
303301 return ;
304302 Opcode curop = f .getOpcode ();
303+ boolean fin = f .isFin ();
304+
305305 if ( curop == Opcode .CLOSING ) {
306306 int code = CloseFrame .NOCODE ;
307307 String reason = "" ;
@@ -327,27 +327,40 @@ private void decodeFrames( ByteBuffer socketBuffer ) {
327327 } else if ( curop == Opcode .PONG ) {
328328 wsl .onWebsocketPong ( this , f );
329329 continue ;
330- } else {
331- // process non control frames
332- if ( tempContiniousFrame == null ) {
333- if ( f .getOpcode () == Opcode .CONTINUOUS ) {
334- throw new InvalidFrameException ( "unexpected continious frame" );
335- } else if ( f .isFin () ) {
336- // receive normal onframe message
337- deliverMessage ( f );
338- } else {
339- // remember the frame whose payload is about to be continued
340- tempContiniousFrame = f ;
341- }
342- } else if ( f .getOpcode () == Opcode .CONTINUOUS ) {
343- tempContiniousFrame .append ( f );
344- if ( f .isFin () ) {
345- deliverMessage ( tempContiniousFrame );
346- tempContiniousFrame = null ;
347- }
348- } else {
349- throw new InvalidDataException ( CloseFrame .PROTOCOL_ERROR , "non control or continious frame expected" );
330+ } else if ( !fin || curop == Opcode .CONTINUOUS ) {
331+ if ( curop != Opcode .CONTINUOUS ) {
332+ if ( current_continuous_frame_opcode != null )
333+ throw new InvalidDataException ( CloseFrame .PROTOCOL_ERROR , "Previous continuous frame sequence not completed." );
334+ current_continuous_frame_opcode = curop ;
335+ } else if ( fin ) {
336+ if ( current_continuous_frame_opcode == null )
337+ throw new InvalidDataException ( CloseFrame .PROTOCOL_ERROR , "Continuous frame sequence was not started." );
338+ current_continuous_frame_opcode = null ;
339+ } else if ( current_continuous_frame_opcode == null ) {
340+ throw new InvalidDataException ( CloseFrame .PROTOCOL_ERROR , "Continuous frame sequence was not started." );
341+ }
342+ try {
343+ wsl .onWebsocketMessageFragment ( this , f );
344+ } catch ( RuntimeException e ) {
345+ wsl .onWebsocketError ( this , e );
346+ }
347+
348+ } else if ( current_continuous_frame_opcode != null ) {
349+ throw new InvalidDataException ( CloseFrame .PROTOCOL_ERROR , "Continuous frame sequence not completed." );
350+ } else if ( curop == Opcode .TEXT ) {
351+ try {
352+ wsl .onWebsocketMessage ( this , Charsetfunctions .stringUtf8 ( f .getPayloadData () ) );
353+ } catch ( RuntimeException e ) {
354+ wsl .onWebsocketError ( this , e );
350355 }
356+ } else if ( curop == Opcode .BINARY ) {
357+ try {
358+ wsl .onWebsocketMessage ( this , f .getPayloadData () );
359+ } catch ( RuntimeException e ) {
360+ wsl .onWebsocketError ( this , e );
361+ }
362+ } else {
363+ throw new InvalidDataException ( CloseFrame .PROTOCOL_ERROR , "non control or continious frame expected" );
351364 }
352365 }
353366 } catch ( InvalidDataException e1 ) {
@@ -431,7 +444,6 @@ protected synchronized void closeConnection( int code, String message, boolean r
431444 }
432445 if ( draft != null )
433446 draft .reset ();
434- tempContiniousFrame = null ;
435447 handshakerequest = null ;
436448
437449 readystate = READYSTATE .CLOSED ;
@@ -471,7 +483,6 @@ protected synchronized void flushAndClose( int code, String message, boolean rem
471483 }
472484 if ( draft != null )
473485 draft .reset ();
474- tempContiniousFrame = null ;
475486 handshakerequest = null ;
476487 }
477488
@@ -611,22 +622,6 @@ private void write( List<ByteBuffer> bufs ) {
611622 }
612623 }
613624
614- private void deliverMessage ( Framedata d ) throws InvalidDataException {
615- try {
616- if ( d .getOpcode () == Opcode .TEXT ) {
617- wsl .onWebsocketMessage ( this , Charsetfunctions .stringUtf8 ( d .getPayloadData () ) );
618- } else if ( d .getOpcode () == Opcode .BINARY ) {
619- wsl .onWebsocketMessage ( this , d .getPayloadData () );
620- } else {
621- if ( DEBUG )
622- System .out .println ( "Ignoring frame:" + d .toString () );
623- assert ( false );
624- }
625- } catch ( RuntimeException e ) {
626- wsl .onWebsocketError ( this , e );
627- }
628- }
629-
630625 private void open ( Handshakedata d ) {
631626 if ( DEBUG )
632627 System .out .println ( "open using draft: " + draft .getClass ().getSimpleName () );
0 commit comments