@@ -253,7 +253,7 @@ public bool PerformServerUpgrade(HttpRequest request, HttpResponse response)
253253 /// <param name="status">WebSocket status (default is 0)</param>
254254 public void PrepareSendFrame ( byte opcode , bool mask , ReadOnlySpan < byte > buffer , int status = 0 )
255255 {
256- int size = buffer . Length ;
256+ long size = ( ( ( opcode & WS_CLOSE ) == WS_CLOSE ) && ( buffer . Length > 0 ) ) ? ( buffer . Length + 2 ) : buffer . Length ;
257257
258258 // Clear the previous WebSocket send buffer
259259 WsSendBuffer . Clear ( ) ;
@@ -263,7 +263,7 @@ public void PrepareSendFrame(byte opcode, bool mask, ReadOnlySpan<byte> buffer,
263263
264264 // Append WebSocket frame size
265265 if ( size <= 125 )
266- WsSendBuffer . Append ( ( byte ) ( ( size & 0xFF ) | ( mask ? 0x80 : 0 ) ) ) ;
266+ WsSendBuffer . Append ( ( byte ) ( ( ( int ) size & 0xFF ) | ( mask ? 0x80 : 0 ) ) ) ;
267267 else if ( size <= 65535 )
268268 {
269269 WsSendBuffer . Append ( ( byte ) ( 126 | ( mask ? 0x80 : 0 ) ) ) ;
@@ -284,11 +284,21 @@ public void PrepareSendFrame(byte opcode, bool mask, ReadOnlySpan<byte> buffer,
284284 }
285285
286286 // Resize WebSocket frame buffer
287- int offset = ( int ) WsSendBuffer . Size ;
287+ long offset = WsSendBuffer . Size ;
288288 WsSendBuffer . Resize ( WsSendBuffer . Size + size ) ;
289289
290+ int index = 0 ;
291+
292+ // Append WebSocket close status
293+ if ( ( ( opcode & WS_CLOSE ) == WS_CLOSE ) && ( buffer . Length > 0 ) )
294+ {
295+ index += 2 ;
296+ WsSendBuffer . Append ( ( byte ) ( ( status >> 8 ) & 0xFF ) ) ;
297+ WsSendBuffer . Append ( ( byte ) ( status & 0xFF ) ) ;
298+ }
299+
290300 // Mask WebSocket frame content
291- for ( int i = 0 ; i < size ; i ++ )
301+ for ( int i = index ; i < size ; i ++ )
292302 WsSendBuffer . Data [ offset + i ] = ( byte ) ( buffer [ i ] ^ WsSendMask [ i % 4 ] ) ;
293303 }
294304
@@ -302,7 +312,7 @@ public void PrepareReceiveFrame(byte[] buffer, long offset, long size)
302312 {
303313 lock ( WsReceiveLock )
304314 {
305- var index = 0 ;
315+ int index = 0 ;
306316
307317 // Clear received data after WebSocket frame was processed
308318 if ( WsFrameReceived )
@@ -339,7 +349,7 @@ public void PrepareReceiveFrame(byte[] buffer, long offset, long size)
339349 // Prepare WebSocket frame opcode and mask flag
340350 if ( WsReceiveFrameBuffer . Size < 2 )
341351 {
342- for ( int i = 0 ; i < 2 ; i ++ , index ++ , size -- )
352+ for ( long i = 0 ; i < 2 ; i ++ , index ++ , size -- )
343353 {
344354 if ( size == 0 )
345355 return ;
@@ -350,7 +360,7 @@ public void PrepareReceiveFrame(byte[] buffer, long offset, long size)
350360 byte opcode = ( byte ) ( WsReceiveFrameBuffer [ 0 ] & 0x0F ) ;
351361 bool fin = ( ( WsReceiveFrameBuffer [ 0 ] >> 7 ) & 0x01 ) != 0 ;
352362 bool mask = ( ( WsReceiveFrameBuffer [ 1 ] >> 7 ) & 0x01 ) != 0 ;
353- int payload = WsReceiveFrameBuffer [ 1 ] & ( ~ 0x80 ) ;
363+ long payload = WsReceiveFrameBuffer [ 1 ] & ( ~ 0x80 ) ;
354364
355365 // Prepare WebSocket opcode
356366 WsOpcode = ( opcode != 0 ) ? opcode : WsOpcode ;
@@ -365,7 +375,7 @@ public void PrepareReceiveFrame(byte[] buffer, long offset, long size)
365375 {
366376 if ( WsReceiveFrameBuffer . Size < 4 )
367377 {
368- for ( int i = 0 ; i < 2 ; i ++ , index ++ , size -- )
378+ for ( long i = 0 ; i < 2 ; i ++ , index ++ , size -- )
369379 {
370380 if ( size == 0 )
371381 return ;
@@ -381,7 +391,7 @@ public void PrepareReceiveFrame(byte[] buffer, long offset, long size)
381391 {
382392 if ( WsReceiveFrameBuffer . Size < 10 )
383393 {
384- for ( int i = 0 ; i < 8 ; i ++ , index ++ , size -- )
394+ for ( long i = 0 ; i < 8 ; i ++ , index ++ , size -- )
385395 {
386396 if ( size == 0 )
387397 return ;
@@ -399,7 +409,7 @@ public void PrepareReceiveFrame(byte[] buffer, long offset, long size)
399409 {
400410 if ( WsReceiveFrameBuffer . Size < WsHeaderSize )
401411 {
402- for ( int i = 0 ; i < 4 ; i ++ , index ++ , size -- )
412+ for ( long i = 0 ; i < 4 ; i ++ , index ++ , size -- )
403413 {
404414 if ( size == 0 )
405415 return ;
@@ -409,12 +419,12 @@ public void PrepareReceiveFrame(byte[] buffer, long offset, long size)
409419 }
410420 }
411421
412- int total = WsHeaderSize + WsPayloadSize ;
413- int length = Math . Min ( total - ( int ) WsReceiveFrameBuffer . Size , ( int ) size ) ;
422+ long total = WsHeaderSize + WsPayloadSize ;
423+ long length = Math . Min ( total - WsReceiveFrameBuffer . Size , size ) ;
414424
415425 // Prepare WebSocket frame payload
416- WsReceiveFrameBuffer . Append ( buffer [ ( ( int ) offset + index ) ..( ( int ) offset + index + length ) ] ) ;
417- index += length ;
426+ WsReceiveFrameBuffer . Append ( buffer [ ( ( int ) offset + index ) ..( ( int ) offset + index + ( int ) length ) ] ) ;
427+ index += ( int ) length ;
418428 size -= length ;
419429
420430 // Process WebSocket frame
@@ -423,11 +433,11 @@ public void PrepareReceiveFrame(byte[] buffer, long offset, long size)
423433 // Unmask WebSocket frame content
424434 if ( mask )
425435 {
426- for ( int i = 0 ; i < WsPayloadSize ; i ++ )
436+ for ( long i = 0 ; i < WsPayloadSize ; i ++ )
427437 WsReceiveFinalBuffer . Append ( ( byte ) ( WsReceiveFrameBuffer [ WsHeaderSize + i ] ^ WsReceiveMask [ i % 4 ] ) ) ;
428438 }
429439 else
430- WsReceiveFinalBuffer . Append ( WsReceiveFrameBuffer . AsSpan ( ) . Slice ( WsHeaderSize , WsPayloadSize ) ) ;
440+ WsReceiveFinalBuffer . Append ( WsReceiveFrameBuffer . AsSpan ( ) . Slice ( ( int ) WsHeaderSize , ( int ) WsPayloadSize ) ) ;
431441
432442 WsFrameReceived = true ;
433443
@@ -452,8 +462,18 @@ public void PrepareReceiveFrame(byte[] buffer, long offset, long size)
452462 }
453463 case WS_CLOSE :
454464 {
465+ int sindex = 0 ;
466+ int status = 1000 ;
467+
468+ // Read WebSocket close status
469+ if ( WsReceiveFinalBuffer . Size > 2 )
470+ {
471+ sindex += 2 ;
472+ status = ( ( WsReceiveFinalBuffer [ 0 ] << 8 ) | ( WsReceiveFinalBuffer [ 1 ] << 0 ) ) ;
473+ }
474+
455475 // Call the WebSocket close handler
456- _wsHandler . OnWsClose ( WsReceiveFinalBuffer . Data , 0 , WsReceiveFinalBuffer . Size ) ;
476+ _wsHandler . OnWsClose ( WsReceiveFinalBuffer . Data , sindex , WsReceiveFinalBuffer . Size - sindex , status ) ;
457477 break ;
458478 }
459479 case WS_BINARY :
@@ -473,7 +493,7 @@ public void PrepareReceiveFrame(byte[] buffer, long offset, long size)
473493 /// <summary>
474494 /// Required WebSocket receive frame size
475495 /// </summary>
476- public int RequiredReceiveFrameSize ( )
496+ public long RequiredReceiveFrameSize ( )
477497 {
478498 lock ( WsReceiveLock )
479499 {
@@ -482,23 +502,23 @@ public int RequiredReceiveFrameSize()
482502
483503 // Required WebSocket frame opcode and mask flag
484504 if ( WsReceiveFrameBuffer . Size < 2 )
485- return 2 - ( int ) WsReceiveFrameBuffer . Size ;
505+ return 2 - WsReceiveFrameBuffer . Size ;
486506
487507 bool mask = ( ( WsReceiveFrameBuffer [ 1 ] >> 7 ) & 0x01 ) != 0 ;
488- int payload = WsReceiveFrameBuffer [ 1 ] & ( ~ 0x80 ) ;
508+ long payload = WsReceiveFrameBuffer [ 1 ] & ( ~ 0x80 ) ;
489509
490510 // Required WebSocket frame size
491511 if ( ( payload == 126 ) && ( WsReceiveFrameBuffer . Size < 4 ) )
492- return 4 - ( int ) WsReceiveFrameBuffer . Size ;
512+ return 4 - WsReceiveFrameBuffer . Size ;
493513 if ( ( payload == 127 ) && ( WsReceiveFrameBuffer . Size < 10 ) )
494- return 10 - ( int ) WsReceiveFrameBuffer . Size ;
514+ return 10 - WsReceiveFrameBuffer . Size ;
495515
496516 // Required WebSocket frame mask
497517 if ( ( mask ) & & ( WsReceiveFrameBuffer . Size < WsHeaderSize ) )
498- return WsHeaderSize - ( int ) WsReceiveFrameBuffer . Size ;
518+ return WsHeaderSize - WsReceiveFrameBuffer . Size ;
499519
500520 // Required WebSocket frame payload
501- return WsHeaderSize + WsPayloadSize - ( int ) WsReceiveFrameBuffer . Size ;
521+ return WsHeaderSize + WsPayloadSize - WsReceiveFrameBuffer . Size ;
502522 }
503523 }
504524
@@ -561,15 +581,15 @@ public void ClearWsBuffers()
561581 /// <summary>
562582 /// Received frame opcode
563583 /// </summary>
564- internal int WsOpcode ;
584+ internal byte WsOpcode ;
565585 /// <summary>
566586 /// Received frame header size
567587 /// </summary>
568- internal int WsHeaderSize ;
588+ internal long WsHeaderSize ;
569589 /// <summary>
570590 /// Received frame payload size
571591 /// </summary>
572- internal int WsPayloadSize ;
592+ internal long WsPayloadSize ;
573593
574594 /// <summary>
575595 /// Receive buffer lock
0 commit comments