@@ -221,12 +221,7 @@ public async override Task<WebSocketReceiveResult> ReceiveAsync(ArraySegment<byt
221
221
{
222
222
if ( ! _firstDataOpCode . HasValue )
223
223
{
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 ) ;
230
225
}
231
226
opCode = _firstDataOpCode . Value ;
232
227
}
@@ -261,12 +256,7 @@ public async override Task<WebSocketReceiveResult> ReceiveAsync(ArraySegment<byt
261
256
if ( messageType == WebSocketMessageType . Text
262
257
&& ! Utilities . TryValidateUtf8 ( new ArraySegment < byte > ( buffer . Array , buffer . Offset , bytesToCopy ) , _frameInProgress . Fin , _incomingUtf8MessageState ) )
263
258
{
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 ) ;
270
260
}
271
261
272
262
if ( bytesToCopy == _frameBytesRemaining )
@@ -303,47 +293,41 @@ private async Task ReadNextFrameAsync(CancellationToken cancellationToken)
303
293
304
294
if ( _frameInProgress . AreReservedSet ( ) )
305
295
{
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 ) ;
312
297
}
313
298
314
299
if ( _unmaskInput != _frameInProgress . Masked )
315
300
{
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 ) ;
322
302
}
323
303
324
- if ( _frameInProgress . OpCode == Constants . OpCodes . PingFrame || _frameInProgress . OpCode == Constants . OpCodes . PongFrame )
304
+ if ( _frameInProgress . IsControlFrame )
325
305
{
326
306
if ( _frameBytesRemaining > 125 )
327
307
{
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 ) ;
334
309
}
335
- // Drain it, should be less than 125 bytes
336
- await EnsureDataAvailableOrReadAsync ( ( int ) _frameBytesRemaining , cancellationToken ) ;
337
310
338
- if ( _frameInProgress . OpCode == Constants . OpCodes . PingFrame )
311
+ if ( ! _frameInProgress . Fin )
339
312
{
340
- await SendPongReplyAsync ( cancellationToken ) ;
313
+ await SendErrorAbortAndThrow ( WebSocketCloseStatus . ProtocolError , "Fragmented control frame" , cancellationToken ) ;
341
314
}
342
315
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
+ }
347
331
}
348
332
}
349
333
@@ -587,5 +571,15 @@ private void ValidateSegment(ArraySegment<byte> buffer)
587
571
throw new ArgumentOutOfRangeException ( "buffer.Count" , buffer . Count , string . Empty ) ;
588
572
}
589
573
}
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
+ }
590
584
}
591
585
}
0 commit comments