Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
ManagedWebSocket.cs
Go to the documentation of this file.
3using System.IO;
9using System.Text;
12
13namespace System.Net.WebSockets;
14
15internal sealed class ManagedWebSocket : WebSocket
16{
17 private sealed class Utf8MessageState
18 {
19 internal bool SequenceInProgress;
20
22
23 internal int ExpectedValueMin;
24
25 internal int CurrentDecodeBits;
26 }
27
28 private enum MessageOpcode : byte
29 {
30 Continuation = 0,
31 Text = 1,
32 Binary = 2,
33 Close = 8,
34 Ping = 9,
35 Pong = 10
36 }
37
38 [StructLayout(LayoutKind.Auto)]
39 private struct MessageHeader
40 {
42
43 internal bool Fin;
44
45 internal long PayloadLength;
46
47 internal bool Compressed;
48
49 internal int Mask;
50
51 internal bool Processed { get; set; }
52
53 internal bool EndOfMessage
54 {
55 get
56 {
57 if (Fin && Processed)
58 {
59 return PayloadLength == 0;
60 }
61 return false;
62 }
63 }
64 }
65
66 [StructLayout(LayoutKind.Auto)]
67 [CompilerGenerated]
69 {
71
73
75
77
79
81
83
85
87
89
91
93
94 private void MoveNext()
95 {
96 int num = _003C_003E1__state;
97 ManagedWebSocket managedWebSocket = _003C_003E4__this;
98 TResult receiveResult;
99 try
100 {
101 if ((uint)num > 7u)
102 {
104 {
105 ((ManagedWebSocket)s).Abort();
106 }, managedWebSocket);
107 }
108 try
109 {
111 if (num != 0)
112 {
113 if ((uint)(num - 1) <= 6u)
114 {
115 goto IL_00be;
116 }
117 awaiter = managedWebSocket._receiveMutex.EnterAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false).GetAwaiter();
118 if (!awaiter.IsCompleted)
119 {
120 num = (_003C_003E1__state = 0);
121 _003C_003Eu__1 = awaiter;
122 _003C_003Et__builder.AwaitUnsafeOnCompleted(ref awaiter, ref this);
123 return;
124 }
125 }
126 else
127 {
128 awaiter = _003C_003Eu__1;
130 num = (_003C_003E1__state = -1);
131 }
132 awaiter.GetResult();
133 goto IL_00be;
134 IL_00be:
135 try
136 {
144 Span<byte> span;
145 int result;
146 int num2;
147 long num4;
148 string text;
149 switch (num)
150 {
151 default:
152 _003Cheader_003E5__3 = managedWebSocket._lastReceiveHeader;
154 {
155 if (managedWebSocket._receiveBufferCount < (managedWebSocket._isServer ? 14 : 10))
156 {
157 if (managedWebSocket._receiveBufferCount < 2)
158 {
159 awaiter8 = managedWebSocket.EnsureBufferContainsAsync(2, cancellationToken).ConfigureAwait(continueOnCapturedContext: false).GetAwaiter();
160 if (!awaiter8.IsCompleted)
161 {
162 num = (_003C_003E1__state = 1);
163 _003C_003Eu__2 = awaiter8;
164 _003C_003Et__builder.AwaitUnsafeOnCompleted(ref awaiter8, ref this);
165 return;
166 }
167 goto IL_018d;
168 }
169 goto IL_0194;
170 }
171 goto IL_0264;
172 }
173 goto IL_0323;
174 case 1:
175 awaiter8 = _003C_003Eu__2;
177 num = (_003C_003E1__state = -1);
178 goto IL_018d;
179 case 2:
180 awaiter7 = _003C_003Eu__2;
182 num = (_003C_003E1__state = -1);
183 goto IL_025d;
184 case 3:
185 awaiter6 = _003C_003Eu__2;
187 num = (_003C_003E1__state = -1);
188 goto IL_02e4;
189 case 4:
190 awaiter5 = _003C_003Eu__2;
192 num = (_003C_003E1__state = -1);
193 goto IL_03b2;
194 case 5:
195 awaiter4 = _003C_003Eu__2;
197 num = (_003C_003E1__state = -1);
198 goto IL_0440;
199 case 6:
200 awaiter3 = _003C_003Eu__3;
201 _003C_003Eu__3 = default(ConfiguredValueTaskAwaitable<int>.ConfiguredValueTaskAwaiter);
202 num = (_003C_003E1__state = -1);
203 goto IL_06b5;
204 case 7:
205 {
206 awaiter2 = _003C_003Eu__2;
208 num = (_003C_003E1__state = -1);
209 goto IL_08c1;
210 }
211 IL_06f0:
212 if (managedWebSocket._isServer)
213 {
214 Span<byte> toMask;
216 {
217 span = payloadBuffer.Span;
218 toMask = span.Slice(0, _003CtotalBytesReceived_003E5__4);
219 }
220 else
221 {
222 span = managedWebSocket._inflater.Span;
223 toMask = span.Slice(0, _003CtotalBytesReceived_003E5__4);
224 }
225 managedWebSocket._receivedMaskOffsetOffset = ApplyMask(toMask, _003Cheader_003E5__3.Mask, managedWebSocket._receivedMaskOffsetOffset);
226 }
227 _003Cheader_003E5__3.PayloadLength -= _003CtotalBytesReceived_003E5__4;
229 {
231 }
232 goto IL_07ac;
233 IL_06b5:
234 result = awaiter3.GetResult();
235 num2 = result;
236 if (num2 <= 0)
237 {
238 managedWebSocket.ThrowIfEOFUnexpected(throwOnPrematureClosure: true);
239 goto IL_06f0;
240 }
242 goto IL_06df;
243 IL_0323:
245 {
246 awaiter5 = managedWebSocket.HandleReceivedPingPongAsync(_003Cheader_003E5__3, cancellationToken).ConfigureAwait(continueOnCapturedContext: false).GetAwaiter();
247 if (!awaiter5.IsCompleted)
248 {
249 num = (_003C_003E1__state = 4);
250 _003C_003Eu__2 = awaiter5;
251 _003C_003Et__builder.AwaitUnsafeOnCompleted(ref awaiter5, ref this);
252 return;
253 }
254 goto IL_03b2;
255 }
257 {
258 awaiter4 = managedWebSocket.HandleReceivedCloseAsync(_003Cheader_003E5__3, cancellationToken).ConfigureAwait(continueOnCapturedContext: false).GetAwaiter();
259 if (!awaiter4.IsCompleted)
260 {
261 num = (_003C_003E1__state = 5);
262 _003C_003Eu__2 = awaiter4;
263 _003C_003Et__builder.AwaitUnsafeOnCompleted(ref awaiter4, ref this);
264 return;
265 }
266 goto IL_0440;
267 }
268 if (_003Cheader_003E5__3.Opcode == MessageOpcode.Continuation)
269 {
270 _003Cheader_003E5__3.Opcode = managedWebSocket._lastReceiveHeader.Opcode;
271 _003Cheader_003E5__3.Compressed = managedWebSocket._lastReceiveHeader.Compressed;
272 }
274 {
277 {
279 {
281 }
282 int length;
284 {
286 }
287 else
288 {
289 span = managedWebSocket._inflater.Span;
290 length = span.Length;
291 }
293 if (managedWebSocket._receiveBufferCount > 0)
294 {
295 int num3 = Math.Min(_003Climit_003E5__5, managedWebSocket._receiveBufferCount);
296 span = managedWebSocket._receiveBuffer.Span;
297 span = span.Slice(managedWebSocket._receiveBufferOffset, num3);
299 managedWebSocket.ConsumeFromBuffer(num3);
301 }
302 goto IL_06df;
303 }
304 goto IL_07ac;
305 }
306 managedWebSocket._lastReceiveHeader = _003Cheader_003E5__3;
307 receiveResult = managedWebSocket.GetReceiveResult<TResult>(0, (_003Cheader_003E5__3.Opcode != MessageOpcode.Text) ? WebSocketMessageType.Binary : WebSocketMessageType.Text, _003Cheader_003E5__3.EndOfMessage);
308 goto end_IL_00be;
309 IL_07ac:
311 {
312 _003Cheader_003E5__3.Processed = managedWebSocket._inflater.Inflate(payloadBuffer.Span, out _003CtotalBytesReceived_003E5__4) && _003Cheader_003E5__3.PayloadLength == 0;
313 }
314 else
315 {
316 _003Cheader_003E5__3.Processed = _003Cheader_003E5__3.PayloadLength == 0;
317 }
319 {
320 break;
321 }
322 span = payloadBuffer.Span;
324 {
325 break;
326 }
327 awaiter2 = managedWebSocket.CloseWithReceiveErrorAndThrowAsync(WebSocketCloseStatus.InvalidPayloadData, WebSocketError.Faulted).ConfigureAwait(continueOnCapturedContext: false).GetAwaiter();
328 if (!awaiter2.IsCompleted)
329 {
330 num = (_003C_003E1__state = 7);
331 _003C_003Eu__2 = awaiter2;
332 _003C_003Et__builder.AwaitUnsafeOnCompleted(ref awaiter2, ref this);
333 return;
334 }
335 goto IL_08c1;
336 IL_06df:
338 {
340 if (!awaiter3.IsCompleted)
341 {
342 num = (_003C_003E1__state = 6);
343 _003C_003Eu__3 = awaiter3;
344 _003C_003Et__builder.AwaitUnsafeOnCompleted(ref awaiter3, ref this);
345 return;
346 }
347 goto IL_06b5;
348 }
349 goto IL_06f0;
350 IL_03b2:
351 awaiter5.GetResult();
352 goto default;
353 IL_025d:
354 awaiter7.GetResult();
355 goto IL_0264;
356 IL_018d:
357 awaiter8.GetResult();
358 goto IL_0194;
359 IL_0194:
360 span = managedWebSocket._receiveBuffer.Span;
361 num4 = span[managedWebSocket._receiveBufferOffset + 1] & 0x7F;
362 if (managedWebSocket._isServer || num4 > 125)
363 {
364 int minimumRequiredBytes = 2 + (managedWebSocket._isServer ? 4 : 0) + ((num4 > 125) ? ((num4 == 126) ? 2 : 8) : 0);
365 awaiter7 = managedWebSocket.EnsureBufferContainsAsync(minimumRequiredBytes, cancellationToken).ConfigureAwait(continueOnCapturedContext: false).GetAwaiter();
366 if (!awaiter7.IsCompleted)
367 {
368 num = (_003C_003E1__state = 2);
369 _003C_003Eu__2 = awaiter7;
370 _003C_003Et__builder.AwaitUnsafeOnCompleted(ref awaiter7, ref this);
371 return;
372 }
373 goto IL_025d;
374 }
375 goto IL_0264;
376 IL_08c1:
377 awaiter2.GetResult();
378 break;
379 IL_0264:
381 if (text != null)
382 {
383 awaiter6 = managedWebSocket.CloseWithReceiveErrorAndThrowAsync(WebSocketCloseStatus.ProtocolError, WebSocketError.Faulted, text).ConfigureAwait(continueOnCapturedContext: false).GetAwaiter();
384 if (!awaiter6.IsCompleted)
385 {
386 num = (_003C_003E1__state = 3);
387 _003C_003Eu__2 = awaiter6;
388 _003C_003Et__builder.AwaitUnsafeOnCompleted(ref awaiter6, ref this);
389 return;
390 }
391 goto IL_02e4;
392 }
393 goto IL_02eb;
394 IL_02e4:
395 awaiter6.GetResult();
396 goto IL_02eb;
397 IL_02eb:
398 managedWebSocket._receivedMaskOffsetOffset = 0;
400 {
401 managedWebSocket._inflater.AddBytes(0, _003Cheader_003E5__3.Fin);
402 }
403 goto IL_0323;
404 IL_0440:
405 awaiter4.GetResult();
406 receiveResult = managedWebSocket.GetReceiveResult<TResult>(0, WebSocketMessageType.Close, endOfMessage: true);
407 goto end_IL_00be;
408 }
409 managedWebSocket._lastReceiveHeader = _003Cheader_003E5__3;
410 receiveResult = managedWebSocket.GetReceiveResult<TResult>(_003CtotalBytesReceived_003E5__4, (_003Cheader_003E5__3.Opcode != MessageOpcode.Text) ? WebSocketMessageType.Binary : WebSocketMessageType.Text, _003Cheader_003E5__3.EndOfMessage);
411 end_IL_00be:;
412 }
413 finally
414 {
415 if (num < 0)
416 {
417 managedWebSocket._receiveMutex.Exit();
418 }
419 }
420 }
421 catch (Exception ex) when (!(ex is OperationCanceledException))
422 {
423 if (managedWebSocket._state == WebSocketState.Aborted)
424 {
425 throw new OperationCanceledException("Aborted", ex);
426 }
427 managedWebSocket.OnAborted();
428 if (ex is WebSocketException)
429 {
430 throw;
431 }
432 throw new WebSocketException(WebSocketError.ConnectionClosedPrematurely, ex);
433 }
434 finally
435 {
436 if (num < 0)
437 {
439 }
440 }
441 }
442 catch (Exception exception)
443 {
446 _003C_003Et__builder.SetException(exception);
447 return;
448 }
451 _003C_003Et__builder.SetResult(receiveResult);
452 }
453
455 {
456 //ILSpy generated this explicit interface implementation from .override directive in MoveNext
457 this.MoveNext();
458 }
459
460 [DebuggerHidden]
462 {
463 _003C_003Et__builder.SetStateMachine(stateMachine);
464 }
465
467 {
468 //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine
469 this.SetStateMachine(stateMachine);
470 }
471 }
472
473 [StructLayout(LayoutKind.Auto)]
474 [CompilerGenerated]
476 {
478
480
482
484
486
488
490
491 private void MoveNext()
492 {
493 int num = _003C_003E1__state;
494 ManagedWebSocket managedWebSocket = _003C_003E4__this;
495 try
496 {
498 if (num == 0)
499 {
500 awaiter = _003C_003Eu__1;
501 _003C_003Eu__1 = default(ConfiguredValueTaskAwaitable<int>.ConfiguredValueTaskAwaiter);
502 num = (_003C_003E1__state = -1);
503 goto IL_00ff;
504 }
505 if (managedWebSocket._receiveBufferCount < minimumRequiredBytes)
506 {
507 if (managedWebSocket._receiveBufferCount > 0)
508 {
509 Span<byte> span = managedWebSocket._receiveBuffer.Span;
510 span = span.Slice(managedWebSocket._receiveBufferOffset, managedWebSocket._receiveBufferCount);
511 span.CopyTo(managedWebSocket._receiveBuffer.Span);
512 }
513 managedWebSocket._receiveBufferOffset = 0;
514 goto IL_012b;
515 }
516 goto end_IL_000e;
517 IL_00ff:
518 int result = awaiter.GetResult();
519 int num2 = result;
520 if (num2 > 0)
521 {
522 managedWebSocket._receiveBufferCount += num2;
523 goto IL_012b;
524 }
526 goto end_IL_000e;
527 IL_012b:
528 if (managedWebSocket._receiveBufferCount < minimumRequiredBytes)
529 {
530 awaiter = managedWebSocket._stream.ReadAsync(managedWebSocket._receiveBuffer.Slice(managedWebSocket._receiveBufferCount, managedWebSocket._receiveBuffer.Length - managedWebSocket._receiveBufferCount), cancellationToken).ConfigureAwait(continueOnCapturedContext: false).GetAwaiter();
531 if (!awaiter.IsCompleted)
532 {
533 num = (_003C_003E1__state = 0);
534 _003C_003Eu__1 = awaiter;
535 _003C_003Et__builder.AwaitUnsafeOnCompleted(ref awaiter, ref this);
536 return;
537 }
538 goto IL_00ff;
539 }
540 end_IL_000e:;
541 }
542 catch (Exception exception)
543 {
546 return;
547 }
550 }
551
553 {
554 //ILSpy generated this explicit interface implementation from .override directive in MoveNext
555 this.MoveNext();
556 }
557
558 [DebuggerHidden]
563
565 {
566 //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine
567 this.SetStateMachine(stateMachine);
568 }
569 }
570
571 private static readonly UTF8Encoding s_textEncoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true);
572
573 private static readonly WebSocketState[] s_validSendStates = new WebSocketState[2]
574 {
575 WebSocketState.Open,
576 WebSocketState.CloseReceived
577 };
578
579 private static readonly WebSocketState[] s_validReceiveStates = new WebSocketState[2]
580 {
581 WebSocketState.Open,
582 WebSocketState.CloseSent
583 };
584
585 private static readonly WebSocketState[] s_validCloseOutputStates = new WebSocketState[2]
586 {
587 WebSocketState.Open,
588 WebSocketState.CloseReceived
589 };
590
591 private static readonly WebSocketState[] s_validCloseStates = new WebSocketState[3]
592 {
593 WebSocketState.Open,
594 WebSocketState.CloseReceived,
595 WebSocketState.CloseSent
596 };
597
598 private readonly Stream _stream;
599
600 private readonly bool _isServer;
601
602 private readonly string _subprotocol;
603
604 private readonly Timer _keepAliveTimer;
605
606 private readonly Memory<byte> _receiveBuffer;
607
609
610 private readonly AsyncMutex _sendMutex = new AsyncMutex();
611
612 private readonly AsyncMutex _receiveMutex = new AsyncMutex();
613
615
616 private bool _disposed;
617
618 private bool _sentCloseFrame;
619
621
623
625
627 {
628 Opcode = MessageOpcode.Text,
629 Fin = true,
630 Processed = true
631 };
632
634
636
638
639 private byte[] _sendBuffer;
640
642
644
645 private readonly WebSocketInflater _inflater;
646
647 private readonly WebSocketDeflater _deflater;
648
649 private object StateUpdateLock => _sendMutex;
650
652
654
655 public override WebSocketState State => _state;
656
657 public override string SubProtocol => _subprotocol;
658
659 internal ManagedWebSocket(Stream stream, bool isServer, string subprotocol, TimeSpan keepAliveInterval)
660 {
661 _stream = stream;
662 _isServer = isServer;
663 _subprotocol = subprotocol;
664 _receiveBuffer = new byte[125];
665 if (!(keepAliveInterval > TimeSpan.Zero))
666 {
667 return;
668 }
669 _keepAliveTimer = new Timer(delegate(object s)
670 {
672 if (weakReference.TryGetTarget(out var target))
673 {
674 target.SendKeepAliveFrameAsync();
675 }
676 }, new WeakReference<ManagedWebSocket>(this), keepAliveInterval, keepAliveInterval);
677 }
678
680 : this(stream, options.IsServer, options.SubProtocol, options.KeepAliveInterval)
681 {
682 WebSocketDeflateOptions dangerousDeflateOptions = options.DangerousDeflateOptions;
683 if (dangerousDeflateOptions != null)
684 {
685 if (options.IsServer)
686 {
687 _inflater = new WebSocketInflater(dangerousDeflateOptions.ClientMaxWindowBits, dangerousDeflateOptions.ClientContextTakeover);
688 _deflater = new WebSocketDeflater(dangerousDeflateOptions.ServerMaxWindowBits, dangerousDeflateOptions.ServerContextTakeover);
689 }
690 else
691 {
692 _inflater = new WebSocketInflater(dangerousDeflateOptions.ServerMaxWindowBits, dangerousDeflateOptions.ServerContextTakeover);
693 _deflater = new WebSocketDeflater(dangerousDeflateOptions.ClientMaxWindowBits, dangerousDeflateOptions.ClientContextTakeover);
694 }
695 }
696 }
697
698 public override void Dispose()
699 {
700 lock (StateUpdateLock)
701 {
702 DisposeCore();
703 }
704 }
705
706 private void DisposeCore()
707 {
708 if (!_disposed)
709 {
710 _disposed = true;
715 if (_state < WebSocketState.Aborted)
716 {
717 _state = WebSocketState.Closed;
718 }
719 }
720 }
721
723 {
724 if (messageType != 0 && messageType != WebSocketMessageType.Binary)
725 {
726 throw new ArgumentException(System.SR.Format(System.SR.net_WebSockets_Argument_InvalidMessageType, "Close", "SendAsync", "Binary", "Text", "CloseOutputAsync"), "messageType");
727 }
729 return SendAsync(buffer, messageType, endOfMessage ? WebSocketMessageFlags.EndOfMessage : WebSocketMessageFlags.None, cancellationToken).AsTask();
730 }
731
733 {
734 return SendAsync(buffer, messageType, endOfMessage ? WebSocketMessageFlags.EndOfMessage : WebSocketMessageFlags.None, cancellationToken);
735 }
736
738 {
739 if (messageType != 0 && messageType != WebSocketMessageType.Binary)
740 {
741 throw new ArgumentException(System.SR.Format(System.SR.net_WebSockets_Argument_InvalidMessageType, "Close", "SendAsync", "Binary", "Text", "CloseOutputAsync"), "messageType");
742 }
743 try
744 {
746 }
747 catch (Exception exception)
748 {
750 }
751 bool flag = messageFlags.HasFlag(WebSocketMessageFlags.EndOfMessage);
752 bool flag2 = messageFlags.HasFlag(WebSocketMessageFlags.DisableCompression);
753 MessageOpcode opcode;
755 {
757 {
759 }
760 opcode = MessageOpcode.Continuation;
761 }
762 else
763 {
764 opcode = ((messageType != WebSocketMessageType.Binary) ? MessageOpcode.Text : MessageOpcode.Binary);
765 }
766 ValueTask result = SendFrameAsync(opcode, flag, flag2, buffer, cancellationToken);
767 _lastSendWasFragment = !flag;
769 return result;
770 }
771
785
798
799 public override Task CloseAsync(WebSocketCloseStatus closeStatus, string statusDescription, CancellationToken cancellationToken)
800 {
801 WebSocketValidate.ValidateCloseStatus(closeStatus, statusDescription);
802 try
803 {
805 }
806 catch (Exception exception)
807 {
809 }
810 return CloseAsyncPrivate(closeStatus, statusDescription, cancellationToken);
811 }
812
813 public override Task CloseOutputAsync(WebSocketCloseStatus closeStatus, string statusDescription, CancellationToken cancellationToken)
814 {
815 WebSocketValidate.ValidateCloseStatus(closeStatus, statusDescription);
816 return CloseOutputAsyncCore(closeStatus, statusDescription, cancellationToken);
817 }
818
819 private async Task CloseOutputAsyncCore(WebSocketCloseStatus closeStatus, string statusDescription, CancellationToken cancellationToken)
820 {
822 await SendCloseFrameAsync(closeStatus, statusDescription, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
823 lock (StateUpdateLock)
824 {
826 {
827 DisposeCore();
828 }
829 }
830 }
831
832 public override void Abort()
833 {
834 OnAborted();
835 Dispose();
836 }
837
838 private void OnAborted()
839 {
840 lock (StateUpdateLock)
841 {
843 if (state != WebSocketState.Closed && state != WebSocketState.Aborted)
844 {
845 _state = ((state != 0 && state != WebSocketState.Connecting) ? WebSocketState.Aborted : WebSocketState.Closed);
846 }
847 }
848 }
849
850 private ValueTask SendFrameAsync(MessageOpcode opcode, bool endOfMessage, bool disableCompression, ReadOnlyMemory<byte> payloadBuffer, CancellationToken cancellationToken)
851 {
853 if (!cancellationToken.CanBeCanceled && task.IsCompletedSuccessfully)
854 {
855 return SendFrameLockAcquiredNonCancelableAsync(opcode, endOfMessage, disableCompression, payloadBuffer);
856 }
857 return SendFrameFallbackAsync(opcode, endOfMessage, disableCompression, payloadBuffer, task, cancellationToken);
858 }
859
860 private ValueTask SendFrameLockAcquiredNonCancelableAsync(MessageOpcode opcode, bool endOfMessage, bool disableCompression, ReadOnlyMemory<byte> payloadBuffer)
861 {
862 ValueTask valueTask = default(ValueTask);
863 bool flag = true;
864 try
865 {
866 int length = WriteFrameToSendBuffer(opcode, endOfMessage, disableCompression, payloadBuffer.Span);
868 if (valueTask.IsCompleted)
869 {
870 return valueTask;
871 }
872 flag = false;
873 }
874 catch (Exception ex)
875 {
876 return new ValueTask(Task.FromException((ex is OperationCanceledException) ? ex : ((_state == WebSocketState.Aborted) ? CreateOperationCanceledException(ex) : new WebSocketException(WebSocketError.ConnectionClosedPrematurely, ex))));
877 }
878 finally
879 {
880 if (flag)
881 {
884 }
885 }
886 return WaitForWriteTaskAsync(valueTask);
887 }
888
890 {
891 try
892 {
893 await writeTask.ConfigureAwait(continueOnCapturedContext: false);
894 }
895 catch (Exception ex) when (!(ex is OperationCanceledException))
896 {
897 throw (_state == WebSocketState.Aborted) ? CreateOperationCanceledException(ex) : new WebSocketException(WebSocketError.ConnectionClosedPrematurely, ex);
898 }
899 finally
900 {
903 }
904 }
905
906 private async ValueTask SendFrameFallbackAsync(MessageOpcode opcode, bool endOfMessage, bool disableCompression, ReadOnlyMemory<byte> payloadBuffer, Task lockTask, CancellationToken cancellationToken)
907 {
908 await lockTask.ConfigureAwait(continueOnCapturedContext: false);
909 try
910 {
911 int length = WriteFrameToSendBuffer(opcode, endOfMessage, disableCompression, payloadBuffer.Span);
912 using (cancellationToken.Register(delegate(object s)
913 {
914 ((ManagedWebSocket)s).Abort();
915 }, this))
916 {
917 await _stream.WriteAsync(new ReadOnlyMemory<byte>(_sendBuffer, 0, length), cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
918 }
919 }
920 catch (Exception ex) when (!(ex is OperationCanceledException))
921 {
922 throw (_state == WebSocketState.Aborted) ? CreateOperationCanceledException(ex, cancellationToken) : new WebSocketException(WebSocketError.ConnectionClosedPrematurely, ex);
923 }
924 finally
925 {
928 }
929 }
930
931 private int WriteFrameToSendBuffer(MessageOpcode opcode, bool endOfMessage, bool disableCompression, ReadOnlySpan<byte> payloadBuffer)
932 {
933 if (_deflater != null && !disableCompression)
934 {
935 payloadBuffer = _deflater.Deflate(payloadBuffer, endOfMessage);
936 }
937 int length = payloadBuffer.Length;
939 int? num = null;
940 int num2;
941 if (_isServer)
942 {
943 num2 = WriteHeader(opcode, _sendBuffer, payloadBuffer, endOfMessage, useMask: false, _deflater != null && !disableCompression);
944 }
945 else
946 {
947 num = WriteHeader(opcode, _sendBuffer, payloadBuffer, endOfMessage, useMask: true, _deflater != null && !disableCompression);
948 num2 = num.GetValueOrDefault() + 4;
949 }
950 if (payloadBuffer.Length > 0)
951 {
952 payloadBuffer.CopyTo(new Span<byte>(_sendBuffer, num2, length));
954 if (num.HasValue)
955 {
956 ApplyMask(new Span<byte>(_sendBuffer, num2, length), _sendBuffer, num.Value, 0);
957 }
958 }
959 return num2 + length;
960 }
961
963 {
964 ValueTask valueTask = SendFrameAsync(MessageOpcode.Pong, endOfMessage: true, disableCompression: true, ReadOnlyMemory<byte>.Empty, CancellationToken.None);
965 if (valueTask.IsCompletedSuccessfully)
966 {
967 valueTask.GetAwaiter().GetResult();
968 return;
969 }
970 valueTask.AsTask().ContinueWith(delegate(Task p)
971 {
972 _ = p.Exception;
973 }, CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
974 }
975
976 private static int WriteHeader(MessageOpcode opcode, byte[] sendBuffer, ReadOnlySpan<byte> payload, bool endOfMessage, bool useMask, bool compressed)
977 {
978 sendBuffer[0] = (byte)opcode;
979 if (endOfMessage)
980 {
981 sendBuffer[0] |= 128;
982 }
983 if (compressed && opcode != 0)
984 {
985 sendBuffer[0] |= 64;
986 }
987 int num;
988 if (payload.Length <= 125)
989 {
990 sendBuffer[1] = (byte)payload.Length;
991 num = 2;
992 }
993 else if (payload.Length <= 65535)
994 {
995 sendBuffer[1] = 126;
996 sendBuffer[2] = (byte)(payload.Length / 256);
997 sendBuffer[3] = (byte)payload.Length;
998 num = 4;
999 }
1000 else
1001 {
1002 sendBuffer[1] = 127;
1003 int num2 = payload.Length;
1004 for (int num3 = 9; num3 >= 2; num3--)
1005 {
1006 sendBuffer[num3] = (byte)num2;
1007 num2 /= 256;
1008 }
1009 num = 10;
1010 }
1011 if (useMask)
1012 {
1013 sendBuffer[1] |= 128;
1014 WriteRandomMask(sendBuffer, num);
1015 }
1016 return num;
1017 }
1018
1019 private static void WriteRandomMask(byte[] buffer, int offset)
1020 {
1021 RandomNumberGenerator.Fill(buffer.AsSpan(offset, 4));
1022 }
1023
1024 [AsyncStateMachine(typeof(_003CReceiveAsyncPrivate_003Ed__63<>))]
1025 [AsyncMethodBuilder(typeof(PoolingAsyncValueTaskMethodBuilder<>))]
1027 {
1029 stateMachine._003C_003Et__builder = PoolingAsyncValueTaskMethodBuilder<TResult>.Create();
1030 stateMachine._003C_003E4__this = this;
1031 stateMachine.payloadBuffer = payloadBuffer;
1032 stateMachine.cancellationToken = cancellationToken;
1033 stateMachine._003C_003E1__state = -1;
1034 stateMachine._003C_003Et__builder.Start(ref stateMachine);
1035 return stateMachine._003C_003Et__builder.Task;
1036 }
1037
1038 [MethodImpl(MethodImplOptions.AggressiveInlining)]
1039 private TResult GetReceiveResult<TResult>(int count, WebSocketMessageType messageType, bool endOfMessage)
1040 {
1041 if (typeof(TResult) == typeof(ValueWebSocketReceiveResult))
1042 {
1043 return (TResult)(object)new ValueWebSocketReceiveResult(count, messageType, endOfMessage);
1044 }
1045 return (TResult)(object)new WebSocketReceiveResult(count, messageType, endOfMessage, _closeStatus, _closeStatusDescription);
1046 }
1047
1049 {
1050 lock (StateUpdateLock)
1051 {
1052 _receivedCloseFrame = true;
1053 if (_sentCloseFrame && _state < WebSocketState.Closed)
1054 {
1055 _state = WebSocketState.Closed;
1056 }
1057 else if (_state < WebSocketState.CloseReceived)
1058 {
1059 _state = WebSocketState.CloseReceived;
1060 }
1061 }
1062 WebSocketCloseStatus closeStatus = WebSocketCloseStatus.NormalClosure;
1063 string closeStatusDescription = string.Empty;
1064 if (header.PayloadLength == 1)
1065 {
1066 await CloseWithReceiveErrorAndThrowAsync(WebSocketCloseStatus.ProtocolError, WebSocketError.Faulted).ConfigureAwait(continueOnCapturedContext: false);
1067 }
1068 else if (header.PayloadLength >= 2)
1069 {
1071 {
1072 await EnsureBufferContainsAsync((int)header.PayloadLength, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
1073 }
1074 if (_isServer)
1075 {
1076 ApplyMask(_receiveBuffer.Span.Slice(_receiveBufferOffset, (int)header.PayloadLength), header.Mask, 0);
1077 }
1079 if (!IsValidCloseStatus(closeStatus))
1080 {
1081 await CloseWithReceiveErrorAndThrowAsync(WebSocketCloseStatus.ProtocolError, WebSocketError.Faulted).ConfigureAwait(continueOnCapturedContext: false);
1082 }
1083 if (header.PayloadLength > 2)
1084 {
1085 try
1086 {
1087 closeStatusDescription = s_textEncoding.GetString(_receiveBuffer.Span.Slice(_receiveBufferOffset + 2, (int)header.PayloadLength - 2));
1088 }
1089 catch (DecoderFallbackException innerException)
1090 {
1091 await CloseWithReceiveErrorAndThrowAsync(WebSocketCloseStatus.ProtocolError, WebSocketError.Faulted, null, innerException).ConfigureAwait(continueOnCapturedContext: false);
1092 }
1093 }
1094 ConsumeFromBuffer((int)header.PayloadLength);
1095 }
1096 _closeStatus = closeStatus;
1097 _closeStatusDescription = closeStatusDescription;
1098 if (!_isServer && _sentCloseFrame)
1099 {
1100 await WaitForServerToCloseConnectionAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
1101 }
1102 }
1103
1105 {
1107 if (valueTask.IsCompletedSuccessfully)
1108 {
1109 valueTask.GetAwaiter().GetResult();
1110 return;
1111 }
1112 try
1113 {
1114 await valueTask.AsTask().WaitAsync(TimeSpan.FromMilliseconds(1000.0)).ConfigureAwait(continueOnCapturedContext: false);
1115 }
1116 catch
1117 {
1118 Abort();
1119 }
1120 }
1121
1123 {
1124 if (header.PayloadLength > 0 && _receiveBufferCount < header.PayloadLength)
1125 {
1126 await EnsureBufferContainsAsync((int)header.PayloadLength, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
1127 }
1128 if (header.Opcode == MessageOpcode.Ping)
1129 {
1130 if (_isServer)
1131 {
1132 ApplyMask(_receiveBuffer.Span.Slice(_receiveBufferOffset, (int)header.PayloadLength), header.Mask, 0);
1133 }
1134 await SendFrameAsync(MessageOpcode.Pong, endOfMessage: true, disableCompression: true, _receiveBuffer.Slice(_receiveBufferOffset, (int)header.PayloadLength), cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
1135 }
1136 if (header.PayloadLength > 0)
1137 {
1138 ConsumeFromBuffer((int)header.PayloadLength);
1139 }
1140 }
1141
1142 private static bool IsValidCloseStatus(WebSocketCloseStatus closeStatus)
1143 {
1144 if (closeStatus < WebSocketCloseStatus.NormalClosure || closeStatus >= (WebSocketCloseStatus)5000)
1145 {
1146 return false;
1147 }
1148 if (closeStatus >= (WebSocketCloseStatus)3000)
1149 {
1150 return true;
1151 }
1152 if ((uint)(closeStatus - 1000) <= 3u || (uint)(closeStatus - 1007) <= 4u)
1153 {
1154 return true;
1155 }
1156 return false;
1157 }
1158
1159 private async ValueTask CloseWithReceiveErrorAndThrowAsync(WebSocketCloseStatus closeStatus, WebSocketError error, string errorMessage = null, Exception innerException = null)
1160 {
1161 if (!_sentCloseFrame)
1162 {
1163 await CloseOutputAsync(closeStatus, string.Empty, default(CancellationToken)).ConfigureAwait(continueOnCapturedContext: false);
1164 }
1166 throw (errorMessage != null) ? new WebSocketException(error, errorMessage, innerException) : new WebSocketException(error, innerException);
1167 }
1168
1170 {
1171 MessageHeader messageHeader = default(MessageHeader);
1173 messageHeader.Fin = (span[_receiveBufferOffset] & 0x80) != 0;
1174 bool flag = (span[_receiveBufferOffset] & 0x30) != 0;
1175 messageHeader.Opcode = (MessageOpcode)(span[_receiveBufferOffset] & 0xFu);
1176 messageHeader.Compressed = (span[_receiveBufferOffset] & 0x40) != 0;
1177 bool flag2 = (span[_receiveBufferOffset + 1] & 0x80) != 0;
1178 messageHeader.PayloadLength = span[_receiveBufferOffset + 1] & 0x7F;
1180 if (messageHeader.PayloadLength == 126)
1181 {
1182 messageHeader.PayloadLength = (span[_receiveBufferOffset] << 8) | span[_receiveBufferOffset + 1];
1184 }
1185 else if (messageHeader.PayloadLength == 127)
1186 {
1187 messageHeader.PayloadLength = 0L;
1188 for (int i = 0; i < 8; i++)
1189 {
1190 messageHeader.PayloadLength = (messageHeader.PayloadLength << 8) | span[_receiveBufferOffset + i];
1191 }
1193 }
1194 if (flag)
1195 {
1196 resultHeader = default(MessageHeader);
1198 }
1199 if (messageHeader.PayloadLength < 0)
1200 {
1201 resultHeader = default(MessageHeader);
1203 }
1204 if (messageHeader.Compressed && _inflater == null)
1205 {
1206 resultHeader = default(MessageHeader);
1208 }
1209 if (flag2)
1210 {
1211 if (!_isServer)
1212 {
1213 resultHeader = default(MessageHeader);
1215 }
1216 messageHeader.Mask = CombineMaskBytes(span, _receiveBufferOffset);
1218 }
1219 switch (messageHeader.Opcode)
1220 {
1221 case MessageOpcode.Continuation:
1223 {
1224 resultHeader = default(MessageHeader);
1226 }
1227 if (messageHeader.Compressed)
1228 {
1229 resultHeader = default(MessageHeader);
1231 }
1232 messageHeader.Compressed = _lastReceiveHeader.Compressed;
1233 break;
1234 case MessageOpcode.Text:
1235 case MessageOpcode.Binary:
1237 {
1238 resultHeader = default(MessageHeader);
1240 }
1241 break;
1242 case MessageOpcode.Close:
1243 case MessageOpcode.Ping:
1244 case MessageOpcode.Pong:
1245 if (messageHeader.PayloadLength > 125 || !messageHeader.Fin)
1246 {
1247 resultHeader = default(MessageHeader);
1249 }
1250 break;
1251 default:
1252 resultHeader = default(MessageHeader);
1254 }
1255 messageHeader.Processed = messageHeader.PayloadLength == 0L && !messageHeader.Compressed;
1256 resultHeader = messageHeader;
1257 return null;
1258 }
1259
1260 private async Task CloseAsyncPrivate(WebSocketCloseStatus closeStatus, string statusDescription, CancellationToken cancellationToken)
1261 {
1262 if (!_sentCloseFrame)
1263 {
1264 await SendCloseFrameAsync(closeStatus, statusDescription, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
1265 }
1266 if (State == WebSocketState.CloseSent)
1267 {
1268 byte[] closeBuffer = ArrayPool<byte>.Shared.Rent(139);
1269 try
1270 {
1271 while (!_receivedCloseFrame)
1272 {
1274 try
1275 {
1276 await _receiveMutex.EnterAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
1277 try
1278 {
1280 {
1281 receiveTask = ReceiveAsyncPrivate<ValueWebSocketReceiveResult>(closeBuffer, cancellationToken);
1282 }
1283 }
1284 finally
1285 {
1287 }
1288 }
1290 {
1291 Abort();
1292 throw;
1293 }
1294 await receiveTask.ConfigureAwait(continueOnCapturedContext: false);
1295 }
1296 }
1297 finally
1298 {
1299 ArrayPool<byte>.Shared.Return(closeBuffer);
1300 }
1301 }
1302 lock (StateUpdateLock)
1303 {
1304 DisposeCore();
1305 }
1306 }
1307
1308 private async ValueTask SendCloseFrameAsync(WebSocketCloseStatus closeStatus, string closeStatusDescription, CancellationToken cancellationToken)
1309 {
1310 byte[] buffer = null;
1311 try
1312 {
1313 int num = 2;
1314 if (string.IsNullOrEmpty(closeStatusDescription))
1315 {
1316 buffer = ArrayPool<byte>.Shared.Rent(num);
1317 }
1318 else
1319 {
1320 num += s_textEncoding.GetByteCount(closeStatusDescription);
1321 buffer = ArrayPool<byte>.Shared.Rent(num);
1322 s_textEncoding.GetBytes(closeStatusDescription, 0, closeStatusDescription.Length, buffer, 2);
1323 }
1324 ushort num2 = (ushort)closeStatus;
1325 buffer[0] = (byte)(num2 >> 8);
1326 buffer[1] = (byte)(num2 & 0xFFu);
1327 await SendFrameAsync(MessageOpcode.Close, endOfMessage: true, disableCompression: true, new Memory<byte>(buffer, 0, num), cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
1328 }
1329 finally
1330 {
1331 if (buffer != null)
1332 {
1334 }
1335 }
1336 lock (StateUpdateLock)
1337 {
1338 _sentCloseFrame = true;
1340 {
1341 _state = WebSocketState.Closed;
1342 }
1343 else if (_state < WebSocketState.CloseSent)
1344 {
1345 _state = WebSocketState.CloseSent;
1346 }
1347 }
1349 {
1350 await WaitForServerToCloseConnectionAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
1351 }
1352 }
1353
1354 private void ConsumeFromBuffer(int count)
1355 {
1358 }
1359
1360 [AsyncStateMachine(typeof(_003CEnsureBufferContainsAsync_003Ed__74))]
1361 [AsyncMethodBuilder(typeof(PoolingAsyncValueTaskMethodBuilder))]
1362 private ValueTask EnsureBufferContainsAsync(int minimumRequiredBytes, CancellationToken cancellationToken, bool throwOnPrematureClosure = true)
1363 {
1365 stateMachine._003C_003Et__builder = PoolingAsyncValueTaskMethodBuilder.Create();
1366 stateMachine._003C_003E4__this = this;
1367 stateMachine.minimumRequiredBytes = minimumRequiredBytes;
1368 stateMachine.cancellationToken = cancellationToken;
1369 stateMachine.throwOnPrematureClosure = throwOnPrematureClosure;
1370 stateMachine._003C_003E1__state = -1;
1371 stateMachine._003C_003Et__builder.Start(ref stateMachine);
1372 return stateMachine._003C_003Et__builder.Task;
1373 }
1374
1375 private void ThrowIfEOFUnexpected(bool throwOnPrematureClosure)
1376 {
1377 if (_disposed)
1378 {
1379 throw new ObjectDisposedException("WebSocket");
1380 }
1381 if (throwOnPrematureClosure)
1382 {
1383 throw new WebSocketException(WebSocketError.ConnectionClosedPrematurely);
1384 }
1385 }
1386
1387 private void AllocateSendBuffer(int minLength)
1388 {
1389 _sendBuffer = ArrayPool<byte>.Shared.Rent(minLength);
1390 }
1391
1392 private void ReleaseSendBuffer()
1393 {
1394 byte[] sendBuffer = _sendBuffer;
1395 if (sendBuffer != null)
1396 {
1397 _sendBuffer = null;
1398 ArrayPool<byte>.Shared.Return(sendBuffer);
1399 }
1400 }
1401
1402 private static int CombineMaskBytes(Span<byte> buffer, int maskOffset)
1403 {
1404 return BitConverter.ToInt32(buffer.Slice(maskOffset));
1405 }
1406
1407 private static int ApplyMask(Span<byte> toMask, byte[] mask, int maskOffset, int maskOffsetIndex)
1408 {
1409 return ApplyMask(toMask, CombineMaskBytes(mask, maskOffset), maskOffsetIndex);
1410 }
1411
1412 private unsafe static int ApplyMask(Span<byte> toMask, int mask, int maskIndex)
1413 {
1414 fixed (byte* ptr = &MemoryMarshal.GetReference(toMask))
1415 {
1416 byte* ptr2 = ptr;
1417 byte* ptr3 = ptr + toMask.Length;
1418 byte* ptr4 = (byte*)(&mask);
1419 if (ptr3 - ptr2 >= 4)
1420 {
1421 while ((ulong)ptr2 % 4uL != 0L)
1422 {
1423 byte* intPtr = ptr2++;
1424 *intPtr ^= ptr4[maskIndex];
1425 maskIndex = (maskIndex + 1) & 3;
1426 }
1427 int num = (int)((!BitConverter.IsLittleEndian) ? BitOperations.RotateLeft((uint)mask, maskIndex * 8) : BitOperations.RotateRight((uint)mask, maskIndex * 8));
1428 if (Vector.IsHardwareAccelerated && Vector<byte>.Count % 4 == 0 && ptr3 - ptr2 >= Vector<byte>.Count)
1429 {
1430 for (; (ulong)ptr2 % (ulong)(uint)Vector<byte>.Count != 0L; ptr2 += 4)
1431 {
1432 *(int*)ptr2 ^= num;
1433 }
1434 if (ptr3 - ptr2 >= Vector<byte>.Count)
1435 {
1436 Vector<byte> vector = Vector.AsVectorByte(new Vector<int>(num));
1437 do
1438 {
1439 *(Vector<byte>*)ptr2 ^= vector;
1440 ptr2 += Vector<byte>.Count;
1441 }
1442 while (ptr3 - ptr2 >= Vector<byte>.Count);
1443 }
1444 }
1445 for (; ptr3 - ptr2 >= 4; ptr2 += 4)
1446 {
1447 *(int*)ptr2 ^= num;
1448 }
1449 }
1450 while (ptr2 != ptr3)
1451 {
1452 byte* intPtr2 = ptr2++;
1453 *intPtr2 ^= ptr4[maskIndex];
1454 maskIndex = (maskIndex + 1) & 3;
1455 }
1456 }
1457 return maskIndex;
1458 }
1459
1464
1465 private static bool TryValidateUtf8(Span<byte> span, bool endOfMessage, Utf8MessageState state)
1466 {
1467 int num = 0;
1468 while (num < span.Length)
1469 {
1470 if (!state.SequenceInProgress)
1471 {
1472 state.SequenceInProgress = true;
1473 byte b = span[num];
1474 num++;
1475 if ((b & 0x80) == 0)
1476 {
1477 state.AdditionalBytesExpected = 0;
1478 state.CurrentDecodeBits = b & 0x7F;
1479 state.ExpectedValueMin = 0;
1480 }
1481 else
1482 {
1483 if ((b & 0xC0) == 128)
1484 {
1485 return false;
1486 }
1487 if ((b & 0xE0) == 192)
1488 {
1489 state.AdditionalBytesExpected = 1;
1490 state.CurrentDecodeBits = b & 0x1F;
1491 state.ExpectedValueMin = 128;
1492 }
1493 else if ((b & 0xF0) == 224)
1494 {
1495 state.AdditionalBytesExpected = 2;
1496 state.CurrentDecodeBits = b & 0xF;
1497 state.ExpectedValueMin = 2048;
1498 }
1499 else
1500 {
1501 if ((b & 0xF8) != 240)
1502 {
1503 return false;
1504 }
1505 state.AdditionalBytesExpected = 3;
1506 state.CurrentDecodeBits = b & 7;
1507 state.ExpectedValueMin = 65536;
1508 }
1509 }
1510 }
1511 while (state.AdditionalBytesExpected > 0 && num < span.Length)
1512 {
1513 byte b2 = span[num];
1514 if ((b2 & 0xC0) != 128)
1515 {
1516 return false;
1517 }
1518 num++;
1519 state.AdditionalBytesExpected--;
1520 state.CurrentDecodeBits = (state.CurrentDecodeBits << 6) | (b2 & 0x3F);
1521 if (state.AdditionalBytesExpected == 1 && state.CurrentDecodeBits >= 864 && state.CurrentDecodeBits <= 895)
1522 {
1523 return false;
1524 }
1525 if (state.AdditionalBytesExpected == 2 && state.CurrentDecodeBits >= 272)
1526 {
1527 return false;
1528 }
1529 }
1530 if (state.AdditionalBytesExpected == 0)
1531 {
1532 state.SequenceInProgress = false;
1533 if (state.CurrentDecodeBits < state.ExpectedValueMin)
1534 {
1535 return false;
1536 }
1537 }
1538 }
1539 if (endOfMessage && state.SequenceInProgress)
1540 {
1541 return false;
1542 }
1543 return true;
1544 }
1545}
static readonly bool IsLittleEndian
static int ToInt32(byte[] value, int startIndex)
static ArrayPool< T > Shared
Definition ArrayPool.cs:7
Task WriteAsync(byte[] buffer, int offset, int count)
Definition Stream.cs:914
void Dispose()
Definition Stream.cs:639
Task< int > ReadAsync(byte[] buffer, int offset, int count)
Definition Stream.cs:762
static byte Min(byte val1, byte val2)
Definition Math.cs:912
ReadOnlySpan< byte > Deflate(ReadOnlySpan< byte > payload, bool endOfMessage)
void AddBytes(int totalBytesReceived, bool endOfMessage)
unsafe bool Inflate(Span< byte > output, out int written)
void Prepare(long payloadLength, int userBufferLength)
async ValueTask HandleReceivedPingPongAsync(MessageHeader header, CancellationToken cancellationToken)
static int CombineMaskBytes(Span< byte > buffer, int maskOffset)
static readonly WebSocketState[] s_validCloseOutputStates
static int WriteHeader(MessageOpcode opcode, byte[] sendBuffer, ReadOnlySpan< byte > payload, bool endOfMessage, bool useMask, bool compressed)
async ValueTask SendCloseFrameAsync(WebSocketCloseStatus closeStatus, string closeStatusDescription, CancellationToken cancellationToken)
readonly Utf8MessageState _utf8TextState
async ValueTask CloseWithReceiveErrorAndThrowAsync(WebSocketCloseStatus closeStatus, WebSocketError error, string errorMessage=null, Exception innerException=null)
ManagedWebSocket(Stream stream, WebSocketCreationOptions options)
string TryParseMessageHeaderFromReceiveBuffer(out MessageHeader resultHeader)
async ValueTask WaitForWriteTaskAsync(ValueTask writeTask)
ManagedWebSocket(Stream stream, bool isServer, string subprotocol, TimeSpan keepAliveInterval)
void ThrowIfEOFUnexpected(bool throwOnPrematureClosure)
static readonly WebSocketState[] s_validSendStates
static readonly UTF8Encoding s_textEncoding
static bool IsValidCloseStatus(WebSocketCloseStatus closeStatus)
override ValueTask SendAsync(ReadOnlyMemory< byte > buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken)
static int ApplyMask(Span< byte > toMask, byte[] mask, int maskOffset, int maskOffsetIndex)
ValueTask EnsureBufferContainsAsync(int minimumRequiredBytes, CancellationToken cancellationToken, bool throwOnPrematureClosure=true)
async ValueTask HandleReceivedCloseAsync(MessageHeader header, CancellationToken cancellationToken)
static Exception CreateOperationCanceledException(Exception innerException, CancellationToken cancellationToken=default(CancellationToken))
static bool TryValidateUtf8(Span< byte > span, bool endOfMessage, Utf8MessageState state)
int WriteFrameToSendBuffer(MessageOpcode opcode, bool endOfMessage, bool disableCompression, ReadOnlySpan< byte > payloadBuffer)
async Task CloseOutputAsyncCore(WebSocketCloseStatus closeStatus, string statusDescription, CancellationToken cancellationToken)
async ValueTask SendFrameFallbackAsync(MessageOpcode opcode, bool endOfMessage, bool disableCompression, ReadOnlyMemory< byte > payloadBuffer, Task lockTask, CancellationToken cancellationToken)
override Task< WebSocketReceiveResult > ReceiveAsync(ArraySegment< byte > buffer, CancellationToken cancellationToken)
TResult GetReceiveResult< TResult >(int count, WebSocketMessageType messageType, bool endOfMessage)
override ValueTask< ValueWebSocketReceiveResult > ReceiveAsync(Memory< byte > buffer, CancellationToken cancellationToken)
static unsafe int ApplyMask(Span< byte > toMask, int mask, int maskIndex)
ValueTask SendFrameAsync(MessageOpcode opcode, bool endOfMessage, bool disableCompression, ReadOnlyMemory< byte > payloadBuffer, CancellationToken cancellationToken)
override Task CloseAsync(WebSocketCloseStatus closeStatus, string statusDescription, CancellationToken cancellationToken)
ValueTask SendFrameLockAcquiredNonCancelableAsync(MessageOpcode opcode, bool endOfMessage, bool disableCompression, ReadOnlyMemory< byte > payloadBuffer)
static readonly WebSocketState[] s_validCloseStates
override Task SendAsync(ArraySegment< byte > buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken)
static void WriteRandomMask(byte[] buffer, int offset)
override? WebSocketCloseStatus CloseStatus
override ValueTask SendAsync(ReadOnlyMemory< byte > buffer, WebSocketMessageType messageType, WebSocketMessageFlags messageFlags, CancellationToken cancellationToken)
async ValueTask WaitForServerToCloseConnectionAsync(CancellationToken cancellationToken)
static readonly WebSocketState[] s_validReceiveStates
ValueTask< TResult > ReceiveAsyncPrivate< TResult >(Memory< byte > payloadBuffer, CancellationToken cancellationToken)
async Task CloseAsyncPrivate(WebSocketCloseStatus closeStatus, string statusDescription, CancellationToken cancellationToken)
override Task CloseOutputAsync(WebSocketCloseStatus closeStatus, string statusDescription, CancellationToken cancellationToken)
static void ValidateArraySegment(ArraySegment< byte > arraySegment, string parameterName)
static void ValidateCloseStatus(WebSocketCloseStatus closeStatus, string statusDescription)
static void ThrowIfInvalidState(WebSocketState currentState, bool isDisposed, WebSocketState[] validStates)
static uint RotateRight(uint value, int offset)
static uint RotateLeft(uint value, int offset)
static bool IsHardwareAccelerated
Definition Vector.cs:14
static string net_Websockets_ContinuationFromFinalFrame
Definition SR.cs:52
static string net_Websockets_InvalidControlMessage
Definition SR.cs:56
static string net_WebSockets_Argument_InvalidMessageType
Definition SR.cs:166
static string net_WebSockets_Argument_MessageFlagsHasDifferentCompressionOptions
Definition SR.cs:80
static string net_Websockets_PerMessageCompressedFlagWhenNotEnabled
Definition SR.cs:68
static string net_Websockets_InvalidPayloadLength
Definition SR.cs:82
static string Format(string resourceFormat, object p1)
Definition SR.cs:118
static string net_Websockets_NonContinuationAfterNonFinalFrame
Definition SR.cs:54
static string net_Websockets_UnknownOpcode
Definition SR.cs:58
static string net_Websockets_ClientReceivedMaskedFrame
Definition SR.cs:50
static string net_Websockets_PerMessageCompressedFlagInContinuation
Definition SR.cs:66
static string net_Websockets_ReservedBitsSet
Definition SR.cs:48
Definition SR.cs:7
Task EnterAsync(CancellationToken cancellationToken)
Definition AsyncMutex.cs:32
Task ContinueWith(Action< Task< TResult > > continuationAction)
Definition Task.cs:263
new ConfiguredTaskAwaitable< TResult > ConfigureAwait(bool continueOnCapturedContext)
Definition Task.cs:226
new Task< TResult > WaitAsync(CancellationToken cancellationToken)
Definition Task.cs:231
static Task FromException(Exception exception)
Definition Task.cs:3341
AggregateException? Exception
Definition Task.cs:1014
bool Dispose(WaitHandle notifyObject)
Definition Timer.cs:176
bool TryGetTarget([MaybeNullWhen(false)][NotNullWhen(true)] out T target)
void SetStateMachine(IAsyncStateMachine stateMachine)
Memory< T > Slice(int start)
Definition Memory.cs:194
unsafe Span< T > Span
Definition Memory.cs:28
ConfiguredValueTaskAwaitable< int >.ConfiguredValueTaskAwaiter _003C_003Eu__1
ConfiguredValueTaskAwaitable< int >.ConfiguredValueTaskAwaiter _003C_003Eu__3
ConfiguredValueTaskAwaitable.ConfiguredValueTaskAwaiter _003C_003Eu__2
unsafe ReadOnlySpan< T > Span
static ReadOnlyMemory< T > Empty
void CopyTo(Span< T > destination)
void CopyTo(Span< T > destination)
Definition Span.cs:224
Span< T > Slice(int start)
Definition Span.cs:271
int Length
Definition Span.cs:70
CancellationTokenRegistration Register(Action callback)
ConfiguredValueTaskAwaitable ConfigureAwait(bool continueOnCapturedContext)
Definition ValueTask.cs:312
static ValueTask FromException(Exception exception)
Definition ValueTask.cs:190
ValueTaskAwaiter GetAwaiter()
Definition ValueTask.cs:306
static TimeSpan FromMilliseconds(double value)
Definition TimeSpan.cs:228
static readonly TimeSpan Zero
Definition TimeSpan.cs:21