@@ -221,12 +221,7 @@ public async override Task<WebSocketReceiveResult> ReceiveAsync(ArraySegment<byt
221221 {
222222 if ( ! _firstDataOpCode . HasValue )
223223 {
224- if ( State == WebSocketState . Open )
225- {
226- await CloseOutputAsync ( WebSocketCloseStatus . ProtocolError , "Invalid continuation frame" , cancellationToken ) ;
227- Abort ( ) ;
228- }
229- throw new InvalidOperationException ( "A continuation can't be the first frame" ) ; // TODO: WebSocketException
224+ await SendErrorAbortAndThrow ( WebSocketCloseStatus . ProtocolError , "Invalid continuation frame" , cancellationToken ) ;
230225 }
231226 opCode = _firstDataOpCode . Value ;
232227 }
@@ -261,12 +256,7 @@ public async override Task<WebSocketReceiveResult> ReceiveAsync(ArraySegment<byt
261256 if ( messageType == WebSocketMessageType . Text
262257 && ! Utilities . TryValidateUtf8 ( new ArraySegment < byte > ( buffer . Array , buffer . Offset , bytesToCopy ) , _frameInProgress . Fin , _incomingUtf8MessageState ) )
263258 {
264- if ( State == WebSocketState . Open )
265- {
266- await CloseOutputAsync ( WebSocketCloseStatus . InvalidPayloadData , "Invalid UTF-8" , cancellationToken ) ;
267- Abort ( ) ;
268- }
269- throw new InvalidOperationException ( "An invalid UTF-8 payload was received." ) ; // TODO: WebSocketException
259+ await SendErrorAbortAndThrow ( WebSocketCloseStatus . InvalidPayloadData , "Invalid UTF-8" , cancellationToken ) ;
270260 }
271261
272262 if ( bytesToCopy == _frameBytesRemaining )
@@ -303,47 +293,41 @@ private async Task ReadNextFrameAsync(CancellationToken cancellationToken)
303293
304294 if ( _frameInProgress . AreReservedSet ( ) )
305295 {
306- if ( State == WebSocketState . Open )
307- {
308- await CloseOutputAsync ( WebSocketCloseStatus . ProtocolError , "Unexpected reserved bits set" , cancellationToken ) ;
309- Abort ( ) ;
310- }
311- throw new InvalidOperationException ( "Unexpected reserved bits are set." ) ; // TODO: WebSocketException
296+ await SendErrorAbortAndThrow ( WebSocketCloseStatus . ProtocolError , "Unexpected reserved bits set" , cancellationToken ) ;
312297 }
313298
314299 if ( _unmaskInput != _frameInProgress . Masked )
315300 {
316- if ( State == WebSocketState . Open )
317- {
318- await CloseOutputAsync ( WebSocketCloseStatus . ProtocolError , "Incorrect masking" , cancellationToken ) ;
319- Abort ( ) ;
320- }
321- throw new InvalidOperationException ( "Unmasking settings out of sync with data." ) ; // TODO: WebSocketException
301+ await SendErrorAbortAndThrow ( WebSocketCloseStatus . ProtocolError , "Incorrect masking" , cancellationToken ) ;
322302 }
323303
324- if ( _frameInProgress . OpCode == Constants . OpCodes . PingFrame || _frameInProgress . OpCode == Constants . OpCodes . PongFrame )
304+ if ( _frameInProgress . IsControlFrame )
325305 {
326306 if ( _frameBytesRemaining > 125 )
327307 {
328- if ( State == WebSocketState . Open )
329- {
330- await CloseOutputAsync ( WebSocketCloseStatus . ProtocolError , "Invalid control frame size" , cancellationToken ) ;
331- Abort ( ) ;
332- }
333- throw new InvalidOperationException ( "Control frame too large." ) ; // TODO: WebSocketException
308+ await SendErrorAbortAndThrow ( WebSocketCloseStatus . ProtocolError , "Invalid control frame size" , cancellationToken ) ;
334309 }
335- // Drain it, should be less than 125 bytes
336- await EnsureDataAvailableOrReadAsync ( ( int ) _frameBytesRemaining , cancellationToken ) ;
337310
338- if ( _frameInProgress . OpCode == Constants . OpCodes . PingFrame )
311+ if ( ! _frameInProgress . Fin )
339312 {
340- await SendPongReplyAsync ( cancellationToken ) ;
313+ await SendErrorAbortAndThrow ( WebSocketCloseStatus . ProtocolError , "Fragmented control frame" , cancellationToken ) ;
341314 }
342315
343- _receiveBufferOffset += ( int ) _frameBytesRemaining ;
344- _receiveBufferBytes -= ( int ) _frameBytesRemaining ;
345- _frameBytesRemaining = 0 ;
346- _frameInProgress = null ;
316+ if ( _frameInProgress . OpCode == Constants . OpCodes . PingFrame || _frameInProgress . OpCode == Constants . OpCodes . PongFrame )
317+ {
318+ // Drain it, should be less than 125 bytes
319+ await EnsureDataAvailableOrReadAsync ( ( int ) _frameBytesRemaining , cancellationToken ) ;
320+
321+ if ( _frameInProgress . OpCode == Constants . OpCodes . PingFrame )
322+ {
323+ await SendPongReplyAsync ( cancellationToken ) ;
324+ }
325+
326+ _receiveBufferOffset += ( int ) _frameBytesRemaining ;
327+ _receiveBufferBytes -= ( int ) _frameBytesRemaining ;
328+ _frameBytesRemaining = 0 ;
329+ _frameInProgress = null ;
330+ }
347331 }
348332 }
349333
@@ -587,5 +571,15 @@ private void ValidateSegment(ArraySegment<byte> buffer)
587571 throw new ArgumentOutOfRangeException ( "buffer.Count" , buffer . Count , string . Empty ) ;
588572 }
589573 }
574+
575+ private async Task SendErrorAbortAndThrow ( WebSocketCloseStatus error , string message , CancellationToken cancellationToken )
576+ {
577+ if ( State == WebSocketState . Open )
578+ {
579+ await CloseOutputAsync ( error , message , cancellationToken ) ;
580+ }
581+ Abort ( ) ;
582+ throw new InvalidOperationException ( message ) ; // TODO: WebSocketException
583+ }
590584 }
591585}
0 commit comments