Removed WebSocketProtocol code and mentions of the assembly.
Moved ManagedWebSocket.cs from Common to System.Net.WebSockets.
Fixes #1493
+++ /dev/null
-<Project>
- <Import Project="..\Directory.Build.props" />
- <PropertyGroup>
- <StrongNameKeyId>Open</StrongNameKeyId>
- <IncludePlatformAttributes>true</IncludePlatformAttributes>
- <PackageDescription>Provides the WebSocketProtocol class, which allows creating a websocket from a connected stream using WebSocketsProtocol.CreateFromConnectedStream.
-
-Commonly Used Types:
-System.Net.WebSockets.WebSocketProtocol</PackageDescription>
- </PropertyGroup>
-</Project>
\ No newline at end of file
+++ /dev/null
-Microsoft Visual Studio Solution File, Format Version 12.00
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestUtilities", "..\Common\tests\TestUtilities\TestUtilities.csproj", "{B6EF5109-6DE6-4CE3-879D-060AA8698540}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Win32.Registry", "..\Microsoft.Win32.Registry\ref\Microsoft.Win32.Registry.csproj", "{BFA2FE9A-920B-4A51-B6A7-571FCE6FF542}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Net.WebSockets.WebSocketProtocol", "ref\System.Net.WebSockets.WebSocketProtocol.csproj", "{753243E4-C9B5-4E5C-8FBA-1211B63C435A}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Net.WebSockets.WebSocketProtocol", "src\System.Net.WebSockets.WebSocketProtocol.csproj", "{F9419A4B-8CBA-4609-BC2A-8596087CD3B0}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Net.WebSockets.WebSocketProtocol.Tests", "tests\System.Net.WebSockets.WebSocketProtocol.Tests.csproj", "{EA24382F-2448-4217-8682-E213A6EF868F}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.CompilerServices.Unsafe", "..\System.Runtime.CompilerServices.Unsafe\ref\System.Runtime.CompilerServices.Unsafe.csproj", "{ABE7DC67-F098-409C-B28C-A59CBEE888F3}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.CompilerServices.Unsafe", "..\System.Runtime.CompilerServices.Unsafe\src\System.Runtime.CompilerServices.Unsafe.ilproj", "{D6B4EB67-A972-4252-9F8C-C53FA38730E6}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Security.AccessControl", "..\System.Security.AccessControl\ref\System.Security.AccessControl.csproj", "{FE98CB0A-9BF7-4FBF-A792-9F89F532CE43}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Security.Principal.Windows", "..\System.Security.Principal.Windows\ref\System.Security.Principal.Windows.csproj", "{22F639F5-413A-41A2-A66D-E8E6876C007C}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{CBA116A5-3B17-4ED8-9F82-E3E1A36E0424}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ref", "ref", "{7825E342-AA06-40BC-89BD-BBC88DD3C2FE}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{CBD1A8B6-B9E0-4D3D-9DEC-D95B022A8C23}"
-EndProject
-Global
- GlobalSection(NestedProjects) = preSolution
- {B6EF5109-6DE6-4CE3-879D-060AA8698540} = {CBA116A5-3B17-4ED8-9F82-E3E1A36E0424}
- {EA24382F-2448-4217-8682-E213A6EF868F} = {CBA116A5-3B17-4ED8-9F82-E3E1A36E0424}
- {BFA2FE9A-920B-4A51-B6A7-571FCE6FF542} = {7825E342-AA06-40BC-89BD-BBC88DD3C2FE}
- {753243E4-C9B5-4E5C-8FBA-1211B63C435A} = {7825E342-AA06-40BC-89BD-BBC88DD3C2FE}
- {ABE7DC67-F098-409C-B28C-A59CBEE888F3} = {7825E342-AA06-40BC-89BD-BBC88DD3C2FE}
- {FE98CB0A-9BF7-4FBF-A792-9F89F532CE43} = {7825E342-AA06-40BC-89BD-BBC88DD3C2FE}
- {22F639F5-413A-41A2-A66D-E8E6876C007C} = {7825E342-AA06-40BC-89BD-BBC88DD3C2FE}
- {F9419A4B-8CBA-4609-BC2A-8596087CD3B0} = {CBD1A8B6-B9E0-4D3D-9DEC-D95B022A8C23}
- {D6B4EB67-A972-4252-9F8C-C53FA38730E6} = {CBD1A8B6-B9E0-4D3D-9DEC-D95B022A8C23}
- EndGlobalSection
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {B6EF5109-6DE6-4CE3-879D-060AA8698540}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {B6EF5109-6DE6-4CE3-879D-060AA8698540}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {B6EF5109-6DE6-4CE3-879D-060AA8698540}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {B6EF5109-6DE6-4CE3-879D-060AA8698540}.Release|Any CPU.Build.0 = Release|Any CPU
- {BFA2FE9A-920B-4A51-B6A7-571FCE6FF542}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {BFA2FE9A-920B-4A51-B6A7-571FCE6FF542}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {BFA2FE9A-920B-4A51-B6A7-571FCE6FF542}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {BFA2FE9A-920B-4A51-B6A7-571FCE6FF542}.Release|Any CPU.Build.0 = Release|Any CPU
- {753243E4-C9B5-4E5C-8FBA-1211B63C435A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {753243E4-C9B5-4E5C-8FBA-1211B63C435A}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {753243E4-C9B5-4E5C-8FBA-1211B63C435A}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {753243E4-C9B5-4E5C-8FBA-1211B63C435A}.Release|Any CPU.Build.0 = Release|Any CPU
- {F9419A4B-8CBA-4609-BC2A-8596087CD3B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {F9419A4B-8CBA-4609-BC2A-8596087CD3B0}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {F9419A4B-8CBA-4609-BC2A-8596087CD3B0}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {F9419A4B-8CBA-4609-BC2A-8596087CD3B0}.Release|Any CPU.Build.0 = Release|Any CPU
- {EA24382F-2448-4217-8682-E213A6EF868F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {EA24382F-2448-4217-8682-E213A6EF868F}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {EA24382F-2448-4217-8682-E213A6EF868F}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {EA24382F-2448-4217-8682-E213A6EF868F}.Release|Any CPU.Build.0 = Release|Any CPU
- {ABE7DC67-F098-409C-B28C-A59CBEE888F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {ABE7DC67-F098-409C-B28C-A59CBEE888F3}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {ABE7DC67-F098-409C-B28C-A59CBEE888F3}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {ABE7DC67-F098-409C-B28C-A59CBEE888F3}.Release|Any CPU.Build.0 = Release|Any CPU
- {D6B4EB67-A972-4252-9F8C-C53FA38730E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {D6B4EB67-A972-4252-9F8C-C53FA38730E6}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {D6B4EB67-A972-4252-9F8C-C53FA38730E6}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {D6B4EB67-A972-4252-9F8C-C53FA38730E6}.Release|Any CPU.Build.0 = Release|Any CPU
- {FE98CB0A-9BF7-4FBF-A792-9F89F532CE43}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {FE98CB0A-9BF7-4FBF-A792-9F89F532CE43}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {FE98CB0A-9BF7-4FBF-A792-9F89F532CE43}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {FE98CB0A-9BF7-4FBF-A792-9F89F532CE43}.Release|Any CPU.Build.0 = Release|Any CPU
- {22F639F5-413A-41A2-A66D-E8E6876C007C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {22F639F5-413A-41A2-A66D-E8E6876C007C}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {22F639F5-413A-41A2-A66D-E8E6876C007C}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {22F639F5-413A-41A2-A66D-E8E6876C007C}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- SolutionGuid = {BC6A06B6-892F-402D-80A3-24138262A1A2}
- EndGlobalSection
-EndGlobal
+++ /dev/null
-<Project DefaultTargets="Build">
- <Import Project="$([MSBuild]::GetPathOfFileAbove(Directory.Build.props))" />
- <ItemGroup>
- <ProjectReference Include="..\src\System.Net.WebSockets.WebSocketProtocol.csproj">
- <SupportedFramework>uap10.0.16299;net461;netcoreapp2.0;$(AllXamarinFrameworks)</SupportedFramework>
- </ProjectReference>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetPathOfFileAbove(Directory.Build.targets))" />
-</Project>
\ No newline at end of file
+++ /dev/null
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// ------------------------------------------------------------------------------
-// Changes to this file must follow the https://aka.ms/api-review process.
-// ------------------------------------------------------------------------------
-
-namespace System.Net.WebSockets
-{
- [System.Runtime.Versioning.UnsupportedOSPlatform("browser")]
- public static partial class WebSocketProtocol
- {
- public static System.Net.WebSockets.WebSocket CreateFromStream(System.IO.Stream stream, bool isServer, string? subProtocol, System.TimeSpan keepAliveInterval) { throw null; }
- }
-}
+++ /dev/null
-<Project Sdk="Microsoft.NET.Sdk">
- <PropertyGroup>
- <TargetFrameworks>netstandard2.0;net461</TargetFrameworks>
- <Nullable>enable</Nullable>
- </PropertyGroup>
- <ItemGroup>
- <Compile Include="System.Net.WebSockets.WebSocketProtocol.cs" />
- </ItemGroup>
- <ItemGroup>
- <PackageReference Include="System.Memory" Version="$(SystemMemoryVersion)" />
- </ItemGroup>
-</Project>
\ No newline at end of file
+++ /dev/null
-<root>
- <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
- <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
- <xsd:element name="root" msdata:IsDataSet="true">
- <xsd:complexType>
- <xsd:choice maxOccurs="unbounded">
- <xsd:element name="metadata">
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element name="value" type="xsd:string" minOccurs="0" />
- </xsd:sequence>
- <xsd:attribute name="name" use="required" type="xsd:string" />
- <xsd:attribute name="type" type="xsd:string" />
- <xsd:attribute name="mimetype" type="xsd:string" />
- <xsd:attribute ref="xml:space" />
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="assembly">
- <xsd:complexType>
- <xsd:attribute name="alias" type="xsd:string" />
- <xsd:attribute name="name" type="xsd:string" />
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="data">
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
- <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
- </xsd:sequence>
- <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
- <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
- <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
- <xsd:attribute ref="xml:space" />
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="resheader">
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
- </xsd:sequence>
- <xsd:attribute name="name" type="xsd:string" use="required" />
- </xsd:complexType>
- </xsd:element>
- </xsd:choice>
- </xsd:complexType>
- </xsd:element>
- </xsd:schema>
- <resheader name="resmimetype">
- <value>text/microsoft-resx</value>
- </resheader>
- <resheader name="version">
- <value>2.0</value>
- </resheader>
- <resheader name="reader">
- <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </resheader>
- <resheader name="writer">
- <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </resheader>
- <data name="net_WebSockets_InvalidEmptySubProtocol" xml:space="preserve">
- <value>Empty string is not a valid subprotocol value. Please use \"null\" to specify no value.</value>
- </data>
- <data name="net_WebSockets_InvalidState" xml:space="preserve">
- <value>The WebSocket is in an invalid state ('{0}') for this operation. Valid states are: '{1}'</value>
- </data>
- <data name="net_WebSockets_InvalidCharInProtocolString" xml:space="preserve">
- <value>The WebSocket protocol '{0}' is invalid because it contains the invalid character '{1}'.</value>
- </data>
- <data name="net_WebSockets_ReasonNotNull" xml:space="preserve">
- <value>The close status description '{0}' is invalid. When using close status code '{1}' the description must be null.</value>
- </data>
- <data name="net_WebSockets_InvalidCloseStatusCode" xml:space="preserve">
- <value>The close status code '{0}' is reserved for system use only and cannot be specified when calling this method.</value>
- </data>
- <data name="net_WebSockets_InvalidCloseStatusDescription" xml:space="preserve">
- <value>The close status description '{0}' is too long. The UTF8-representation of the status description must not be longer than {1} bytes.</value>
- </data>
- <data name="net_WebSockets_UnsupportedPlatform" xml:space="preserve">
- <value>The WebSocket protocol is not supported on this platform.</value>
- </data>
- <data name="net_WebSockets_Argument_InvalidMessageType" xml:space="preserve">
- <value>The message type '{0}' is not allowed for the '{1}' operation. Valid message types are: '{2}, {3}'. To close the WebSocket, use the '{4}' operation instead. </value>
- </data>
- <data name="net_Websockets_AlreadyOneOutstandingOperation" xml:space="preserve">
- <value>There is already one outstanding '{0}' call for this WebSocket instance. ReceiveAsync and SendAsync can be called simultaneously, but at most one outstanding operation for each of them is allowed at the same time.</value>
- </data>
- <data name="NotReadableStream" xml:space="preserve">
- <value>The base stream is not readable.</value>
- </data>
- <data name="NotWriteableStream" xml:space="preserve">
- <value>The base stream is not writeable.</value>
- </data>
- <data name="net_WebSockets_ArgumentOutOfRange_TooSmall" xml:space="preserve">
- <value>The argument must be a value greater than {0}.</value>
- </data>
- <data name="net_Websockets_ReservedBitsSet" xml:space="preserve">
- <value>The WebSocket received a frame with one or more reserved bits set.</value>
- </data>
- <data name="net_Websockets_ClientReceivedMaskedFrame" xml:space="preserve">
- <value>The WebSocket server sent a masked frame.</value>
- </data>
- <data name="net_Websockets_ContinuationFromFinalFrame" xml:space="preserve">
- <value>The WebSocket received a continuation frame from a previous final message.</value>
- </data>
- <data name="net_Websockets_NonContinuationAfterNonFinalFrame" xml:space="preserve">
- <value>The WebSocket expected a continuation frame after having received a previous non-final frame.</value>
- </data>
- <data name="net_Websockets_InvalidControlMessage" xml:space="preserve">
- <value>The WebSocket received an invalid control message.</value>
- </data>
- <data name="net_Websockets_UnknownOpcode" xml:space="preserve">
- <value>The WebSocket received a frame with an unknown opcode: '0x{0}'.</value>
- </data>
-</root>
+++ /dev/null
-<Project Sdk="Microsoft.NET.Sdk">
- <PropertyGroup>
- <AllowUnsafeBlocks>True</AllowUnsafeBlocks>
- <TargetFrameworks>$(NetCoreAppCurrent);netstandard2.0;netcoreapp2.1;net461</TargetFrameworks>
- <ExcludeCurrentNetCoreAppFromPackage>true</ExcludeCurrentNetCoreAppFromPackage>
- <Nullable>enable</Nullable>
- </PropertyGroup>
- <ItemGroup>
- <Compile Include="$(CommonPath)System\Net\WebSockets\ManagedWebSocket.cs"
- Link="Common\System\Net\WebSockets\ManagedWebSocket.cs" />
- <Compile Include="$(CommonPath)System\Net\WebSockets\WebSocketValidate.cs"
- Link="Common\System\Net\WebSockets\WebSocketValidate.cs" />
- <Compile Include="System\Net\WebSockets\ManagedWebSocket.netstandard.cs" />
- <Compile Include="System\Net\WebSockets\ManagedWebSocketExtensions.cs" />
- <Compile Include="System\Net\WebSockets\WebSocketProtocol.cs" />
- </ItemGroup>
- <ItemGroup Condition="'$(TargetFramework)' != '$(NetCoreAppCurrent)'">
- <Compile Include="System\Numerics\BitOperations.cs" />
- </ItemGroup>
- <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0' Or $(TargetFramework.StartsWith('net4'))">
- <Compile Include="System\Net\WebSockets\ManagedWebSocketExtensions.netstandard.cs" />
- </ItemGroup>
- <ItemGroup Condition="'$(TargetFramework)' == '$(NetCoreAppCurrent)' or
- '$(TargetFramework)' == 'netcoreapp2.1'">
- <Reference Include="Microsoft.Win32.Primitives" />
- <Reference Include="System.Buffers" />
- <Reference Include="System.Diagnostics.Debug" />
- <Reference Include="System.Memory" />
- <Reference Include="System.Net.WebSockets" />
- <Reference Include="System.Numerics.Vectors" />
- <Reference Include="System.Resources.ResourceManager" />
- <Reference Include="System.Runtime" />
- <Reference Include="System.Runtime.Extensions" />
- <Reference Include="System.Security.Cryptography.Algorithms" />
- <Reference Include="System.Text.Encoding.Extensions" />
- <Reference Include="System.Threading" />
- <Reference Include="System.Threading.Tasks" />
- <Reference Include="System.Threading.Tasks.Extensions" />
- <Reference Include="System.Threading.Timer" />
- </ItemGroup>
- <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0' or
- $(TargetFramework.StartsWith('net4'))">
- <PackageReference Include="System.Buffers" Version="$(SystemBuffersVersion)" />
- <PackageReference Include="System.Memory" Version="$(SystemMemoryVersion)" />
- <PackageReference Include="System.Numerics.Vectors" Version="$(SystemNumericsVectorsVersion)" />
- <PackageReference Include="System.Threading.Tasks.Extensions" Version="$(SystemThreadingTasksExtensionsVersion)" />
- <ProjectReference Include="$(LibrariesProjectRoot)System.Runtime.CompilerServices.Unsafe\src\System.Runtime.CompilerServices.Unsafe.ilproj" />
- </ItemGroup>
-</Project>
+++ /dev/null
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace System.Net.WebSockets
-{
- internal sealed partial class ManagedWebSocket : WebSocket
- {
- private Task ValidateAndReceiveAsync(Task receiveTask, byte[] buffer, CancellationToken cancellationToken)
- {
- if (receiveTask == null ||
- (receiveTask.Status == TaskStatus.RanToCompletion &&
- !(receiveTask is Task<WebSocketReceiveResult> wsrr && wsrr.Result.MessageType == WebSocketMessageType.Close)))
- {
- receiveTask = ReceiveAsyncPrivate<WebSocketReceiveResultGetter, WebSocketReceiveResult>(new ArraySegment<byte>(buffer), cancellationToken).AsTask();
- }
-
- return receiveTask;
- }
- }
-}
+++ /dev/null
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Threading;
-
-namespace System.Net.WebSockets
-{
- internal static partial class ManagedWebSocketExtensions
- {
- internal static CancellationTokenRegistration UnsafeRegister(this CancellationToken cancellationToken, Action<object?> callback, object? state) =>
- cancellationToken.Register(callback, state);
- }
-}
+++ /dev/null
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Buffers;
-using System.Diagnostics;
-using System.IO;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace System.Net.WebSockets
-{
- internal static partial class ManagedWebSocketExtensions
- {
- internal static unsafe string GetString(this UTF8Encoding encoding, Span<byte> bytes)
- {
- fixed (byte* b = &MemoryMarshal.GetReference(bytes))
- {
- return encoding.GetString(b, bytes.Length);
- }
- }
-
- internal static ValueTask<int> ReadAsync(this Stream stream, Memory<byte> destination, CancellationToken cancellationToken = default)
- {
- if (MemoryMarshal.TryGetArray(destination, out ArraySegment<byte> array))
- {
- return new ValueTask<int>(stream.ReadAsync(array.Array, array.Offset, array.Count, cancellationToken));
- }
- else
- {
- byte[] buffer = ArrayPool<byte>.Shared.Rent(destination.Length);
- return new ValueTask<int>(FinishReadAsync(stream.ReadAsync(buffer, 0, destination.Length, cancellationToken), buffer, destination));
-
- static async Task<int> FinishReadAsync(Task<int> readTask, byte[] localBuffer, Memory<byte> localDestination)
- {
- try
- {
- int result = await readTask.ConfigureAwait(false);
- new Span<byte>(localBuffer, 0, result).CopyTo(localDestination.Span);
- return result;
- }
- finally
- {
- ArrayPool<byte>.Shared.Return(localBuffer);
- }
- }
- }
- }
-
- internal static ValueTask WriteAsync(this Stream stream, ReadOnlyMemory<byte> source, CancellationToken cancellationToken = default)
- {
- if (MemoryMarshal.TryGetArray(source, out ArraySegment<byte> array))
- {
- return new ValueTask(stream.WriteAsync(array.Array, array.Offset, array.Count, cancellationToken));
- }
- else
- {
- byte[] buffer = ArrayPool<byte>.Shared.Rent(source.Length);
- source.Span.CopyTo(buffer);
- return new ValueTask(FinishWriteAsync(stream.WriteAsync(buffer, 0, source.Length, cancellationToken), buffer));
-
- static async Task FinishWriteAsync(Task writeTask, byte[] localBuffer)
- {
- try
- {
- await writeTask.ConfigureAwait(false);
- }
- finally
- {
- ArrayPool<byte>.Shared.Return(localBuffer);
- }
- }
- }
- }
- }
-
- internal static class BitConverter
- {
- internal static unsafe int ToInt32(ReadOnlySpan<byte> value)
- {
- Debug.Assert(value.Length >= sizeof(int));
- return Unsafe.ReadUnaligned<int>(ref MemoryMarshal.GetReference(value));
- }
- }
-}
+++ /dev/null
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.IO;
-using System.Runtime.Versioning;
-using System.Threading;
-
-namespace System.Net.WebSockets
-{
- [UnsupportedOSPlatform("browser")]
- public static class WebSocketProtocol
- {
- public static WebSocket CreateFromStream(
- Stream stream,
- bool isServer,
- string? subProtocol,
- TimeSpan keepAliveInterval)
- {
- if (stream == null)
- {
- throw new ArgumentNullException(nameof(stream));
- }
-
- if (!stream.CanRead || !stream.CanWrite)
- {
- throw new ArgumentException(!stream.CanRead ? SR.NotReadableStream : SR.NotWriteableStream, nameof(stream));
- }
-
- if (subProtocol != null)
- {
- WebSocketValidate.ValidateSubprotocol(subProtocol);
- }
-
- if (keepAliveInterval != Timeout.InfiniteTimeSpan && keepAliveInterval < TimeSpan.Zero)
- {
- throw new ArgumentOutOfRangeException(nameof(keepAliveInterval), keepAliveInterval,
- SR.Format(SR.net_WebSockets_ArgumentOutOfRange_TooSmall,
- 0));
- }
-
- return ManagedWebSocket.CreateFromConnectedStream(stream, isServer, subProtocol, keepAliveInterval);
- }
- }
-}
+++ /dev/null
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Runtime.CompilerServices;
-
-namespace System.Numerics
-{
- // NOTE: This is an edited excerpt copy from src\Common\src\CoreLib\System\Numerics\BitOperations.cs.
- // It is only for use downlevel and internally by WebSocketProtocol.
-
- internal static class BitOperations
- {
- /// <summary>
- /// Rotates the specified value right by the specified number of bits.
- /// Similar in behavior to the x86 instruction ROR.
- /// </summary>
- /// <param name="value">The value to rotate.</param>
- /// <param name="offset">The number of bits to rotate by.
- /// Any value outside the range [0..31] is treated as congruent mod 32.</param>
- /// <returns>The rotated value.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static uint RotateRight(uint value, int offset) =>
- (value >> offset) | (value << (32 - offset));
- }
-}
+++ /dev/null
-<Project Sdk="Microsoft.NET.Sdk">
- <PropertyGroup>
- <TargetFrameworks>$(NetCoreAppCurrent);net48</TargetFrameworks>
- </PropertyGroup>
- <ItemGroup>
- <Compile Include="$(CommonTestPath)System\Net\WebSockets\WebSocketCreateTest.cs"
- Link="Common\System\Net\WebSockets\WebSocketCreateTest.cs" />
- <Compile Include="$(CommonTestPath)System\Net\Configuration.cs"
- Link="Common\System\Net\Configuration.cs" />
- <Compile Include="$(CommonTestPath)System\Net\Configuration.WebSockets.cs"
- Link="Common\System\Net\Configuration.WebSockets.cs" />
- <Compile Include="$(CommonPath)System\Net\HttpKnownHeaderNames.cs"
- Link="Common\System\Net\HttpKnownHeaderNames.cs" />
- <Compile Include="WebSocketProtocolTests.cs" />
- </ItemGroup>
- <ItemGroup>
- <ProjectReference Include="..\src\System.Net.WebSockets.WebSocketProtocol.csproj" />
- </ItemGroup>
-</Project>
+++ /dev/null
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.IO;
-using Xunit;
-
-namespace System.Net.WebSockets.Tests
-{
- public sealed class WebSocketProtocolCreateTests : WebSocketCreateTest
- {
- protected override WebSocket CreateFromStream(Stream stream, bool isServer, string subProtocol, TimeSpan keepAliveInterval) =>
- WebSocketProtocol.CreateFromStream(stream, isServer, subProtocol, keepAliveInterval);
- }
-}
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
- <Compile Include="System\Net\WebSockets\ManagedWebSocket.netcoreapp.cs" />
<Compile Include="System\Net\WebSockets\ValueWebSocketReceiveResult.cs" />
<Compile Include="System\Net\WebSockets\WebSocket.cs" />
<Compile Include="System\Net\WebSockets\WebSocketCloseStatus.cs" />
<Compile Include="System\Net\WebSockets\WebSocketMessageType.cs" />
<Compile Include="System\Net\WebSockets\WebSocketReceiveResult.cs" />
<Compile Include="System\Net\WebSockets\WebSocketState.cs" />
+ <Compile Include="System\Net\WebSockets\ManagedWebSocket.cs" />
<Compile Include="$(CommonPath)System\Net\WebSockets\WebSocketValidate.cs"
Link="Common\System\Net\WebSockets\WebSocketValidate.cs" />
- <Compile Include="$(CommonPath)System\Net\WebSockets\ManagedWebSocket.cs"
- Link="Common\System\Net\WebSockets\ManagedWebSocket.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="Microsoft.Win32.Primitives" />
/// <summary>Valid states to be in when calling CloseAsync.</summary>
private static readonly WebSocketState[] s_validCloseStates = { WebSocketState.Open, WebSocketState.CloseReceived, WebSocketState.CloseSent };
-#pragma warning disable CA1823 // not used by System.Net.WebSockets.WebSocketProtocol.dll
/// <summary>Successfully completed task representing a close message.</summary>
private static readonly Task<WebSocketReceiveResult> s_cachedCloseTask = Task.FromResult(new WebSocketReceiveResult(0, WebSocketMessageType.Close, true));
-#pragma warning restore CA1823
/// <summary>The maximum size in bytes of a message frame header that includes mask bytes.</summary>
internal const int MaxMessageHeaderLength = 14;
Dispose(); // forcibly tear down connection
}
+ public override ValueTask SendAsync(ReadOnlyMemory<byte> buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken)
+ {
+ return SendPrivateAsync(buffer, messageType, endOfMessage, cancellationToken);
+ }
+
+ public override ValueTask<ValueWebSocketReceiveResult> ReceiveAsync(Memory<byte> buffer, CancellationToken cancellationToken)
+ {
+ try
+ {
+ WebSocketValidate.ThrowIfInvalidState(_state, _disposed, s_validReceiveStates);
+
+ Debug.Assert(!Monitor.IsEntered(StateUpdateLock), $"{nameof(StateUpdateLock)} must never be held when acquiring {nameof(ReceiveAsyncLock)}");
+ lock (ReceiveAsyncLock) // synchronize with receives in CloseAsync
+ {
+ ThrowIfOperationInProgress(_lastReceiveAsync.IsCompleted);
+
+ ValueTask<ValueWebSocketReceiveResult> receiveValueTask = ReceiveAsyncPrivate<ValueWebSocketReceiveResultGetter, ValueWebSocketReceiveResult>(buffer, cancellationToken);
+ if (receiveValueTask.IsCompletedSuccessfully)
+ {
+ _lastReceiveAsync = receiveValueTask.Result.MessageType == WebSocketMessageType.Close ? s_cachedCloseTask : Task.CompletedTask;
+ return receiveValueTask;
+ }
+
+ // We need to both store the last receive task and return it, but we can't do that with a ValueTask,
+ // as that could result in consuming it multiple times. Instead, we use AsTask to consume it just once,
+ // and then store that Task and return a new ValueTask that wraps it. (It would be nice in the future
+ // to avoid this AsTask as well; currently it's used both for error detection and as part of close tracking.)
+ Task<ValueWebSocketReceiveResult> receiveTask = receiveValueTask.AsTask();
+ _lastReceiveAsync = receiveTask;
+ return new ValueTask<ValueWebSocketReceiveResult>(receiveTask);
+ }
+ }
+ catch (Exception exc)
+ {
+ return ValueTask.FromException<ValueWebSocketReceiveResult>(exc);
+ }
+ }
+
+ private Task ValidateAndReceiveAsync(Task receiveTask, byte[] buffer, CancellationToken cancellationToken)
+ {
+ if (receiveTask == null ||
+ (receiveTask.IsCompletedSuccessfully &&
+ !(receiveTask is Task<WebSocketReceiveResult> wsrr && wsrr.Result.MessageType == WebSocketMessageType.Close) &&
+ !(receiveTask is Task<ValueWebSocketReceiveResult> vwsrr && vwsrr.Result.MessageType == WebSocketMessageType.Close)))
+ {
+ ValueTask<ValueWebSocketReceiveResult> vt = ReceiveAsyncPrivate<ValueWebSocketReceiveResultGetter, ValueWebSocketReceiveResult>(buffer, cancellationToken);
+ receiveTask =
+ vt.IsCompletedSuccessfully ? (vt.Result.MessageType == WebSocketMessageType.Close ? s_cachedCloseTask : Task.CompletedTask) :
+ vt.AsTask();
+ }
+
+ return receiveTask;
+ }
+
+ /// <summary><see cref="IWebSocketReceiveResultGetter{TResult}"/> implementation for <see cref="ValueWebSocketReceiveResult"/>.</summary>
+ private readonly struct ValueWebSocketReceiveResultGetter : IWebSocketReceiveResultGetter<ValueWebSocketReceiveResult>
+ {
+ public ValueWebSocketReceiveResult GetResult(int count, WebSocketMessageType messageType, bool endOfMessage, WebSocketCloseStatus? closeStatus, string? closeDescription) =>
+ new ValueWebSocketReceiveResult(count, messageType, endOfMessage); // closeStatus/closeDescription are ignored
+ }
+
/// <summary>Sends a websocket frame to the network.</summary>
/// <param name="opcode">The opcode for the message.</param>
/// <param name="endOfMessage">The value of the FIN bit for the message.</param>
+++ /dev/null
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Diagnostics;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace System.Net.WebSockets
-{
- internal sealed partial class ManagedWebSocket : WebSocket
- {
- public override ValueTask SendAsync(ReadOnlyMemory<byte> buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken)
- {
- return SendPrivateAsync(buffer, messageType, endOfMessage, cancellationToken);
- }
-
- public override ValueTask<ValueWebSocketReceiveResult> ReceiveAsync(Memory<byte> buffer, CancellationToken cancellationToken)
- {
- try
- {
- WebSocketValidate.ThrowIfInvalidState(_state, _disposed, s_validReceiveStates);
-
- Debug.Assert(!Monitor.IsEntered(StateUpdateLock), $"{nameof(StateUpdateLock)} must never be held when acquiring {nameof(ReceiveAsyncLock)}");
- lock (ReceiveAsyncLock) // synchronize with receives in CloseAsync
- {
- ThrowIfOperationInProgress(_lastReceiveAsync.IsCompleted);
-
- ValueTask<ValueWebSocketReceiveResult> receiveValueTask = ReceiveAsyncPrivate<ValueWebSocketReceiveResultGetter, ValueWebSocketReceiveResult>(buffer, cancellationToken);
- if (receiveValueTask.IsCompletedSuccessfully)
- {
- _lastReceiveAsync = receiveValueTask.Result.MessageType == WebSocketMessageType.Close ? s_cachedCloseTask : Task.CompletedTask;
- return receiveValueTask;
- }
-
- // We need to both store the last receive task and return it, but we can't do that with a ValueTask,
- // as that could result in consuming it multiple times. Instead, we use AsTask to consume it just once,
- // and then store that Task and return a new ValueTask that wraps it. (It would be nice in the future
- // to avoid this AsTask as well; currently it's used both for error detection and as part of close tracking.)
- Task<ValueWebSocketReceiveResult> receiveTask = receiveValueTask.AsTask();
- _lastReceiveAsync = receiveTask;
- return new ValueTask<ValueWebSocketReceiveResult>(receiveTask);
- }
- }
- catch (Exception exc)
- {
- return ValueTask.FromException<ValueWebSocketReceiveResult>(exc);
- }
- }
-
- private Task ValidateAndReceiveAsync(Task receiveTask, byte[] buffer, CancellationToken cancellationToken)
- {
- if (receiveTask == null ||
- (receiveTask.IsCompletedSuccessfully &&
- !(receiveTask is Task<WebSocketReceiveResult> wsrr && wsrr.Result.MessageType == WebSocketMessageType.Close) &&
- !(receiveTask is Task<ValueWebSocketReceiveResult> vwsrr && vwsrr.Result.MessageType == WebSocketMessageType.Close)))
- {
- ValueTask<ValueWebSocketReceiveResult> vt = ReceiveAsyncPrivate<ValueWebSocketReceiveResultGetter, ValueWebSocketReceiveResult>(buffer, cancellationToken);
- receiveTask =
- vt.IsCompletedSuccessfully ? (vt.Result.MessageType == WebSocketMessageType.Close ? s_cachedCloseTask : Task.CompletedTask) :
- vt.AsTask();
- }
-
- return receiveTask;
- }
-
- /// <summary><see cref="IWebSocketReceiveResultGetter{TResult}"/> implementation for <see cref="ValueWebSocketReceiveResult"/>.</summary>
- private readonly struct ValueWebSocketReceiveResultGetter : IWebSocketReceiveResultGetter<ValueWebSocketReceiveResult>
- {
- public ValueWebSocketReceiveResult GetResult(int count, WebSocketMessageType messageType, bool endOfMessage, WebSocketCloseStatus? closeStatus, string? closeDescription) =>
- new ValueWebSocketReceiveResult(count, messageType, endOfMessage); // closeStatus/closeDescription are ignored
- }
- }
-}
<Compile Include="WebSocketTests.cs" />
<Compile Include="WebSocketExceptionTests.cs" />
<Compile Include="WebSocketReceiveResultTests.cs" />
- <Compile Include="$(CommonTestPath)System\Net\WebSockets\WebSocketCreateTest.cs"
- Link="Common\System\Net\WebSockets\WebSocketCreateTest.cs" />
+ <Compile Include="WebSocketCreateTest.cs" />
<Compile Include="$(CommonTestPath)System\Net\Configuration.cs"
Link="Common\System\Net\Configuration.cs" />
<Compile Include="$(CommonTestPath)System\Net\Configuration.WebSockets.cs"
"4.6.0",
"5.0.0"
],
- "BaselineVersion": "6.0.0",
"InboxOn": {},
"AssemblyVersionInPackageVersion": {
"4.0.0.0": "4.5.0",
"4.0.0.1": "4.5.2",
"4.0.0.2": "4.5.3",
"4.0.1.0": "4.6.0",
- "5.0.0.0": "5.0.0",
- "6.0.0.0": "6.0.0"
+ "5.0.0.0": "5.0.0"
}
},
"System.Numerics": {
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Private.Xml/tests/XmlSerializer/ReflectionOnly/System.Xml.XmlSerializer.ReflectionOnly.Tests.csproj" />
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Private.Xml/tests/XmlSerializer/System.Xml.XmlSerializer.Tests.csproj" />
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Linq.Queryable/tests/System.Linq.Queryable.Tests.csproj" />
- <ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Net.WebSockets.WebSocketProtocol/tests/System.Net.WebSockets.WebSocketProtocol.Tests.csproj" />
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Reflection.DispatchProxy/tests/System.Reflection.DispatchProxy.Tests.csproj" />
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Reflection.Emit.Lightweight/tests/System.Reflection.Emit.Lightweight.Tests.csproj" />
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Runtime.Serialization.Json/tests/System.Runtime.Serialization.Json.Tests.csproj" />
'System.Net.WebProxy.dll',
'System.Net.WebSockets.Client.dll',
'System.Net.WebSockets.dll',
- 'System.Net.WebSockets.WebSocketProtocol.dll',
'System.Numerics.dll',
'System.Numerics.Tensors.dll',
'System.Numerics.Vectors.dll',