Ver Fonte

Remove SocketHttpListener

Claus Vium há 6 anos atrás
pai
commit
77addb2283

+ 0 - 2
Emby.Server.Implementations/Emby.Server.Implementations.csproj

@@ -9,7 +9,6 @@
     <ProjectReference Include="..\MediaBrowser.Providers\MediaBrowser.Providers.csproj" />
     <ProjectReference Include="..\MediaBrowser.Providers\MediaBrowser.Providers.csproj" />
     <ProjectReference Include="..\MediaBrowser.WebDashboard\MediaBrowser.WebDashboard.csproj" />
     <ProjectReference Include="..\MediaBrowser.WebDashboard\MediaBrowser.WebDashboard.csproj" />
     <ProjectReference Include="..\MediaBrowser.XbmcMetadata\MediaBrowser.XbmcMetadata.csproj" />
     <ProjectReference Include="..\MediaBrowser.XbmcMetadata\MediaBrowser.XbmcMetadata.csproj" />
-    <ProjectReference Include="..\SocketHttpListener\SocketHttpListener.csproj" />
     <ProjectReference Include="..\Emby.Dlna\Emby.Dlna.csproj" />
     <ProjectReference Include="..\Emby.Dlna\Emby.Dlna.csproj" />
     <ProjectReference Include="..\Mono.Nat\Mono.Nat.csproj" />
     <ProjectReference Include="..\Mono.Nat\Mono.Nat.csproj" />
     <ProjectReference Include="..\MediaBrowser.Api\MediaBrowser.Api.csproj" />
     <ProjectReference Include="..\MediaBrowser.Api\MediaBrowser.Api.csproj" />
@@ -40,7 +39,6 @@
     <PackageReference Include="ServiceStack.Text.Core" Version="5.4.0" />
     <PackageReference Include="ServiceStack.Text.Core" Version="5.4.0" />
     <PackageReference Include="sharpcompress" Version="0.22.0" />
     <PackageReference Include="sharpcompress" Version="0.22.0" />
     <PackageReference Include="SQLitePCL.pretty.netstandard" Version="1.0.0" />
     <PackageReference Include="SQLitePCL.pretty.netstandard" Version="1.0.0" />
-    <PackageReference Include="System.Buffers" Version="4.5.0" />
     <PackageReference Include="UTF.Unknown" Version="1.0.0-beta1" />
     <PackageReference Include="UTF.Unknown" Version="1.0.0-beta1" />
   </ItemGroup>
   </ItemGroup>
 
 

+ 1 - 2
Emby.Server.Implementations/SocketSharp/SharpWebSocket.cs

@@ -23,9 +23,8 @@ namespace Emby.Server.Implementations.SocketSharp
         /// <value>The web socket.</value>
         /// <value>The web socket.</value>
         private readonly WebSocket _webSocket;
         private readonly WebSocket _webSocket;
 
 
-        private TaskCompletionSource<bool> _taskCompletionSource = new TaskCompletionSource<bool>();
         private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
         private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
-        private bool _disposed = false;
+        private bool _disposed;
 
 
         public SharpWebSocket(WebSocket socket, ILogger logger)
         public SharpWebSocket(WebSocket socket, ILogger logger)
         {
         {

+ 0 - 1
Emby.Server.Implementations/SocketSharp/WebSocketSharpRequest.cs

@@ -11,7 +11,6 @@ using Microsoft.AspNetCore.Http.Extensions;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Primitives;
 using Microsoft.Extensions.Primitives;
 using Microsoft.Net.Http.Headers;
 using Microsoft.Net.Http.Headers;
-using SocketHttpListener.Net;
 using IHttpFile = MediaBrowser.Model.Services.IHttpFile;
 using IHttpFile = MediaBrowser.Model.Services.IHttpFile;
 using IHttpRequest = MediaBrowser.Model.Services.IHttpRequest;
 using IHttpRequest = MediaBrowser.Model.Services.IHttpRequest;
 using IHttpResponse = MediaBrowser.Model.Services.IHttpResponse;
 using IHttpResponse = MediaBrowser.Model.Services.IHttpResponse;

+ 187 - 192
MediaBrowser.sln

@@ -1,192 +1,187 @@
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 15
-VisualStudioVersion = 15.0.26730.3
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MediaBrowser.Controller", "MediaBrowser.Controller\MediaBrowser.Controller.csproj", "{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MediaBrowser.Api", "MediaBrowser.Api\MediaBrowser.Api.csproj", "{4FD51AC5-2C16-4308-A993-C3A84F3B4582}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MediaBrowser.Common", "MediaBrowser.Common\MediaBrowser.Common.csproj", "{9142EEFA-7570-41E1-BFCC-468BB571AF2F}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MediaBrowser.Model", "MediaBrowser.Model\MediaBrowser.Model.csproj", "{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MediaBrowser.WebDashboard", "MediaBrowser.WebDashboard\MediaBrowser.WebDashboard.csproj", "{5624B7B5-B5A7-41D8-9F10-CC5611109619}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MediaBrowser.Providers", "MediaBrowser.Providers\MediaBrowser.Providers.csproj", "{442B5058-DCAF-4263-BB6A-F21E31120A1B}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenSubtitlesHandler", "OpenSubtitlesHandler\OpenSubtitlesHandler.csproj", "{4A4402D4-E910-443B-B8FC-2C18286A2CA0}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MediaBrowser.XbmcMetadata", "MediaBrowser.XbmcMetadata\MediaBrowser.XbmcMetadata.csproj", "{23499896-B135-4527-8574-C26E926EA99E}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MediaBrowser.LocalMetadata", "MediaBrowser.LocalMetadata\MediaBrowser.LocalMetadata.csproj", "{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Emby.Drawing", "Emby.Drawing\Emby.Drawing.csproj", "{08FFF49B-F175-4807-A2B5-73B0EBD9F716}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Emby.Photos", "Emby.Photos\Emby.Photos.csproj", "{89AB4548-770D-41FD-A891-8DAFF44F452C}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DvdLib", "DvdLib\DvdLib.csproj", "{713F42B5-878E-499D-A878-E4C652B1D5E8}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BDInfo", "BDInfo\BDInfo.csproj", "{88AE38DF-19D7-406F-A6A9-09527719A21E}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Emby.Server.Implementations", "Emby.Server.Implementations\Emby.Server.Implementations.csproj", "{E383961B-9356-4D5D-8233-9A1079D03055}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RSSDP", "RSSDP\RSSDP.csproj", "{21002819-C39A-4D3E-BE83-2A276A77FB1F}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Emby.Dlna", "Emby.Dlna\Emby.Dlna.csproj", "{805844AB-E92F-45E6-9D99-4F6D48D129A5}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mono.Nat", "Mono.Nat\Mono.Nat.csproj", "{CB7F2326-6497-4A3D-BA03-48513B17A7BE}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SocketHttpListener", "SocketHttpListener\SocketHttpListener.csproj", "{1D74413B-E7CF-455B-B021-F52BDF881542}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Emby.Notifications", "Emby.Notifications\Emby.Notifications.csproj", "{2E030C33-6923-4530-9E54-FA29FA6AD1A9}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Emby.Naming", "Emby.Naming\Emby.Naming.csproj", "{E5AF7B26-2239-4CE0-B477-0AA2018EDAA2}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Emby.XmlTv", "Emby.XmlTv\Emby.XmlTv\Emby.XmlTv.csproj", "{6EAFA7F0-8A82-49E6-B2FA-086C5CAEA95B}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IsoMounter", "Emby.IsoMounting\IsoMounter\IsoMounter.csproj", "{9BA471D2-6DB9-4DBF-B3A0-9FB3171F94A6}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MediaBrowser.MediaEncoding", "MediaBrowser.MediaEncoding\MediaBrowser.MediaEncoding.csproj", "{960295EE-4AF4-4440-A525-B4C295B01A61}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Jellyfin.Server", "Jellyfin.Server\Jellyfin.Server.csproj", "{07E39F42-A2C6-4B32-AF8C-725F957A73FF}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{41093F42-C7CC-4D07-956B-6182CBEDE2EC}"
-	ProjectSection(SolutionItems) = preProject
-		.editorconfig = .editorconfig
-		SharedVersion.cs = SharedVersion.cs
-	EndProjectSection
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfin.Drawing.Skia", "Jellyfin.Drawing.Skia\Jellyfin.Drawing.Skia.csproj", "{154872D9-6C12-4007-96E3-8F70A58386CE}"
-EndProject
-Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|Any CPU = Debug|Any CPU
-		Release|Any CPU = Release|Any CPU
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release|Any CPU.Build.0 = Release|Any CPU
-		{4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release|Any CPU.Build.0 = Release|Any CPU
-		{9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release|Any CPU.Build.0 = Release|Any CPU
-		{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Release|Any CPU.Build.0 = Release|Any CPU
-		{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release|Any CPU.Build.0 = Release|Any CPU
-		{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release|Any CPU.Build.0 = Release|Any CPU
-		{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release|Any CPU.Build.0 = Release|Any CPU
-		{23499896-B135-4527-8574-C26E926EA99E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{23499896-B135-4527-8574-C26E926EA99E}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{23499896-B135-4527-8574-C26E926EA99E}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{23499896-B135-4527-8574-C26E926EA99E}.Release|Any CPU.Build.0 = Release|Any CPU
-		{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Release|Any CPU.Build.0 = Release|Any CPU
-		{08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Release|Any CPU.Build.0 = Release|Any CPU
-		{89AB4548-770D-41FD-A891-8DAFF44F452C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{89AB4548-770D-41FD-A891-8DAFF44F452C}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{89AB4548-770D-41FD-A891-8DAFF44F452C}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{89AB4548-770D-41FD-A891-8DAFF44F452C}.Release|Any CPU.Build.0 = Release|Any CPU
-		{713F42B5-878E-499D-A878-E4C652B1D5E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{713F42B5-878E-499D-A878-E4C652B1D5E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{713F42B5-878E-499D-A878-E4C652B1D5E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{713F42B5-878E-499D-A878-E4C652B1D5E8}.Release|Any CPU.Build.0 = Release|Any CPU
-		{88AE38DF-19D7-406F-A6A9-09527719A21E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{88AE38DF-19D7-406F-A6A9-09527719A21E}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{88AE38DF-19D7-406F-A6A9-09527719A21E}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{88AE38DF-19D7-406F-A6A9-09527719A21E}.Release|Any CPU.Build.0 = Release|Any CPU
-		{E383961B-9356-4D5D-8233-9A1079D03055}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{E383961B-9356-4D5D-8233-9A1079D03055}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{E383961B-9356-4D5D-8233-9A1079D03055}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{E383961B-9356-4D5D-8233-9A1079D03055}.Release|Any CPU.Build.0 = Release|Any CPU
-		{21002819-C39A-4D3E-BE83-2A276A77FB1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{21002819-C39A-4D3E-BE83-2A276A77FB1F}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{21002819-C39A-4D3E-BE83-2A276A77FB1F}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{21002819-C39A-4D3E-BE83-2A276A77FB1F}.Release|Any CPU.Build.0 = Release|Any CPU
-		{805844AB-E92F-45E6-9D99-4F6D48D129A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{805844AB-E92F-45E6-9D99-4F6D48D129A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{805844AB-E92F-45E6-9D99-4F6D48D129A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{805844AB-E92F-45E6-9D99-4F6D48D129A5}.Release|Any CPU.Build.0 = Release|Any CPU
-		{CB7F2326-6497-4A3D-BA03-48513B17A7BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{CB7F2326-6497-4A3D-BA03-48513B17A7BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{CB7F2326-6497-4A3D-BA03-48513B17A7BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{CB7F2326-6497-4A3D-BA03-48513B17A7BE}.Release|Any CPU.Build.0 = Release|Any CPU
-		{1D74413B-E7CF-455B-B021-F52BDF881542}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{1D74413B-E7CF-455B-B021-F52BDF881542}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{1D74413B-E7CF-455B-B021-F52BDF881542}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{1D74413B-E7CF-455B-B021-F52BDF881542}.Release|Any CPU.Build.0 = Release|Any CPU
-		{2E030C33-6923-4530-9E54-FA29FA6AD1A9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{2E030C33-6923-4530-9E54-FA29FA6AD1A9}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{2E030C33-6923-4530-9E54-FA29FA6AD1A9}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{2E030C33-6923-4530-9E54-FA29FA6AD1A9}.Release|Any CPU.Build.0 = Release|Any CPU
-		{E5AF7B26-2239-4CE0-B477-0AA2018EDAA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{E5AF7B26-2239-4CE0-B477-0AA2018EDAA2}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{E5AF7B26-2239-4CE0-B477-0AA2018EDAA2}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{E5AF7B26-2239-4CE0-B477-0AA2018EDAA2}.Release|Any CPU.Build.0 = Release|Any CPU
-		{6EAFA7F0-8A82-49E6-B2FA-086C5CAEA95B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{6EAFA7F0-8A82-49E6-B2FA-086C5CAEA95B}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{6EAFA7F0-8A82-49E6-B2FA-086C5CAEA95B}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{6EAFA7F0-8A82-49E6-B2FA-086C5CAEA95B}.Release|Any CPU.Build.0 = Release|Any CPU
-		{9BA471D2-6DB9-4DBF-B3A0-9FB3171F94A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{9BA471D2-6DB9-4DBF-B3A0-9FB3171F94A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{9BA471D2-6DB9-4DBF-B3A0-9FB3171F94A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{9BA471D2-6DB9-4DBF-B3A0-9FB3171F94A6}.Release|Any CPU.Build.0 = Release|Any CPU
-		{960295EE-4AF4-4440-A525-B4C295B01A61}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{960295EE-4AF4-4440-A525-B4C295B01A61}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{960295EE-4AF4-4440-A525-B4C295B01A61}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{960295EE-4AF4-4440-A525-B4C295B01A61}.Release|Any CPU.Build.0 = Release|Any CPU
-		{07E39F42-A2C6-4B32-AF8C-725F957A73FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{07E39F42-A2C6-4B32-AF8C-725F957A73FF}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{07E39F42-A2C6-4B32-AF8C-725F957A73FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{07E39F42-A2C6-4B32-AF8C-725F957A73FF}.Release|Any CPU.Build.0 = Release|Any CPU
-		{154872D9-6C12-4007-96E3-8F70A58386CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{154872D9-6C12-4007-96E3-8F70A58386CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{154872D9-6C12-4007-96E3-8F70A58386CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{154872D9-6C12-4007-96E3-8F70A58386CE}.Release|Any CPU.Build.0 = Release|Any CPU
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
-	EndGlobalSection
-	GlobalSection(ExtensibilityGlobals) = postSolution
-		SolutionGuid = {3448830C-EBDC-426C-85CD-7BBB9651A7FE}
-	EndGlobalSection
-	GlobalSection(AutomaticVersions) = postSolution
-		UpdateAssemblyVersion = True
-		UpdateAssemblyFileVersion = True
-		UpdateAssemblyInfoVersion = True
-		AssemblyVersionSettings = None.None.None.None
-		AssemblyFileVersionSettings = None.None.None.None
-		AssemblyInfoVersionSettings = None.None.None.None
-		UpdatePackageVersion = False
-		AssemblyInfoVersionType = SettingsVersion
-		InheritWinAppVersionFrom = None
-	EndGlobalSection
-	GlobalSection(MonoDevelopProperties) = preSolution
-		Policies = $0
-		$0.StandardHeader = $1
-		$1.Text = @### This header should be used to start new files.\n### It provides an explicit per-file license reference that should be present on all new files.\n### To use this header, delete these lines and the following empty line, modify <filename> to\n### the proper full path, and then add new code following the header and a single empty line.\n\n// ${FileName}\n// Part of the Jellyfin project (https://jellyfin.media)\n//\n//    All copyright belongs to the Jellyfin contributors; a full list can\n//    be found in the file CONTRIBUTORS.md\n//\n//    This program is free software: you can redistribute it and/or modify\n//    it under the terms of the GNU General Public License as published by\n//    the Free Software Foundation, version 2.\n//\n//    This program is distributed in the hope that it will be useful,\n//    but WITHOUT ANY WARRANTY; without even the implied warranty of\n//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n//    GNU General Public License for more details.\n//\n//    You should have received a copy of the GNU General Public License\n//    along with this program.  If not, see <https://www.gnu.org/licenses/>.\n
-		$0.DotNetNamingPolicy = $2
-		$2.DirectoryNamespaceAssociation = PrefixedHierarchical
-	EndGlobalSection
-EndGlobal
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.26730.3
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MediaBrowser.Controller", "MediaBrowser.Controller\MediaBrowser.Controller.csproj", "{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MediaBrowser.Api", "MediaBrowser.Api\MediaBrowser.Api.csproj", "{4FD51AC5-2C16-4308-A993-C3A84F3B4582}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MediaBrowser.Common", "MediaBrowser.Common\MediaBrowser.Common.csproj", "{9142EEFA-7570-41E1-BFCC-468BB571AF2F}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MediaBrowser.Model", "MediaBrowser.Model\MediaBrowser.Model.csproj", "{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MediaBrowser.WebDashboard", "MediaBrowser.WebDashboard\MediaBrowser.WebDashboard.csproj", "{5624B7B5-B5A7-41D8-9F10-CC5611109619}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MediaBrowser.Providers", "MediaBrowser.Providers\MediaBrowser.Providers.csproj", "{442B5058-DCAF-4263-BB6A-F21E31120A1B}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenSubtitlesHandler", "OpenSubtitlesHandler\OpenSubtitlesHandler.csproj", "{4A4402D4-E910-443B-B8FC-2C18286A2CA0}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MediaBrowser.XbmcMetadata", "MediaBrowser.XbmcMetadata\MediaBrowser.XbmcMetadata.csproj", "{23499896-B135-4527-8574-C26E926EA99E}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MediaBrowser.LocalMetadata", "MediaBrowser.LocalMetadata\MediaBrowser.LocalMetadata.csproj", "{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Emby.Drawing", "Emby.Drawing\Emby.Drawing.csproj", "{08FFF49B-F175-4807-A2B5-73B0EBD9F716}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Emby.Photos", "Emby.Photos\Emby.Photos.csproj", "{89AB4548-770D-41FD-A891-8DAFF44F452C}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DvdLib", "DvdLib\DvdLib.csproj", "{713F42B5-878E-499D-A878-E4C652B1D5E8}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BDInfo", "BDInfo\BDInfo.csproj", "{88AE38DF-19D7-406F-A6A9-09527719A21E}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Emby.Server.Implementations", "Emby.Server.Implementations\Emby.Server.Implementations.csproj", "{E383961B-9356-4D5D-8233-9A1079D03055}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RSSDP", "RSSDP\RSSDP.csproj", "{21002819-C39A-4D3E-BE83-2A276A77FB1F}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Emby.Dlna", "Emby.Dlna\Emby.Dlna.csproj", "{805844AB-E92F-45E6-9D99-4F6D48D129A5}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mono.Nat", "Mono.Nat\Mono.Nat.csproj", "{CB7F2326-6497-4A3D-BA03-48513B17A7BE}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Emby.Notifications", "Emby.Notifications\Emby.Notifications.csproj", "{2E030C33-6923-4530-9E54-FA29FA6AD1A9}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Emby.Naming", "Emby.Naming\Emby.Naming.csproj", "{E5AF7B26-2239-4CE0-B477-0AA2018EDAA2}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Emby.XmlTv", "Emby.XmlTv\Emby.XmlTv\Emby.XmlTv.csproj", "{6EAFA7F0-8A82-49E6-B2FA-086C5CAEA95B}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IsoMounter", "Emby.IsoMounting\IsoMounter\IsoMounter.csproj", "{9BA471D2-6DB9-4DBF-B3A0-9FB3171F94A6}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MediaBrowser.MediaEncoding", "MediaBrowser.MediaEncoding\MediaBrowser.MediaEncoding.csproj", "{960295EE-4AF4-4440-A525-B4C295B01A61}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Jellyfin.Server", "Jellyfin.Server\Jellyfin.Server.csproj", "{07E39F42-A2C6-4B32-AF8C-725F957A73FF}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{41093F42-C7CC-4D07-956B-6182CBEDE2EC}"
+	ProjectSection(SolutionItems) = preProject
+		.editorconfig = .editorconfig
+		SharedVersion.cs = SharedVersion.cs
+	EndProjectSection
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Jellyfin.Drawing.Skia", "Jellyfin.Drawing.Skia\Jellyfin.Drawing.Skia.csproj", "{154872D9-6C12-4007-96E3-8F70A58386CE}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release|Any CPU.Build.0 = Release|Any CPU
+		{4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release|Any CPU.Build.0 = Release|Any CPU
+		{9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release|Any CPU.Build.0 = Release|Any CPU
+		{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Release|Any CPU.Build.0 = Release|Any CPU
+		{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release|Any CPU.Build.0 = Release|Any CPU
+		{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release|Any CPU.Build.0 = Release|Any CPU
+		{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release|Any CPU.Build.0 = Release|Any CPU
+		{23499896-B135-4527-8574-C26E926EA99E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{23499896-B135-4527-8574-C26E926EA99E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{23499896-B135-4527-8574-C26E926EA99E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{23499896-B135-4527-8574-C26E926EA99E}.Release|Any CPU.Build.0 = Release|Any CPU
+		{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Release|Any CPU.Build.0 = Release|Any CPU
+		{08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Release|Any CPU.Build.0 = Release|Any CPU
+		{89AB4548-770D-41FD-A891-8DAFF44F452C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{89AB4548-770D-41FD-A891-8DAFF44F452C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{89AB4548-770D-41FD-A891-8DAFF44F452C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{89AB4548-770D-41FD-A891-8DAFF44F452C}.Release|Any CPU.Build.0 = Release|Any CPU
+		{713F42B5-878E-499D-A878-E4C652B1D5E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{713F42B5-878E-499D-A878-E4C652B1D5E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{713F42B5-878E-499D-A878-E4C652B1D5E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{713F42B5-878E-499D-A878-E4C652B1D5E8}.Release|Any CPU.Build.0 = Release|Any CPU
+		{88AE38DF-19D7-406F-A6A9-09527719A21E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{88AE38DF-19D7-406F-A6A9-09527719A21E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{88AE38DF-19D7-406F-A6A9-09527719A21E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{88AE38DF-19D7-406F-A6A9-09527719A21E}.Release|Any CPU.Build.0 = Release|Any CPU
+		{E383961B-9356-4D5D-8233-9A1079D03055}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{E383961B-9356-4D5D-8233-9A1079D03055}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{E383961B-9356-4D5D-8233-9A1079D03055}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{E383961B-9356-4D5D-8233-9A1079D03055}.Release|Any CPU.Build.0 = Release|Any CPU
+		{21002819-C39A-4D3E-BE83-2A276A77FB1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{21002819-C39A-4D3E-BE83-2A276A77FB1F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{21002819-C39A-4D3E-BE83-2A276A77FB1F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{21002819-C39A-4D3E-BE83-2A276A77FB1F}.Release|Any CPU.Build.0 = Release|Any CPU
+		{805844AB-E92F-45E6-9D99-4F6D48D129A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{805844AB-E92F-45E6-9D99-4F6D48D129A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{805844AB-E92F-45E6-9D99-4F6D48D129A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{805844AB-E92F-45E6-9D99-4F6D48D129A5}.Release|Any CPU.Build.0 = Release|Any CPU
+		{CB7F2326-6497-4A3D-BA03-48513B17A7BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{CB7F2326-6497-4A3D-BA03-48513B17A7BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{CB7F2326-6497-4A3D-BA03-48513B17A7BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{CB7F2326-6497-4A3D-BA03-48513B17A7BE}.Release|Any CPU.Build.0 = Release|Any CPU
+		{2E030C33-6923-4530-9E54-FA29FA6AD1A9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{2E030C33-6923-4530-9E54-FA29FA6AD1A9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{2E030C33-6923-4530-9E54-FA29FA6AD1A9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{2E030C33-6923-4530-9E54-FA29FA6AD1A9}.Release|Any CPU.Build.0 = Release|Any CPU
+		{E5AF7B26-2239-4CE0-B477-0AA2018EDAA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{E5AF7B26-2239-4CE0-B477-0AA2018EDAA2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{E5AF7B26-2239-4CE0-B477-0AA2018EDAA2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{E5AF7B26-2239-4CE0-B477-0AA2018EDAA2}.Release|Any CPU.Build.0 = Release|Any CPU
+		{6EAFA7F0-8A82-49E6-B2FA-086C5CAEA95B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{6EAFA7F0-8A82-49E6-B2FA-086C5CAEA95B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{6EAFA7F0-8A82-49E6-B2FA-086C5CAEA95B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{6EAFA7F0-8A82-49E6-B2FA-086C5CAEA95B}.Release|Any CPU.Build.0 = Release|Any CPU
+		{9BA471D2-6DB9-4DBF-B3A0-9FB3171F94A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{9BA471D2-6DB9-4DBF-B3A0-9FB3171F94A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{9BA471D2-6DB9-4DBF-B3A0-9FB3171F94A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{9BA471D2-6DB9-4DBF-B3A0-9FB3171F94A6}.Release|Any CPU.Build.0 = Release|Any CPU
+		{960295EE-4AF4-4440-A525-B4C295B01A61}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{960295EE-4AF4-4440-A525-B4C295B01A61}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{960295EE-4AF4-4440-A525-B4C295B01A61}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{960295EE-4AF4-4440-A525-B4C295B01A61}.Release|Any CPU.Build.0 = Release|Any CPU
+		{07E39F42-A2C6-4B32-AF8C-725F957A73FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{07E39F42-A2C6-4B32-AF8C-725F957A73FF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{07E39F42-A2C6-4B32-AF8C-725F957A73FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{07E39F42-A2C6-4B32-AF8C-725F957A73FF}.Release|Any CPU.Build.0 = Release|Any CPU
+		{154872D9-6C12-4007-96E3-8F70A58386CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{154872D9-6C12-4007-96E3-8F70A58386CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{154872D9-6C12-4007-96E3-8F70A58386CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{154872D9-6C12-4007-96E3-8F70A58386CE}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {3448830C-EBDC-426C-85CD-7BBB9651A7FE}
+	EndGlobalSection
+	GlobalSection(AutomaticVersions) = postSolution
+		UpdateAssemblyVersion = True
+		UpdateAssemblyFileVersion = True
+		UpdateAssemblyInfoVersion = True
+		AssemblyVersionSettings = None.None.None.None
+		AssemblyFileVersionSettings = None.None.None.None
+		AssemblyInfoVersionSettings = None.None.None.None
+		UpdatePackageVersion = False
+		AssemblyInfoVersionType = SettingsVersion
+		InheritWinAppVersionFrom = None
+	EndGlobalSection
+	GlobalSection(MonoDevelopProperties) = preSolution
+		Policies = $0
+		$0.StandardHeader = $1
+		$1.Text = @### This header should be used to start new files.\n### It provides an explicit per-file license reference that should be present on all new files.\n### To use this header, delete these lines and the following empty line, modify <filename> to\n### the proper full path, and then add new code following the header and a single empty line.\n\n// ${FileName}\n// Part of the Jellyfin project (https://jellyfin.media)\n//\n//    All copyright belongs to the Jellyfin contributors; a full list can\n//    be found in the file CONTRIBUTORS.md\n//\n//    This program is free software: you can redistribute it and/or modify\n//    it under the terms of the GNU General Public License as published by\n//    the Free Software Foundation, version 2.\n//\n//    This program is distributed in the hope that it will be useful,\n//    but WITHOUT ANY WARRANTY; without even the implied warranty of\n//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n//    GNU General Public License for more details.\n//\n//    You should have received a copy of the GNU General Public License\n//    along with this program.  If not, see <https://www.gnu.org/licenses/>.\n
+		$0.DotNetNamingPolicy = $2
+		$2.DirectoryNamespaceAssociation = PrefixedHierarchical
+	EndGlobalSection
+EndGlobal

+ 0 - 17
SocketHttpListener/ByteOrder.cs

@@ -1,17 +0,0 @@
-namespace SocketHttpListener
-{
-    /// <summary>
-    /// Contains the values that indicate whether the byte order is a Little-endian or Big-endian.
-    /// </summary>
-    public enum ByteOrder : byte
-    {
-        /// <summary>
-        /// Indicates a Little-endian.
-        /// </summary>
-        Little,
-        /// <summary>
-        /// Indicates a Big-endian.
-        /// </summary>
-        Big
-    }
-}

+ 0 - 79
SocketHttpListener/CloseEventArgs.cs

@@ -1,79 +0,0 @@
-using System;
-using System.Text;
-
-namespace SocketHttpListener
-{
-    /// <summary>
-    /// Contains the event data associated with a <see cref="WebSocket.OnClose"/> event.
-    /// </summary>
-    /// <remarks>
-    /// A <see cref="WebSocket.OnClose"/> event occurs when the WebSocket connection has been closed.
-    /// If you would like to get the reason for the close, you should access the <see cref="Code"/> or
-    /// <see cref="Reason"/> property.
-    /// </remarks>
-    public class CloseEventArgs : EventArgs
-    {
-        #region Private Fields
-
-        private bool _clean;
-        private ushort _code;
-        private string _reason;
-
-        #endregion
-
-        #region Internal Constructors
-
-        internal CloseEventArgs(PayloadData payload)
-        {
-            var data = payload.ApplicationData;
-            var len = data.Length;
-            _code = len > 1
-                    ? data.SubArray(0, 2).ToUInt16(ByteOrder.Big)
-                    : (ushort)CloseStatusCode.NoStatusCode;
-
-            _reason = len > 2
-                      ? GetUtf8String(data.SubArray(2, len - 2))
-                      : string.Empty;
-        }
-
-        private static string GetUtf8String(byte[] bytes)
-        {
-            return Encoding.UTF8.GetString(bytes, 0, bytes.Length);
-        }
-
-        #endregion
-
-        #region Public Properties
-
-        /// <summary>
-        /// Gets the status code for the close.
-        /// </summary>
-        /// <value>
-        /// A <see cref="ushort"/> that represents the status code for the close if any.
-        /// </value>
-        public ushort Code => _code;
-
-        /// <summary>
-        /// Gets the reason for the close.
-        /// </summary>
-        /// <value>
-        /// A <see cref="string"/> that represents the reason for the close if any.
-        /// </value>
-        public string Reason => _reason;
-
-        /// <summary>
-        /// Gets a value indicating whether the WebSocket connection has been closed cleanly.
-        /// </summary>
-        /// <value>
-        /// <c>true</c> if the WebSocket connection has been closed cleanly; otherwise, <c>false</c>.
-        /// </value>
-        public bool WasClean
-        {
-            get => _clean;
-
-            internal set => _clean = value;
-        }
-
-        #endregion
-    }
-}

+ 0 - 94
SocketHttpListener/CloseStatusCode.cs

@@ -1,94 +0,0 @@
-namespace SocketHttpListener
-{
-    /// <summary>
-    /// Contains the values of the status code for the WebSocket connection close.
-    /// </summary>
-    /// <remarks>
-    ///   <para>
-    ///   The values of the status code are defined in
-    ///   <see href="http://tools.ietf.org/html/rfc6455#section-7.4">Section 7.4</see>
-    ///   of RFC 6455.
-    ///   </para>
-    ///   <para>
-    ///   "Reserved value" must not be set as a status code in a close control frame
-    ///   by an endpoint. It's designated for use in applications expecting a status
-    ///   code to indicate that the connection was closed due to the system grounds.
-    ///   </para>
-    /// </remarks>
-    public enum CloseStatusCode : ushort
-    {
-        /// <summary>
-        /// Equivalent to close status 1000.
-        /// Indicates a normal close.
-        /// </summary>
-        Normal = 1000,
-        /// <summary>
-        /// Equivalent to close status 1001.
-        /// Indicates that an endpoint is going away.
-        /// </summary>
-        Away = 1001,
-        /// <summary>
-        /// Equivalent to close status 1002.
-        /// Indicates that an endpoint is terminating the connection due to a protocol error.
-        /// </summary>
-        ProtocolError = 1002,
-        /// <summary>
-        /// Equivalent to close status 1003.
-        /// Indicates that an endpoint is terminating the connection because it has received
-        /// an unacceptable type message.
-        /// </summary>
-        IncorrectData = 1003,
-        /// <summary>
-        /// Equivalent to close status 1004.
-        /// Still undefined. Reserved value.
-        /// </summary>
-        Undefined = 1004,
-        /// <summary>
-        /// Equivalent to close status 1005.
-        /// Indicates that no status code was actually present. Reserved value.
-        /// </summary>
-        NoStatusCode = 1005,
-        /// <summary>
-        /// Equivalent to close status 1006.
-        /// Indicates that the connection was closed abnormally. Reserved value.
-        /// </summary>
-        Abnormal = 1006,
-        /// <summary>
-        /// Equivalent to close status 1007.
-        /// Indicates that an endpoint is terminating the connection because it has received
-        /// a message that contains a data that isn't consistent with the type of the message.
-        /// </summary>
-        InconsistentData = 1007,
-        /// <summary>
-        /// Equivalent to close status 1008.
-        /// Indicates that an endpoint is terminating the connection because it has received
-        /// a message that violates its policy.
-        /// </summary>
-        PolicyViolation = 1008,
-        /// <summary>
-        /// Equivalent to close status 1009.
-        /// Indicates that an endpoint is terminating the connection because it has received
-        /// a message that is too big to process.
-        /// </summary>
-        TooBig = 1009,
-        /// <summary>
-        /// Equivalent to close status 1010.
-        /// Indicates that the client is terminating the connection because it has expected
-        /// the server to negotiate one or more extension, but the server didn't return them
-        /// in the handshake response.
-        /// </summary>
-        IgnoreExtension = 1010,
-        /// <summary>
-        /// Equivalent to close status 1011.
-        /// Indicates that the server is terminating the connection because it has encountered
-        /// an unexpected condition that prevented it from fulfilling the request.
-        /// </summary>
-        ServerError = 1011,
-        /// <summary>
-        /// Equivalent to close status 1015.
-        /// Indicates that the connection was closed due to a failure to perform a TLS handshake.
-        /// Reserved value.
-        /// </summary>
-        TlsHandshakeFailure = 1015
-    }
-}

+ 0 - 23
SocketHttpListener/CompressionMethod.cs

@@ -1,23 +0,0 @@
-namespace SocketHttpListener
-{
-    /// <summary>
-    /// Contains the values of the compression method used to compress the message on the WebSocket
-    /// connection.
-    /// </summary>
-    /// <remarks>
-    /// The values of the compression method are defined in
-    /// <see href="http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-09">Compression
-    /// Extensions for WebSocket</see>.
-    /// </remarks>
-    public enum CompressionMethod : byte
-    {
-        /// <summary>
-        /// Indicates non compression.
-        /// </summary>
-        None,
-        /// <summary>
-        /// Indicates using DEFLATE.
-        /// </summary>
-        Deflate
-    }
-}

+ 0 - 42
SocketHttpListener/ErrorEventArgs.cs

@@ -1,42 +0,0 @@
-using System;
-
-namespace SocketHttpListener
-{
-    /// <summary>
-    /// Contains the event data associated with a <see cref="WebSocket.OnError"/> event.
-    /// </summary>
-    /// <remarks>
-    /// A <see cref="WebSocket.OnError"/> event occurs when the <see cref="WebSocket"/> gets an error.
-    /// If you would like to get the error message, you should access the <see cref="Message"/>
-    /// property.
-    /// </remarks>
-    public class ErrorEventArgs : EventArgs
-    {
-        #region Private Fields
-
-        private string _message;
-
-        #endregion
-
-        #region Internal Constructors
-
-        internal ErrorEventArgs(string message)
-        {
-            _message = message;
-        }
-
-        #endregion
-
-        #region Public Properties
-
-        /// <summary>
-        /// Gets the error message.
-        /// </summary>
-        /// <value>
-        /// A <see cref="string"/> that represents the error message.
-        /// </value>
-        public string Message => _message;
-
-        #endregion
-    }
-}

+ 0 - 946
SocketHttpListener/Ext.cs

@@ -1,946 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.IO.Compression;
-using System.Net;
-using System.Text;
-using System.Threading.Tasks;
-using MediaBrowser.Model.Services;
-using WebSocketState = System.Net.WebSockets.WebSocketState;
-
-namespace SocketHttpListener
-{
-    /// <summary>
-    /// Provides a set of static methods for the websocket-sharp.
-    /// </summary>
-    public static class Ext
-    {
-        #region Private Const Fields
-
-        private const string _tspecials = "()<>@,;:\\\"/[]?={} \t";
-
-        #endregion
-
-        #region Private Methods
-
-        private static MemoryStream compress(this Stream stream)
-        {
-            var output = new MemoryStream();
-            if (stream.Length == 0)
-                return output;
-
-            stream.Position = 0;
-            using (var ds = new DeflateStream(output, CompressionMode.Compress, true))
-            {
-                stream.CopyTo(ds);
-                //ds.Close(); // "BFINAL" set to 1.
-                output.Position = 0;
-
-                return output;
-            }
-        }
-
-        private static byte[] decompress(this byte[] value)
-        {
-            if (value.Length == 0)
-                return value;
-
-            using (var input = new MemoryStream(value))
-            {
-                return input.decompressToArray();
-            }
-        }
-
-        private static MemoryStream decompress(this Stream stream)
-        {
-            var output = new MemoryStream();
-            if (stream.Length == 0)
-                return output;
-
-            stream.Position = 0;
-            using (var ds = new DeflateStream(stream, CompressionMode.Decompress, true))
-            {
-                ds.CopyTo(output, true);
-                return output;
-            }
-        }
-
-        private static byte[] decompressToArray(this Stream stream)
-        {
-            using (var decomp = stream.decompress())
-            {
-                return decomp.ToArray();
-            }
-        }
-
-        private static async Task<byte[]> ReadBytesAsync(this Stream stream, byte[] buffer, int offset, int length)
-        {
-            var len = await stream.ReadAsync(buffer, offset, length).ConfigureAwait(false);
-            if (len < 1)
-                return buffer.SubArray(0, offset);
-
-            var tmp = 0;
-            while (len < length)
-            {
-                tmp = await stream.ReadAsync(buffer, offset + len, length - len).ConfigureAwait(false);
-                if (tmp < 1)
-                {
-                    break;
-                }
-
-                len += tmp;
-            }
-
-            return len < length
-                   ? buffer.SubArray(0, offset + len)
-                   : buffer;
-        }
-
-        private static async Task<bool> ReadBytesAsync(this Stream stream, byte[] buffer, int offset, int length, Stream dest)
-        {
-            var bytes = await stream.ReadBytesAsync(buffer, offset, length).ConfigureAwait(false);
-            var len = bytes.Length;
-            dest.Write(bytes, 0, len);
-
-            return len == offset + length;
-        }
-
-        #endregion
-
-        #region Internal Methods
-
-        internal static async Task<byte[]> AppendAsync(this ushort code, string reason)
-        {
-            using (var buffer = new MemoryStream())
-            {
-                var tmp = code.ToByteArrayInternally(ByteOrder.Big);
-                await buffer.WriteAsync(tmp, 0, 2).ConfigureAwait(false);
-                if (reason != null && reason.Length > 0)
-                {
-                    tmp = Encoding.UTF8.GetBytes(reason);
-                    await buffer.WriteAsync(tmp, 0, tmp.Length).ConfigureAwait(false);
-                }
-
-                return buffer.ToArray();
-            }
-        }
-
-        internal static string CheckIfClosable(this WebSocketState state)
-        {
-            return state == WebSocketState.CloseSent
-                   ? "While closing the WebSocket connection."
-                   : state == WebSocketState.Closed
-                     ? "The WebSocket connection has already been closed."
-                     : null;
-        }
-
-        internal static string CheckIfOpen(this WebSocketState state)
-        {
-            return state == WebSocketState.Connecting
-                   ? "A WebSocket connection isn't established."
-                   : state == WebSocketState.CloseSent
-                     ? "While closing the WebSocket connection."
-                     : state == WebSocketState.Closed
-                       ? "The WebSocket connection has already been closed."
-                       : null;
-        }
-
-        internal static string CheckIfValidControlData(this byte[] data, string paramName)
-        {
-            return data.Length > 125
-                   ? string.Format("'{0}' length must be less.", paramName)
-                   : null;
-        }
-
-        internal static Stream Compress(this Stream stream, CompressionMethod method)
-        {
-            return method == CompressionMethod.Deflate
-                   ? stream.compress()
-                   : stream;
-        }
-
-        internal static bool Contains<T>(this IEnumerable<T> source, Func<T, bool> condition)
-        {
-            foreach (T elm in source)
-                if (condition(elm))
-                    return true;
-
-            return false;
-        }
-
-        internal static void CopyTo(this Stream src, Stream dest, bool setDefaultPosition)
-        {
-            var readLen = 0;
-            var bufferLen = 256;
-            var buffer = new byte[bufferLen];
-            while ((readLen = src.Read(buffer, 0, bufferLen)) > 0)
-            {
-                dest.Write(buffer, 0, readLen);
-            }
-
-            if (setDefaultPosition)
-                dest.Position = 0;
-        }
-
-        internal static byte[] Decompress(this byte[] value, CompressionMethod method)
-        {
-            return method == CompressionMethod.Deflate
-                   ? value.decompress()
-                   : value;
-        }
-
-        internal static byte[] DecompressToArray(this Stream stream, CompressionMethod method)
-        {
-            return method == CompressionMethod.Deflate
-                   ? stream.decompressToArray()
-                   : stream.ToByteArray();
-        }
-
-        /// <summary>
-        /// Determines whether the specified <see cref="int"/> equals the specified <see cref="char"/>,
-        /// and invokes the specified Action&lt;int&gt; delegate at the same time.
-        /// </summary>
-        /// <returns>
-        /// <c>true</c> if <paramref name="value"/> equals <paramref name="c"/>;
-        /// otherwise, <c>false</c>.
-        /// </returns>
-        /// <param name="value">
-        /// An <see cref="int"/> to compare.
-        /// </param>
-        /// <param name="c">
-        /// A <see cref="char"/> to compare.
-        /// </param>
-        /// <param name="action">
-        /// An Action&lt;int&gt; delegate that references the method(s) called at
-        /// the same time as comparing. An <see cref="int"/> parameter to pass to
-        /// the method(s) is <paramref name="value"/>.
-        /// </param>
-        /// <exception cref="ArgumentOutOfRangeException">
-        /// <paramref name="value"/> isn't between 0 and 255.
-        /// </exception>
-        internal static bool EqualsWith(this int value, char c, Action<int> action)
-        {
-            if (value < 0 || value > 255)
-                throw new ArgumentOutOfRangeException(nameof(value));
-
-            action(value);
-            return value == c - 0;
-        }
-
-        internal static string GetMessage(this CloseStatusCode code)
-        {
-            return code == CloseStatusCode.ProtocolError
-                   ? "A WebSocket protocol error has occurred."
-                   : code == CloseStatusCode.IncorrectData
-                     ? "An incorrect data has been received."
-                     : code == CloseStatusCode.Abnormal
-                       ? "An exception has occurred."
-                       : code == CloseStatusCode.InconsistentData
-                         ? "An inconsistent data has been received."
-                         : code == CloseStatusCode.PolicyViolation
-                           ? "A policy violation has occurred."
-                           : code == CloseStatusCode.TooBig
-                             ? "A too big data has been received."
-                             : code == CloseStatusCode.IgnoreExtension
-                               ? "WebSocket client did not receive expected extension(s)."
-                               : code == CloseStatusCode.ServerError
-                                 ? "WebSocket server got an internal error."
-                                 : code == CloseStatusCode.TlsHandshakeFailure
-                                   ? "An error has occurred while handshaking."
-                                   : string.Empty;
-        }
-
-        internal static string GetNameInternal(this string nameAndValue, string separator)
-        {
-            var i = nameAndValue.IndexOf(separator);
-            return i > 0
-                   ? nameAndValue.Substring(0, i).Trim()
-                   : null;
-        }
-
-        internal static string GetValueInternal(this string nameAndValue, string separator)
-        {
-            var i = nameAndValue.IndexOf(separator);
-            return i >= 0 && i < nameAndValue.Length - 1
-                   ? nameAndValue.Substring(i + 1).Trim()
-                   : null;
-        }
-
-        internal static bool IsCompressionExtension(this string value, CompressionMethod method)
-        {
-            return value.StartsWith(method.ToExtensionString());
-        }
-
-        internal static bool IsPortNumber(this int value)
-        {
-            return value > 0 && value < 65536;
-        }
-
-        internal static bool IsReserved(this ushort code)
-        {
-            return code == (ushort)CloseStatusCode.Undefined ||
-                   code == (ushort)CloseStatusCode.NoStatusCode ||
-                   code == (ushort)CloseStatusCode.Abnormal ||
-                   code == (ushort)CloseStatusCode.TlsHandshakeFailure;
-        }
-
-        internal static bool IsReserved(this CloseStatusCode code)
-        {
-            return code == CloseStatusCode.Undefined ||
-                   code == CloseStatusCode.NoStatusCode ||
-                   code == CloseStatusCode.Abnormal ||
-                   code == CloseStatusCode.TlsHandshakeFailure;
-        }
-
-        internal static bool IsText(this string value)
-        {
-            var len = value.Length;
-            for (var i = 0; i < len; i++)
-            {
-                char c = value[i];
-                if (c < 0x20 && !"\r\n\t".Contains(c))
-                    return false;
-
-                if (c == 0x7f)
-                    return false;
-
-                if (c == '\n' && ++i < len)
-                {
-                    c = value[i];
-                    if (!" \t".Contains(c))
-                        return false;
-                }
-            }
-
-            return true;
-        }
-
-        internal static bool IsToken(this string value)
-        {
-            foreach (char c in value)
-                if (c < 0x20 || c >= 0x7f || _tspecials.Contains(c))
-                    return false;
-
-            return true;
-        }
-
-        internal static string Quote(this string value)
-        {
-            return value.IsToken()
-                   ? value
-                   : string.Format("\"{0}\"", value.Replace("\"", "\\\""));
-        }
-
-        internal static Task<byte[]> ReadBytesAsync(this Stream stream, int length)
-            => stream.ReadBytesAsync(new byte[length], 0, length);
-
-        internal static async Task<byte[]> ReadBytesAsync(this Stream stream, long length, int bufferLength)
-        {
-            using (var result = new MemoryStream())
-            {
-                var count = length / bufferLength;
-                var rem = (int)(length % bufferLength);
-
-                var buffer = new byte[bufferLength];
-                var end = false;
-                for (long i = 0; i < count; i++)
-                {
-                    if (!await stream.ReadBytesAsync(buffer, 0, bufferLength, result).ConfigureAwait(false))
-                    {
-                        end = true;
-                        break;
-                    }
-                }
-
-                if (!end && rem > 0)
-                {
-                    await stream.ReadBytesAsync(new byte[rem], 0, rem, result).ConfigureAwait(false);
-                }
-
-                return result.ToArray();
-            }
-        }
-
-        internal static string RemovePrefix(this string value, params string[] prefixes)
-        {
-            var i = 0;
-            foreach (var prefix in prefixes)
-            {
-                if (value.StartsWith(prefix))
-                {
-                    i = prefix.Length;
-                    break;
-                }
-            }
-
-            return i > 0
-                   ? value.Substring(i)
-                   : value;
-        }
-
-        internal static T[] Reverse<T>(this T[] array)
-        {
-            var len = array.Length;
-            T[] reverse = new T[len];
-
-            var end = len - 1;
-            for (var i = 0; i <= end; i++)
-                reverse[i] = array[end - i];
-
-            return reverse;
-        }
-
-        internal static IEnumerable<string> SplitHeaderValue(
-          this string value, params char[] separator)
-        {
-            var len = value.Length;
-            var separators = new string(separator);
-
-            var buffer = new StringBuilder(32);
-            var quoted = false;
-            var escaped = false;
-
-            char c;
-            for (var i = 0; i < len; i++)
-            {
-                c = value[i];
-                if (c == '"')
-                {
-                    if (escaped)
-                        escaped = !escaped;
-                    else
-                        quoted = !quoted;
-                }
-                else if (c == '\\')
-                {
-                    if (i < len - 1 && value[i + 1] == '"')
-                        escaped = true;
-                }
-                else if (separators.Contains(c))
-                {
-                    if (!quoted)
-                    {
-                        yield return buffer.ToString();
-                        buffer.Length = 0;
-
-                        continue;
-                    }
-                }
-                else
-                {
-                }
-
-                buffer.Append(c);
-            }
-
-            if (buffer.Length > 0)
-                yield return buffer.ToString();
-        }
-
-        internal static byte[] ToByteArray(this Stream stream)
-        {
-            using (var output = new MemoryStream())
-            {
-                stream.Position = 0;
-                stream.CopyTo(output);
-
-                return output.ToArray();
-            }
-        }
-
-        internal static byte[] ToByteArrayInternally(this ushort value, ByteOrder order)
-        {
-            var bytes = BitConverter.GetBytes(value);
-            if (!order.IsHostOrder())
-                Array.Reverse(bytes);
-
-            return bytes;
-        }
-
-        internal static byte[] ToByteArrayInternally(this ulong value, ByteOrder order)
-        {
-            var bytes = BitConverter.GetBytes(value);
-            if (!order.IsHostOrder())
-                Array.Reverse(bytes);
-
-            return bytes;
-        }
-
-        internal static string ToExtensionString(
-          this CompressionMethod method, params string[] parameters)
-        {
-            if (method == CompressionMethod.None)
-                return string.Empty;
-
-            var m = string.Format("permessage-{0}", method.ToString().ToLowerInvariant());
-            if (parameters == null || parameters.Length == 0)
-                return m;
-
-            return string.Format("{0}; {1}", m, parameters.ToString("; "));
-        }
-
-        internal static ushort ToUInt16(this byte[] src, ByteOrder srcOrder)
-        {
-            src.ToHostOrder(srcOrder);
-            return BitConverter.ToUInt16(src, 0);
-        }
-
-        internal static ulong ToUInt64(this byte[] src, ByteOrder srcOrder)
-        {
-            src.ToHostOrder(srcOrder);
-            return BitConverter.ToUInt64(src, 0);
-        }
-
-        internal static string TrimEndSlash(this string value)
-        {
-            value = value.TrimEnd('/');
-            return value.Length > 0
-                   ? value
-                   : "/";
-        }
-
-        internal static string Unquote(this string value)
-        {
-            var start = value.IndexOf('\"');
-            var end = value.LastIndexOf('\"');
-            if (start < end)
-                value = value.Substring(start + 1, end - start - 1).Replace("\\\"", "\"");
-
-            return value.Trim();
-        }
-
-        internal static void WriteBytes(this Stream stream, byte[] value)
-        {
-            using (var src = new MemoryStream(value))
-            {
-                src.CopyTo(stream);
-            }
-        }
-
-        #endregion
-
-        #region Public Methods
-
-        /// <summary>
-        /// Determines whether the specified <see cref="string"/> contains any of characters
-        /// in the specified array of <see cref="char"/>.
-        /// </summary>
-        /// <returns>
-        /// <c>true</c> if <paramref name="value"/> contains any of <paramref name="chars"/>;
-        /// otherwise, <c>false</c>.
-        /// </returns>
-        /// <param name="value">
-        /// A <see cref="string"/> to test.
-        /// </param>
-        /// <param name="chars">
-        /// An array of <see cref="char"/> that contains characters to find.
-        /// </param>
-        public static bool Contains(this string value, params char[] chars)
-        {
-            return chars == null || chars.Length == 0
-                   ? true
-                   : value == null || value.Length == 0
-                     ? false
-                     : value.IndexOfAny(chars) != -1;
-        }
-
-        /// <summary>
-        /// Determines whether the specified <see cref="QueryParamCollection"/> contains the entry
-        /// with the specified <paramref name="name"/>.
-        /// </summary>
-        /// <returns>
-        /// <c>true</c> if <paramref name="collection"/> contains the entry
-        /// with <paramref name="name"/>; otherwise, <c>false</c>.
-        /// </returns>
-        /// <param name="collection">
-        /// A <see cref="QueryParamCollection"/> to test.
-        /// </param>
-        /// <param name="name">
-        /// A <see cref="string"/> that represents the key of the entry to find.
-        /// </param>
-        public static bool Contains(this QueryParamCollection collection, string name)
-        {
-            return collection == null || collection.Count == 0
-                   ? false
-                   : collection[name] != null;
-        }
-
-        /// <summary>
-        /// Determines whether the specified <see cref="QueryParamCollection"/> contains the entry
-        /// with the specified both <paramref name="name"/> and <paramref name="value"/>.
-        /// </summary>
-        /// <returns>
-        /// <c>true</c> if <paramref name="collection"/> contains the entry
-        /// with both <paramref name="name"/> and <paramref name="value"/>;
-        /// otherwise, <c>false</c>.
-        /// </returns>
-        /// <param name="collection">
-        /// A <see cref="QueryParamCollection"/> to test.
-        /// </param>
-        /// <param name="name">
-        /// A <see cref="string"/> that represents the key of the entry to find.
-        /// </param>
-        /// <param name="value">
-        /// A <see cref="string"/> that represents the value of the entry to find.
-        /// </param>
-        public static bool Contains(this QueryParamCollection collection, string name, string value)
-        {
-            if (collection == null || collection.Count == 0)
-                return false;
-
-            var values = collection[name];
-            if (values == null)
-                return false;
-
-            foreach (var v in values.Split(','))
-                if (v.Trim().Equals(value, StringComparison.OrdinalIgnoreCase))
-                    return true;
-
-            return false;
-        }
-
-        /// <summary>
-        /// Emits the specified <c>EventHandler&lt;TEventArgs&gt;</c> delegate
-        /// if it isn't <see langword="null"/>.
-        /// </summary>
-        /// <param name="eventHandler">
-        /// An <c>EventHandler&lt;TEventArgs&gt;</c> to emit.
-        /// </param>
-        /// <param name="sender">
-        /// An <see cref="object"/> from which emits this <paramref name="eventHandler"/>.
-        /// </param>
-        /// <param name="e">
-        /// A <c>TEventArgs</c> that represents the event data.
-        /// </param>
-        /// <typeparam name="TEventArgs">
-        /// The type of the event data generated by the event.
-        /// </typeparam>
-        public static void Emit<TEventArgs>(
-          this EventHandler<TEventArgs> eventHandler, object sender, TEventArgs e)
-          where TEventArgs : EventArgs
-        {
-            if (eventHandler != null)
-                eventHandler(sender, e);
-        }
-
-        /// <summary>
-        /// Gets the description of the specified HTTP status <paramref name="code"/>.
-        /// </summary>
-        /// <returns>
-        /// A <see cref="string"/> that represents the description of the HTTP status code.
-        /// </returns>
-        /// <param name="code">
-        /// One of <see cref="HttpStatusCode"/> enum values, indicates the HTTP status codes.
-        /// </param>
-        public static string GetDescription(this HttpStatusCode code)
-        {
-            return ((int)code).GetStatusDescription();
-        }
-
-        /// <summary>
-        /// Gets the description of the specified HTTP status <paramref name="code"/>.
-        /// </summary>
-        /// <returns>
-        /// A <see cref="string"/> that represents the description of the HTTP status code.
-        /// </returns>
-        /// <param name="code">
-        /// An <see cref="int"/> that represents the HTTP status code.
-        /// </param>
-        public static string GetStatusDescription(this int code)
-        {
-            switch (code)
-            {
-                case 100: return "Continue";
-                case 101: return "Switching Protocols";
-                case 102: return "Processing";
-                case 200: return "OK";
-                case 201: return "Created";
-                case 202: return "Accepted";
-                case 203: return "Non-Authoritative Information";
-                case 204: return "No Content";
-                case 205: return "Reset Content";
-                case 206: return "Partial Content";
-                case 207: return "Multi-Status";
-                case 300: return "Multiple Choices";
-                case 301: return "Moved Permanently";
-                case 302: return "Found";
-                case 303: return "See Other";
-                case 304: return "Not Modified";
-                case 305: return "Use Proxy";
-                case 307: return "Temporary Redirect";
-                case 400: return "Bad Request";
-                case 401: return "Unauthorized";
-                case 402: return "Payment Required";
-                case 403: return "Forbidden";
-                case 404: return "Not Found";
-                case 405: return "Method Not Allowed";
-                case 406: return "Not Acceptable";
-                case 407: return "Proxy Authentication Required";
-                case 408: return "Request Timeout";
-                case 409: return "Conflict";
-                case 410: return "Gone";
-                case 411: return "Length Required";
-                case 412: return "Precondition Failed";
-                case 413: return "Request Entity Too Large";
-                case 414: return "Request-Uri Too Long";
-                case 415: return "Unsupported Media Type";
-                case 416: return "Requested Range Not Satisfiable";
-                case 417: return "Expectation Failed";
-                case 422: return "Unprocessable Entity";
-                case 423: return "Locked";
-                case 424: return "Failed Dependency";
-                case 500: return "Internal Server Error";
-                case 501: return "Not Implemented";
-                case 502: return "Bad Gateway";
-                case 503: return "Service Unavailable";
-                case 504: return "Gateway Timeout";
-                case 505: return "Http Version Not Supported";
-                case 507: return "Insufficient Storage";
-            }
-
-            return string.Empty;
-        }
-
-        /// <summary>
-        /// Determines whether the specified <see cref="ByteOrder"/> is host
-        /// (this computer architecture) byte order.
-        /// </summary>
-        /// <returns>
-        /// <c>true</c> if <paramref name="order"/> is host byte order;
-        /// otherwise, <c>false</c>.
-        /// </returns>
-        /// <param name="order">
-        /// One of the <see cref="ByteOrder"/> enum values, to test.
-        /// </param>
-        public static bool IsHostOrder(this ByteOrder order)
-        {
-            // true : !(true ^ true)  or !(false ^ false)
-            // false: !(true ^ false) or !(false ^ true)
-            return !(BitConverter.IsLittleEndian ^ (order == ByteOrder.Little));
-        }
-
-        /// <summary>
-        /// Determines whether the specified <see cref="string"/> is a predefined scheme.
-        /// </summary>
-        /// <returns>
-        /// <c>true</c> if <paramref name="value"/> is a predefined scheme; otherwise, <c>false</c>.
-        /// </returns>
-        /// <param name="value">
-        /// A <see cref="string"/> to test.
-        /// </param>
-        public static bool IsPredefinedScheme(this string value)
-        {
-            if (value == null || value.Length < 2)
-                return false;
-
-            var c = value[0];
-            if (c == 'h')
-                return value == "http" || value == "https";
-
-            if (c == 'w')
-                return value == "ws" || value == "wss";
-
-            if (c == 'f')
-                return value == "file" || value == "ftp";
-
-            if (c == 'n')
-            {
-                c = value[1];
-                return c == 'e'
-                       ? value == "news" || value == "net.pipe" || value == "net.tcp"
-                       : value == "nntp";
-            }
-
-            return (c == 'g' && value == "gopher") || (c == 'm' && value == "mailto");
-        }
-
-        /// <summary>
-        /// Determines whether the specified <see cref="string"/> is a URI string.
-        /// </summary>
-        /// <returns>
-        /// <c>true</c> if <paramref name="value"/> may be a URI string; otherwise, <c>false</c>.
-        /// </returns>
-        /// <param name="value">
-        /// A <see cref="string"/> to test.
-        /// </param>
-        public static bool MaybeUri(this string value)
-        {
-            if (value == null || value.Length == 0)
-                return false;
-
-            var i = value.IndexOf(':');
-            if (i == -1)
-                return false;
-
-            if (i >= 10)
-                return false;
-
-            return value.Substring(0, i).IsPredefinedScheme();
-        }
-
-        /// <summary>
-        /// Retrieves a sub-array from the specified <paramref name="array"/>.
-        /// A sub-array starts at the specified element position.
-        /// </summary>
-        /// <returns>
-        /// An array of T that receives a sub-array, or an empty array of T if any problems
-        /// with the parameters.
-        /// </returns>
-        /// <param name="array">
-        /// An array of T that contains the data to retrieve a sub-array.
-        /// </param>
-        /// <param name="startIndex">
-        /// An <see cref="int"/> that contains the zero-based starting position of a sub-array
-        /// in <paramref name="array"/>.
-        /// </param>
-        /// <param name="length">
-        /// An <see cref="int"/> that contains the number of elements to retrieve a sub-array.
-        /// </param>
-        /// <typeparam name="T">
-        /// The type of elements in the <paramref name="array"/>.
-        /// </typeparam>
-        public static T[] SubArray<T>(this T[] array, int startIndex, int length)
-        {
-            if (array == null || array.Length == 0)
-                return new T[0];
-
-            if (startIndex < 0 || length <= 0)
-                return new T[0];
-
-            if (startIndex + length > array.Length)
-                return new T[0];
-
-            if (startIndex == 0 && array.Length == length)
-                return array;
-
-            T[] subArray = new T[length];
-            Array.Copy(array, startIndex, subArray, 0, length);
-
-            return subArray;
-        }
-
-        /// <summary>
-        /// Converts the order of the specified array of <see cref="byte"/> to the host byte order.
-        /// </summary>
-        /// <returns>
-        /// An array of <see cref="byte"/> converted from <paramref name="src"/>.
-        /// </returns>
-        /// <param name="src">
-        /// An array of <see cref="byte"/> to convert.
-        /// </param>
-        /// <param name="srcOrder">
-        /// One of the <see cref="ByteOrder"/> enum values, indicates the byte order of
-        /// <paramref name="src"/>.
-        /// </param>
-        /// <exception cref="ArgumentNullException">
-        /// <paramref name="src"/> is <see langword="null"/>.
-        /// </exception>
-        public static void ToHostOrder(this byte[] src, ByteOrder srcOrder)
-        {
-            if (src == null)
-            {
-                throw new ArgumentNullException(nameof(src));
-            }
-
-            if (src.Length > 1 && !srcOrder.IsHostOrder())
-            {
-                Array.Reverse(src);
-            }
-        }
-
-        /// <summary>
-        /// Converts the specified <paramref name="array"/> to a <see cref="string"/> that
-        /// concatenates the each element of <paramref name="array"/> across the specified
-        /// <paramref name="separator"/>.
-        /// </summary>
-        /// <returns>
-        /// A <see cref="string"/> converted from <paramref name="array"/>,
-        /// or <see cref="String.Empty"/> if <paramref name="array"/> is empty.
-        /// </returns>
-        /// <param name="array">
-        /// An array of T to convert.
-        /// </param>
-        /// <param name="separator">
-        /// A <see cref="string"/> that represents the separator string.
-        /// </param>
-        /// <typeparam name="T">
-        /// The type of elements in <paramref name="array"/>.
-        /// </typeparam>
-        /// <exception cref="ArgumentNullException">
-        /// <paramref name="array"/> is <see langword="null"/>.
-        /// </exception>
-        public static string ToString<T>(this T[] array, string separator)
-        {
-            if (array == null)
-                throw new ArgumentNullException(nameof(array));
-
-            var len = array.Length;
-            if (len == 0)
-                return string.Empty;
-
-            if (separator == null)
-                separator = string.Empty;
-
-            var buff = new StringBuilder(64);
-            (len - 1).Times(i => buff.AppendFormat("{0}{1}", array[i].ToString(), separator));
-
-            buff.Append(array[len - 1].ToString());
-            return buff.ToString();
-        }
-
-        /// <summary>
-        /// Executes the specified <c>Action&lt;int&gt;</c> delegate <paramref name="n"/> times.
-        /// </summary>
-        /// <param name="n">
-        /// An <see cref="int"/> is the number of times to execute.
-        /// </param>
-        /// <param name="action">
-        /// An <c>Action&lt;int&gt;</c> delegate that references the method(s) to execute.
-        /// An <see cref="int"/> parameter to pass to the method(s) is the zero-based count of
-        /// iteration.
-        /// </param>
-        public static void Times(this int n, Action<int> action)
-        {
-            if (n > 0 && action != null)
-                for (int i = 0; i < n; i++)
-                    action(i);
-        }
-
-        /// <summary>
-        /// Converts the specified <see cref="string"/> to a <see cref="Uri"/>.
-        /// </summary>
-        /// <returns>
-        /// A <see cref="Uri"/> converted from <paramref name="uriString"/>, or <see langword="null"/>
-        /// if <paramref name="uriString"/> isn't successfully converted.
-        /// </returns>
-        /// <param name="uriString">
-        /// A <see cref="string"/> to convert.
-        /// </param>
-        public static Uri ToUri(this string uriString)
-        {
-            return Uri.TryCreate(
-                     uriString, uriString.MaybeUri() ? UriKind.Absolute : UriKind.Relative, out var res)
-                   ? res
-                   : null;
-        }
-
-        /// <summary>
-        /// URL-decodes the specified <see cref="string"/>.
-        /// </summary>
-        /// <returns>
-        /// A <see cref="string"/> that receives the decoded string, or the <paramref name="value"/>
-        /// if it's <see langword="null"/> or empty.
-        /// </returns>
-        /// <param name="value">
-        /// A <see cref="string"/> to decode.
-        /// </param>
-        public static string UrlDecode(this string value)
-        {
-            return value == null || value.Length == 0
-                   ? value
-                   : WebUtility.UrlDecode(value);
-        }
-
-        #endregion
-    }
-}

+ 0 - 8
SocketHttpListener/Fin.cs

@@ -1,8 +0,0 @@
-namespace SocketHttpListener
-{
-    internal enum Fin : byte
-    {
-        More = 0x0,
-        Final = 0x1
-    }
-}

+ 0 - 70
SocketHttpListener/HttpBase.cs

@@ -1,70 +0,0 @@
-using System;
-using System.Text;
-using MediaBrowser.Model.Services;
-
-namespace SocketHttpListener
-{
-    internal abstract class HttpBase
-    {
-        #region Private Fields
-
-        private QueryParamCollection _headers;
-        private Version _version;
-
-        #endregion
-
-        #region Protected Fields
-
-        protected const string CrLf = "\r\n";
-
-        #endregion
-
-        #region Protected Constructors
-
-        protected HttpBase(Version version, QueryParamCollection headers)
-        {
-            _version = version;
-            _headers = headers;
-        }
-
-        #endregion
-
-        #region Public Properties
-
-        public QueryParamCollection Headers => _headers;
-
-        public Version ProtocolVersion => _version;
-
-        #endregion
-
-        #region Private Methods
-
-        private static Encoding getEncoding(string contentType)
-        {
-            if (contentType == null || contentType.Length == 0)
-                return Encoding.UTF8;
-
-            var i = contentType.IndexOf("charset=", StringComparison.Ordinal);
-            if (i == -1)
-                return Encoding.UTF8;
-
-            var charset = contentType.Substring(i + 8);
-            i = charset.IndexOf(';');
-            if (i != -1)
-                charset = charset.Substring(0, i).TrimEnd();
-
-            return Encoding.GetEncoding(charset.Trim('"'));
-        }
-
-        #endregion
-
-        #region Public Methods
-
-        public byte[] ToByteArray()
-        {
-            return Encoding.UTF8.GetBytes(ToString());
-        }
-
-        #endregion
-    }
-}

+ 0 - 122
SocketHttpListener/HttpResponse.cs

@@ -1,122 +0,0 @@
-using System;
-using System.Linq;
-using System.Net;
-using System.Text;
-using MediaBrowser.Model.Services;
-using SocketHttpListener.Net;
-
-namespace SocketHttpListener
-{
-    // TODO what is the point of this class?
-    internal class HttpResponse : HttpBase
-    {
-        #region Private Fields
-
-        private string _code;
-        private string _reason;
-
-        #endregion
-
-        #region Private Constructors
-
-        private HttpResponse(string code, string reason, Version version, QueryParamCollection headers)
-            : base(version, headers)
-        {
-            _code = code;
-            _reason = reason;
-        }
-
-        #endregion
-
-        #region Internal Constructors
-
-        internal HttpResponse(HttpStatusCode code)
-            : this(code, code.GetDescription())
-        {
-        }
-
-        internal HttpResponse(HttpStatusCode code, string reason)
-            : this(((int)code).ToString(), reason, HttpVersion.Version11, new QueryParamCollection())
-        {
-            Headers["Server"] = "websocket-sharp/1.0";
-        }
-
-        #endregion
-
-        #region Public Properties
-
-        public CookieCollection Cookies => GetCookies(Headers, true);
-
-        private static CookieCollection GetCookies(QueryParamCollection headers, bool response)
-        {
-            var name = response ? "Set-Cookie" : "Cookie";
-            return headers == null || !headers.Contains(name)
-                   ? new CookieCollection()
-                   : CookieHelper.Parse(headers[name], response);
-        }
-
-        public bool IsProxyAuthenticationRequired => _code == "407";
-
-        public bool IsUnauthorized => _code == "401";
-
-        public bool IsWebSocketResponse
-        {
-            get
-            {
-                var headers = Headers;
-                return ProtocolVersion > HttpVersion.Version10 &&
-                       _code == "101" &&
-                       headers.Contains("Upgrade", "websocket") &&
-                       headers.Contains("Connection", "Upgrade");
-            }
-        }
-
-        public string Reason => _reason;
-
-        public string StatusCode => _code;
-
-        #endregion
-
-        #region Internal Methods
-
-        internal static HttpResponse CreateCloseResponse(HttpStatusCode code)
-        {
-            var res = new HttpResponse(code);
-            res.Headers["Connection"] = "close";
-
-            return res;
-        }
-
-        #endregion
-
-        #region Public Methods
-
-        public void SetCookies(CookieCollection cookies)
-        {
-            if (cookies == null || cookies.Count == 0)
-                return;
-
-            var headers = Headers;
-            var sorted = cookies.OfType<Cookie>().OrderBy(i => i.Name).ToList();
-
-            foreach (var cookie in sorted)
-                headers.Add("Set-Cookie", cookie.ToString());
-        }
-
-        public override string ToString()
-        {
-            var output = new StringBuilder(64);
-            output.AppendFormat("HTTP/{0} {1} {2}{3}", ProtocolVersion, _code, _reason, CrLf);
-
-            var headers = Headers;
-            foreach (var key in headers.Keys)
-                output.AppendFormat("{0}: {1}{2}", key, headers[key], CrLf);
-
-            output.Append(CrLf);
-
-            return output.ToString();
-        }
-
-        #endregion
-    }
-}

+ 0 - 8
SocketHttpListener/Mask.cs

@@ -1,8 +0,0 @@
-namespace SocketHttpListener
-{
-    internal enum Mask : byte
-    {
-        Unmask = 0x0,
-        Mask = 0x1
-    }
-}

+ 0 - 84
SocketHttpListener/MessageEventArgs.cs

@@ -1,84 +0,0 @@
-using System;
-using System.Text;
-
-namespace SocketHttpListener
-{
-    /// <summary>
-    /// Contains the event data associated with a <see cref="WebSocket.OnMessage"/> event.
-    /// </summary>
-    /// <remarks>
-    /// A <see cref="WebSocket.OnMessage"/> event occurs when the <see cref="WebSocket"/> receives
-    /// a text or binary data frame.
-    /// If you want to get the received data, you access the <see cref="Data"/> or
-    /// <see cref="RawData"/> property.
-    /// </remarks>
-    public class MessageEventArgs : EventArgs
-    {
-        #region Private Fields
-
-        private string _data;
-        private Opcode _opcode;
-        private byte[] _rawData;
-
-        #endregion
-
-        #region Internal Constructors
-
-        internal MessageEventArgs(Opcode opcode, byte[] data)
-        {
-            _opcode = opcode;
-            _rawData = data;
-            _data = convertToString(opcode, data);
-        }
-
-        internal MessageEventArgs(Opcode opcode, PayloadData payload)
-        {
-            _opcode = opcode;
-            _rawData = payload.ApplicationData;
-            _data = convertToString(opcode, _rawData);
-        }
-
-        #endregion
-
-        #region Public Properties
-
-        /// <summary>
-        /// Gets the received data as a <see cref="string"/>.
-        /// </summary>
-        /// <value>
-        /// A <see cref="string"/> that contains the received data.
-        /// </value>
-        public string Data => _data;
-
-        /// <summary>
-        /// Gets the received data as an array of <see cref="byte"/>.
-        /// </summary>
-        /// <value>
-        /// An array of <see cref="byte"/> that contains the received data.
-        /// </value>
-        public byte[] RawData => _rawData;
-
-        /// <summary>
-        /// Gets the type of the received data.
-        /// </summary>
-        /// <value>
-        /// One of the <see cref="Opcode"/> values, indicates the type of the received data.
-        /// </value>
-        public Opcode Type => _opcode;
-
-        #endregion
-
-        #region Private Methods
-
-        private static string convertToString(Opcode opcode, byte[] data)
-        {
-            return data.Length == 0
-                   ? string.Empty
-                   : opcode == Opcode.Text
-                     ? Encoding.UTF8.GetString(data, 0, data.Length)
-                     : opcode.ToString();
-        }
-
-        #endregion
-    }
-}

+ 0 - 141
SocketHttpListener/Net/CookieHelper.cs

@@ -1,141 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Net;
-using System.Text;
-
-namespace SocketHttpListener.Net
-{
-    public static class CookieHelper
-    {
-        internal static CookieCollection Parse(string value, bool response)
-        {
-            return response
-                ? parseResponse(value)
-                : null;
-        }
-
-        private static string[] splitCookieHeaderValue(string value)
-        {
-            return new List<string>(value.SplitHeaderValue(',', ';')).ToArray();
-        }
-
-        private static CookieCollection parseResponse(string value)
-        {
-            var cookies = new CookieCollection();
-
-            Cookie cookie = null;
-            var pairs = splitCookieHeaderValue(value);
-            for (int i = 0; i < pairs.Length; i++)
-            {
-                var pair = pairs[i].Trim();
-                if (pair.Length == 0)
-                    continue;
-
-                if (pair.StartsWith("version", StringComparison.OrdinalIgnoreCase))
-                {
-                    if (cookie != null)
-                        cookie.Version = int.Parse(pair.GetValueInternal("=").Trim('"'));
-                }
-                else if (pair.StartsWith("expires", StringComparison.OrdinalIgnoreCase))
-                {
-                    var buffer = new StringBuilder(pair.GetValueInternal("="), 32);
-                    if (i < pairs.Length - 1)
-                        buffer.AppendFormat(", {0}", pairs[++i].Trim());
-
-                    if (!DateTime.TryParseExact(
-                      buffer.ToString(),
-                      new[] { "ddd, dd'-'MMM'-'yyyy HH':'mm':'ss 'GMT'", "r" },
-                      new CultureInfo("en-US"),
-                      DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal,
-                      out var expires))
-                        expires = DateTime.Now;
-
-                    if (cookie != null && cookie.Expires == DateTime.MinValue)
-                        cookie.Expires = expires.ToLocalTime();
-                }
-                else if (pair.StartsWith("max-age", StringComparison.OrdinalIgnoreCase))
-                {
-                    var max = int.Parse(pair.GetValueInternal("=").Trim('"'));
-                    var expires = DateTime.Now.AddSeconds((double)max);
-                    if (cookie != null)
-                        cookie.Expires = expires;
-                }
-                else if (pair.StartsWith("path", StringComparison.OrdinalIgnoreCase))
-                {
-                    if (cookie != null)
-                        cookie.Path = pair.GetValueInternal("=");
-                }
-                else if (pair.StartsWith("domain", StringComparison.OrdinalIgnoreCase))
-                {
-                    if (cookie != null)
-                        cookie.Domain = pair.GetValueInternal("=");
-                }
-                else if (pair.StartsWith("port", StringComparison.OrdinalIgnoreCase))
-                {
-                    var port = pair.Equals("port", StringComparison.OrdinalIgnoreCase)
-                               ? "\"\""
-                               : pair.GetValueInternal("=");
-
-                    if (cookie != null)
-                        cookie.Port = port;
-                }
-                else if (pair.StartsWith("comment", StringComparison.OrdinalIgnoreCase))
-                {
-                    if (cookie != null)
-                        cookie.Comment = pair.GetValueInternal("=").UrlDecode();
-                }
-                else if (pair.StartsWith("commenturl", StringComparison.OrdinalIgnoreCase))
-                {
-                    if (cookie != null)
-                        cookie.CommentUri = pair.GetValueInternal("=").Trim('"').ToUri();
-                }
-                else if (pair.StartsWith("discard", StringComparison.OrdinalIgnoreCase))
-                {
-                    if (cookie != null)
-                        cookie.Discard = true;
-                }
-                else if (pair.StartsWith("secure", StringComparison.OrdinalIgnoreCase))
-                {
-                    if (cookie != null)
-                        cookie.Secure = true;
-                }
-                else if (pair.StartsWith("httponly", StringComparison.OrdinalIgnoreCase))
-                {
-                    if (cookie != null)
-                        cookie.HttpOnly = true;
-                }
-                else
-                {
-                    if (cookie != null)
-                        cookies.Add(cookie);
-
-                    string name;
-                    string val = string.Empty;
-
-                    var pos = pair.IndexOf('=');
-                    if (pos == -1)
-                    {
-                        name = pair;
-                    }
-                    else if (pos == pair.Length - 1)
-                    {
-                        name = pair.Substring(0, pos).TrimEnd(' ');
-                    }
-                    else
-                    {
-                        name = pair.Substring(0, pos).TrimEnd(' ');
-                        val = pair.Substring(pos + 1).TrimStart(' ');
-                    }
-
-                    cookie = new Cookie(name, val);
-                }
-            }
-
-            if (cookie != null)
-                cookies.Add(cookie);
-
-            return cookies;
-        }
-    }
-}

+ 0 - 43
SocketHttpListener/Opcode.cs

@@ -1,43 +0,0 @@
-namespace SocketHttpListener
-{
-    /// <summary>
-    /// Contains the values of the opcode that indicates the type of a WebSocket frame.
-    /// </summary>
-    /// <remarks>
-    /// The values of the opcode are defined in
-    /// <see href="http://tools.ietf.org/html/rfc6455#section-5.2">Section 5.2</see> of RFC 6455.
-    /// </remarks>
-    public enum Opcode : byte
-    {
-        /// <summary>
-        /// Equivalent to numeric value 0.
-        /// Indicates a continuation frame.
-        /// </summary>
-        Cont = 0x0,
-        /// <summary>
-        /// Equivalent to numeric value 1.
-        /// Indicates a text frame.
-        /// </summary>
-        Text = 0x1,
-        /// <summary>
-        /// Equivalent to numeric value 2.
-        /// Indicates a binary frame.
-        /// </summary>
-        Binary = 0x2,
-        /// <summary>
-        /// Equivalent to numeric value 8.
-        /// Indicates a connection close frame.
-        /// </summary>
-        Close = 0x8,
-        /// <summary>
-        /// Equivalent to numeric value 9.
-        /// Indicates a ping frame.
-        /// </summary>
-        Ping = 0x9,
-        /// <summary>
-        /// Equivalent to numeric value 10.
-        /// Indicates a pong frame.
-        /// </summary>
-        Pong = 0xa
-    }
-}

+ 0 - 130
SocketHttpListener/PayloadData.cs

@@ -1,130 +0,0 @@
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Text;
-
-namespace SocketHttpListener
-{
-    internal class PayloadData : IEnumerable<byte>
-    {
-        #region Private Fields
-
-        private byte[] _applicationData;
-        private byte[] _extensionData;
-        private bool _masked;
-
-        #endregion
-
-        #region Public Const Fields
-
-        public const ulong MaxLength = long.MaxValue;
-
-        #endregion
-
-        #region Public Constructors
-
-        public PayloadData()
-          : this(new byte[0], new byte[0], false)
-        {
-        }
-
-        public PayloadData(byte[] applicationData)
-          : this(new byte[0], applicationData, false)
-        {
-        }
-
-        public PayloadData(string applicationData)
-          : this(new byte[0], Encoding.UTF8.GetBytes(applicationData), false)
-        {
-        }
-
-        public PayloadData(byte[] applicationData, bool masked)
-          : this(new byte[0], applicationData, masked)
-        {
-        }
-
-        public PayloadData(byte[] extensionData, byte[] applicationData, bool masked)
-        {
-            _extensionData = extensionData;
-            _applicationData = applicationData;
-            _masked = masked;
-        }
-
-        #endregion
-
-        #region Internal Properties
-
-        internal bool ContainsReservedCloseStatusCode =>
-            _applicationData.Length > 1 &&
-            _applicationData.SubArray(0, 2).ToUInt16(ByteOrder.Big).IsReserved();
-
-        #endregion
-
-        #region Public Properties
-
-        public byte[] ApplicationData => _applicationData;
-
-        public byte[] ExtensionData => _extensionData;
-
-        public bool IsMasked => _masked;
-
-        public ulong Length => (ulong)(_extensionData.Length + _applicationData.Length);
-
-        #endregion
-
-        #region Private Methods
-
-        private static void mask(byte[] src, byte[] key)
-        {
-            for (long i = 0; i < src.Length; i++)
-                src[i] = (byte)(src[i] ^ key[i % 4]);
-        }
-
-        #endregion
-
-        #region Public Methods
-
-        public IEnumerator<byte> GetEnumerator()
-        {
-            foreach (byte b in _extensionData)
-                yield return b;
-
-            foreach (byte b in _applicationData)
-                yield return b;
-        }
-
-        public void Mask(byte[] maskingKey)
-        {
-            if (_extensionData.Length > 0)
-                mask(_extensionData, maskingKey);
-
-            if (_applicationData.Length > 0)
-                mask(_applicationData, maskingKey);
-
-            _masked = !_masked;
-        }
-
-        public byte[] ToByteArray()
-        {
-            return _extensionData.Length > 0
-                   ? new List<byte>(this).ToArray()
-                   : _applicationData;
-        }
-
-        public override string ToString()
-        {
-            return BitConverter.ToString(ToByteArray());
-        }
-
-        #endregion
-
-        #region Explicitly Implemented Interface Members
-
-        IEnumerator IEnumerable.GetEnumerator()
-        {
-            return GetEnumerator();
-        }
-
-        #endregion
-    }
-}

+ 0 - 21
SocketHttpListener/Properties/AssemblyInfo.cs

@@ -1,21 +0,0 @@
-using System.Reflection;
-using System.Resources;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("SocketHttpListener")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("Jellyfin Project")]
-[assembly: AssemblyProduct("Jellyfin: The Free Software Media System")]
-[assembly: AssemblyCopyright("Copyright ©  2019 Jellyfin Contributors. Code released under the GNU General Public License Version 2")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-[assembly: NeutralResourcesLanguage("en")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components.  If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]

+ 0 - 8
SocketHttpListener/Rsv.cs

@@ -1,8 +0,0 @@
-namespace SocketHttpListener
-{
-    internal enum Rsv : byte
-    {
-        Off = 0x0,
-        On = 0x1
-    }
-}

+ 0 - 18
SocketHttpListener/SocketHttpListener.csproj

@@ -1,18 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk">
-
-  <ItemGroup>
-    <ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj" />
-    <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj" />
-  </ItemGroup>
-
-  <ItemGroup>
-    <Compile Include="..\SharedVersion.cs" />
-  </ItemGroup>
-
-  <PropertyGroup>
-    <TargetFramework>netstandard2.0</TargetFramework>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
-  </PropertyGroup>
-
-</Project>

+ 0 - 74
SocketHttpListener/SocketStream.cs

@@ -1,74 +0,0 @@
-using System;
-using System.IO;
-using System.Net.Sockets;
-
-namespace SocketHttpListener
-{
-    public class SocketStream : Stream
-    {
-        private readonly Socket _socket;
-
-        public SocketStream(Socket socket, bool ownsSocket)
-        {
-            _socket = socket;
-        }
-
-        public override void Flush()
-        {
-        }
-
-        public override bool CanRead => true;
-
-        public override bool CanSeek => false;
-
-        public override bool CanWrite => true;
-
-        public override long Length => throw new NotImplementedException();
-
-        public override long Position
-        {
-            get => throw new NotImplementedException();
-            set => throw new NotImplementedException();
-        }
-
-        public override void Write(byte[] buffer, int offset, int count)
-        {
-            _socket.Send(buffer, offset, count, SocketFlags.None);
-        }
-
-        public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
-        {
-            return _socket.BeginSend(buffer, offset, count, SocketFlags.None, callback, state);
-        }
-
-        public override void EndWrite(IAsyncResult asyncResult)
-        {
-            _socket.EndSend(asyncResult);
-        }
-
-        public override void SetLength(long value)
-        {
-            throw new NotImplementedException();
-        }
-
-        public override long Seek(long offset, SeekOrigin origin)
-        {
-            throw new NotImplementedException();
-        }
-
-        public override int Read(byte[] buffer, int offset, int count)
-        {
-            return _socket.Receive(buffer, offset, count, SocketFlags.None);
-        }
-
-        public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
-        {
-            return _socket.BeginReceive(buffer, offset, count, SocketFlags.None, callback, state);
-        }
-
-        public override int EndRead(IAsyncResult asyncResult)
-        {
-            return _socket.EndReceive(asyncResult);
-        }
-    }
-}

+ 0 - 777
SocketHttpListener/WebSocket.cs

@@ -1,777 +0,0 @@
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.IO;
-using System.Net;
-using System.Net.Sockets;
-using System.Net.WebSockets;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using WebSocketState = System.Net.WebSockets.WebSocketState;
-
-namespace SocketHttpListener
-{
-    /// <summary>
-    /// Implements the WebSocket interface.
-    /// </summary>
-    /// <remarks>
-    /// The WebSocket class provides a set of methods and properties for two-way communication using
-    /// the WebSocket protocol (<see href="http://tools.ietf.org/html/rfc6455">RFC 6455</see>).
-    /// </remarks>
-    public class WebSocket : IDisposable
-    {
-        #region Private Fields
-
-        private Action _closeContext;
-        private CompressionMethod _compression;
-        private WebSocketContext _context;
-        private CookieCollection _cookies;
-        private AutoResetEvent _exitReceiving;
-        private object _forConn;
-        private readonly SemaphoreSlim _forEvent = new SemaphoreSlim(1, 1);
-        private object _forMessageEventQueue;
-        private readonly SemaphoreSlim _forSend = new SemaphoreSlim(1, 1);
-        private const string _guid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
-        private Queue<MessageEventArgs> _messageEventQueue;
-        private string _protocol;
-        private volatile WebSocketState _readyState;
-        private AutoResetEvent _receivePong;
-        private bool _secure;
-        private Stream _stream;
-        private const string _version = "13";
-
-        #endregion
-
-        #region Internal Fields
-
-        internal const int FragmentLength = 1016; // Max value is int.MaxValue - 14.
-
-        #endregion
-
-        #region Internal Constructors
-
-        // As server
-        internal WebSocket(string protocol)
-        {
-            _protocol = protocol;
-        }
-
-        public void SetContext(HttpListenerWebSocketContext context, Action closeContextFn, Stream stream)
-        {
-            _context = context;
-
-            _closeContext = closeContextFn;
-            _secure = context.IsSecureConnection;
-            _stream = stream;
-
-            init();
-        }
-
-        // In the .NET Framework, this pulls the value from a P/Invoke.  Here we just hardcode it to a reasonable default.
-        public static TimeSpan DefaultKeepAliveInterval => TimeSpan.FromSeconds(30);
-
-        #endregion
-
-        /// <summary>
-        /// Gets the state of the WebSocket connection.
-        /// </summary>
-        /// <value>
-        /// One of the <see cref="WebSocketState"/> enum values, indicates the state of the WebSocket
-        /// connection. The default value is <see cref="WebSocketState.Connecting"/>.
-        /// </value>
-        public WebSocketState ReadyState => _readyState;
-
-        #region Public Events
-
-        /// <summary>
-        /// Occurs when the WebSocket connection has been closed.
-        /// </summary>
-        public event EventHandler<CloseEventArgs> OnClose;
-
-        /// <summary>
-        /// Occurs when the <see cref="WebSocket"/> gets an error.
-        /// </summary>
-        public event EventHandler<ErrorEventArgs> OnError;
-
-        /// <summary>
-        /// Occurs when the <see cref="WebSocket"/> receives a message.
-        /// </summary>
-        public event EventHandler<MessageEventArgs> OnMessage;
-
-        /// <summary>
-        /// Occurs when the WebSocket connection has been established.
-        /// </summary>
-        public event EventHandler OnOpen;
-
-        #endregion
-
-        #region Private Methods
-
-        private async Task CloseAsync(CloseStatusCode code, string reason, bool wait)
-        {
-            await CloseAsync(new PayloadData(
-                await ((ushort)code).AppendAsync(reason).ConfigureAwait(false)),
-                !code.IsReserved(),
-                wait).ConfigureAwait(false);
-        }
-
-        private async Task CloseAsync(PayloadData payload, bool send, bool wait)
-        {
-            lock (_forConn)
-            {
-                if (_readyState == WebSocketState.CloseSent || _readyState == WebSocketState.Closed)
-                {
-                    return;
-                }
-
-                _readyState = WebSocketState.CloseSent;
-            }
-
-            var e = new CloseEventArgs(payload)
-            {
-                WasClean = await CloseHandshakeAsync(
-                  send ? WebSocketFrame.CreateCloseFrame(Mask.Unmask, payload).ToByteArray() : null,
-                  wait ? 1000 : 0).ConfigureAwait(false)
-            };
-
-            _readyState = WebSocketState.Closed;
-            try
-            {
-                OnClose.Emit(this, e);
-            }
-            catch (Exception ex)
-            {
-                error("An exception has occurred while OnClose.", ex);
-            }
-        }
-
-        private async Task<bool> CloseHandshakeAsync(byte[] frameAsBytes, int millisecondsTimeout)
-        {
-            var sent = frameAsBytes != null && await WriteBytesAsync(frameAsBytes).ConfigureAwait(false);
-            var received =
-              millisecondsTimeout == 0 ||
-              (sent && _exitReceiving != null && _exitReceiving.WaitOne(millisecondsTimeout));
-
-            closeServerResources();
-
-            if (_receivePong != null)
-            {
-                _receivePong.Dispose();
-                _receivePong = null;
-            }
-
-            if (_exitReceiving != null)
-            {
-                _exitReceiving.Dispose();
-                _exitReceiving = null;
-            }
-
-            var result = sent && received;
-
-            return result;
-        }
-
-        // As server
-        private void closeServerResources()
-        {
-            if (_closeContext == null)
-                return;
-
-            try
-            {
-                _closeContext();
-            }
-            catch (SocketException)
-            {
-                // it could be unable to send the handshake response
-            }
-
-            _closeContext = null;
-            _stream = null;
-            _context = null;
-        }
-
-        private async Task<bool> ConcatenateFragmentsIntoAsync(Stream dest)
-        {
-            while (true)
-            {
-                var frame = await WebSocketFrame.ReadAsync(_stream, true).ConfigureAwait(false);
-                if (frame.IsFinal)
-                {
-                    /* FINAL */
-
-                    // CONT
-                    if (frame.IsContinuation)
-                    {
-                        dest.WriteBytes(frame.PayloadData.ApplicationData);
-                        break;
-                    }
-
-                    // PING
-                    if (frame.IsPing)
-                    {
-                        processPingFrame(frame);
-                        continue;
-                    }
-
-                    // PONG
-                    if (frame.IsPong)
-                    {
-                        processPongFrame(frame);
-                        continue;
-                    }
-
-                    // CLOSE
-                    if (frame.IsClose)
-                        return await ProcessCloseFrameAsync(frame).ConfigureAwait(false);
-                }
-                else
-                {
-                    /* MORE */
-
-                    // CONT
-                    if (frame.IsContinuation)
-                    {
-                        dest.WriteBytes(frame.PayloadData.ApplicationData);
-                        continue;
-                    }
-                }
-
-                // ?
-                return await ProcessUnsupportedFrameAsync(
-                  frame,
-                  CloseStatusCode.IncorrectData,
-                  "An incorrect data has been received while receiving fragmented data.").ConfigureAwait(false);
-            }
-
-            return true;
-        }
-
-        // As server
-        private HttpResponse createHandshakeCloseResponse(HttpStatusCode code)
-        {
-            var res = HttpResponse.CreateCloseResponse(code);
-            res.Headers["Sec-WebSocket-Version"] = _version;
-
-            return res;
-        }
-
-        private MessageEventArgs dequeueFromMessageEventQueue()
-        {
-            lock (_forMessageEventQueue)
-                return _messageEventQueue.Count > 0
-                       ? _messageEventQueue.Dequeue()
-                       : null;
-        }
-
-        private void enqueueToMessageEventQueue(MessageEventArgs e)
-        {
-            lock (_forMessageEventQueue)
-                _messageEventQueue.Enqueue(e);
-        }
-
-        private void error(string message, Exception exception)
-        {
-            try
-            {
-                if (exception != null)
-                {
-                    message += ". Exception.Message: " + exception.Message;
-                }
-                OnError.Emit(this, new ErrorEventArgs(message));
-            }
-            catch (Exception)
-            {
-            }
-        }
-
-        private void error(string message)
-        {
-            try
-            {
-                OnError.Emit(this, new ErrorEventArgs(message));
-            }
-            catch (Exception)
-            {
-            }
-        }
-
-        private void init()
-        {
-            _compression = CompressionMethod.None;
-            _cookies = new CookieCollection();
-            _forConn = new object();
-            _messageEventQueue = new Queue<MessageEventArgs>();
-            _forMessageEventQueue = ((ICollection)_messageEventQueue).SyncRoot;
-            _readyState = WebSocketState.Connecting;
-        }
-
-        private async Task OpenAsync()
-        {
-            try
-            {
-                startReceiving();
-
-            }
-            catch (Exception ex)
-            {
-                await ProcessExceptionAsync(ex, "An exception has occurred while opening.").ConfigureAwait(false);
-            }
-
-            await _forEvent.WaitAsync().ConfigureAwait(false);
-            try
-            {
-                OnOpen?.Invoke(this, EventArgs.Empty);
-            }
-            catch (Exception ex)
-            {
-                await ProcessExceptionAsync(ex, "An exception has occurred while OnOpen.").ConfigureAwait(false);
-            }
-            finally
-            {
-                _forEvent.Release();
-            }
-        }
-
-        private async Task<bool> ProcessCloseFrameAsync(WebSocketFrame frame)
-        {
-            var payload = frame.PayloadData;
-            await CloseAsync(payload, !payload.ContainsReservedCloseStatusCode, false).ConfigureAwait(false);
-
-            return false;
-        }
-
-        private bool processDataFrame(WebSocketFrame frame)
-        {
-            var e = frame.IsCompressed
-                    ? new MessageEventArgs(
-                        frame.Opcode, frame.PayloadData.ApplicationData.Decompress(_compression))
-                    : new MessageEventArgs(frame.Opcode, frame.PayloadData);
-
-            enqueueToMessageEventQueue(e);
-            return true;
-        }
-
-        private async Task ProcessExceptionAsync(Exception exception, string message)
-        {
-            var code = CloseStatusCode.Abnormal;
-            var reason = message;
-            if (exception is WebSocketException)
-            {
-                var wsex = (WebSocketException)exception;
-                code = wsex.Code;
-                reason = wsex.Message;
-            }
-
-            error(message ?? code.GetMessage(), exception);
-            if (_readyState == WebSocketState.Connecting)
-            {
-                await CloseAsync(HttpStatusCode.BadRequest).ConfigureAwait(false);
-            }
-            else
-            {
-                await CloseAsync(code, reason ?? code.GetMessage(), false).ConfigureAwait(false);
-            }
-        }
-
-        private Task<bool> ProcessFragmentedFrameAsync(WebSocketFrame frame)
-        {
-            return frame.IsContinuation // Not first fragment
-                   ? Task.FromResult(true)
-                   : ProcessFragmentsAsync(frame);
-        }
-
-        private async Task<bool> ProcessFragmentsAsync(WebSocketFrame first)
-        {
-            using (var buff = new MemoryStream())
-            {
-                buff.WriteBytes(first.PayloadData.ApplicationData);
-                if (!await ConcatenateFragmentsIntoAsync(buff).ConfigureAwait(false))
-                {
-                    return false;
-                }
-
-                byte[] data;
-                if (_compression != CompressionMethod.None)
-                {
-                    data = buff.DecompressToArray(_compression);
-                }
-                else
-                {
-                    data = buff.ToArray();
-                }
-
-                enqueueToMessageEventQueue(new MessageEventArgs(first.Opcode, data));
-                return true;
-            }
-        }
-
-        private bool processPingFrame(WebSocketFrame frame)
-        {
-            return true;
-        }
-
-        private bool processPongFrame(WebSocketFrame frame)
-        {
-            _receivePong.Set();
-
-            return true;
-        }
-
-        private async Task<bool> ProcessUnsupportedFrameAsync(WebSocketFrame frame, CloseStatusCode code, string reason)
-        {
-            await ProcessExceptionAsync(new WebSocketException(code, reason), null).ConfigureAwait(false);
-
-            return false;
-        }
-
-        private Task<bool> ProcessWebSocketFrameAsync(WebSocketFrame frame)
-        {
-            // TODO: @bond change to if/else chain
-            return frame.IsCompressed && _compression == CompressionMethod.None
-                   ? ProcessUnsupportedFrameAsync(
-                       frame,
-                       CloseStatusCode.IncorrectData,
-                       "A compressed data has been received without available decompression method.")
-                   : frame.IsFragmented
-                     ? ProcessFragmentedFrameAsync(frame)
-                     : frame.IsData
-                       ? Task.FromResult(processDataFrame(frame))
-                       : frame.IsPing
-                         ? Task.FromResult(processPingFrame(frame))
-                         : frame.IsPong
-                           ? Task.FromResult(processPongFrame(frame))
-                           : frame.IsClose
-                             ? ProcessCloseFrameAsync(frame)
-                             : ProcessUnsupportedFrameAsync(frame, CloseStatusCode.PolicyViolation, null);
-        }
-
-        private async Task<bool> SendAsync(Opcode opcode, Stream stream)
-        {
-            await _forSend.WaitAsync().ConfigureAwait(false);
-            try
-            {
-                var src = stream;
-                var compressed = false;
-                var sent = false;
-                try
-                {
-                    if (_compression != CompressionMethod.None)
-                    {
-                        stream = stream.Compress(_compression);
-                        compressed = true;
-                    }
-
-                    sent = await SendAsync(opcode, Mask.Unmask, stream, compressed).ConfigureAwait(false);
-                    if (!sent)
-                        error("Sending a data has been interrupted.");
-                }
-                catch (Exception ex)
-                {
-                    error("An exception has occurred while sending a data.", ex);
-                }
-                finally
-                {
-                    if (compressed)
-                        stream.Dispose();
-
-                    src.Dispose();
-                }
-
-                return sent;
-            }
-            finally
-            {
-                _forSend.Release();
-            }
-        }
-
-        private async Task<bool> SendAsync(Opcode opcode, Mask mask, Stream stream, bool compressed)
-        {
-            var len = stream.Length;
-
-            /* Not fragmented */
-
-            if (len == 0)
-                return await SendAsync(Fin.Final, opcode, mask, new byte[0], compressed).ConfigureAwait(false);
-
-            var quo = len / FragmentLength;
-            var rem = (int)(len % FragmentLength);
-
-            byte[] buff = null;
-            if (quo == 0)
-            {
-                buff = new byte[rem];
-                return await stream.ReadAsync(buff, 0, rem).ConfigureAwait(false) == rem &&
-                       await SendAsync(Fin.Final, opcode, mask, buff, compressed).ConfigureAwait(false);
-            }
-
-            buff = new byte[FragmentLength];
-            if (quo == 1 && rem == 0)
-                return await stream.ReadAsync(buff, 0, FragmentLength).ConfigureAwait(false) == FragmentLength &&
-                       await SendAsync(Fin.Final, opcode, mask, buff, compressed).ConfigureAwait(false);
-
-            /* Send fragmented */
-
-            // Begin
-            if (await stream.ReadAsync(buff, 0, FragmentLength).ConfigureAwait(false) != FragmentLength ||
-                !await SendAsync(Fin.More, opcode, mask, buff, compressed).ConfigureAwait(false))
-                return false;
-
-            var n = rem == 0 ? quo - 2 : quo - 1;
-            for (long i = 0; i < n; i++)
-                if (await stream.ReadAsync(buff, 0, FragmentLength).ConfigureAwait(false) != FragmentLength ||
-                    !await SendAsync(Fin.More, Opcode.Cont, mask, buff, compressed).ConfigureAwait(false))
-                    return false;
-
-            // End
-            if (rem == 0)
-                rem = FragmentLength;
-            else
-                buff = new byte[rem];
-
-            return await stream.ReadAsync(buff, 0, rem).ConfigureAwait(false) == rem &&
-                   await SendAsync(Fin.Final, Opcode.Cont, mask, buff, compressed).ConfigureAwait(false);
-        }
-
-        private Task<bool> SendAsync(Fin fin, Opcode opcode, Mask mask, byte[] data, bool compressed)
-        {
-            lock (_forConn)
-            {
-                if (_readyState != WebSocketState.Open)
-                {
-                    return Task.FromResult(false);
-                }
-
-                return WriteBytesAsync(
-                  WebSocketFrame.CreateWebSocketFrame(fin, opcode, mask, data, compressed).ToByteArray());
-            }
-        }
-
-        // As server
-        private Task<bool> SendHttpResponseAsync(HttpResponse response)
-            => WriteBytesAsync(response.ToByteArray());
-
-        private void startReceiving()
-        {
-            if (_messageEventQueue.Count > 0)
-            {
-                _messageEventQueue.Clear();
-            }
-
-            _exitReceiving = new AutoResetEvent(false);
-            _receivePong = new AutoResetEvent(false);
-
-            Action receive = null;
-            receive = async () => await WebSocketFrame.ReadAsync(
-                _stream,
-                true,
-                async frame =>
-                {
-                    if (await ProcessWebSocketFrameAsync(frame).ConfigureAwait(false) && _readyState != WebSocketState.Closed)
-                    {
-                        receive();
-
-                        if (!frame.IsData)
-                        {
-                            return;
-                        }
-
-                        await _forEvent.WaitAsync().ConfigureAwait(false);
-
-                        try
-                        {
-                            var e = dequeueFromMessageEventQueue();
-                            if (e != null && _readyState == WebSocketState.Open)
-                            {
-                                OnMessage.Emit(this, e);
-                            }
-                        }
-                        catch (Exception ex)
-                        {
-                            await ProcessExceptionAsync(ex, "An exception has occurred while OnMessage.").ConfigureAwait(false);
-                        }
-                        finally
-                        {
-                            _forEvent.Release();
-                        }
-
-                    }
-                    else if (_exitReceiving != null)
-                    {
-                        _exitReceiving.Set();
-                    }
-                },
-                async ex => await ProcessExceptionAsync(ex, "An exception has occurred while receiving a message.")).ConfigureAwait(false);
-
-            receive();
-        }
-
-        private async Task<bool> WriteBytesAsync(byte[] data)
-        {
-            try
-            {
-                await _stream.WriteAsync(data, 0, data.Length).ConfigureAwait(false);
-                return true;
-            }
-            catch (Exception)
-            {
-                return false;
-            }
-        }
-
-        #endregion
-
-        #region Internal Methods
-
-        // As server
-        internal async Task CloseAsync(HttpResponse response)
-        {
-            _readyState = WebSocketState.CloseSent;
-            await SendHttpResponseAsync(response).ConfigureAwait(false);
-
-            closeServerResources();
-
-            _readyState = WebSocketState.Closed;
-        }
-
-        // As server
-        internal Task CloseAsync(HttpStatusCode code)
-            => CloseAsync(createHandshakeCloseResponse(code));
-
-        // As server
-        public async Task ConnectAsServer()
-        {
-            try
-            {
-                _readyState = WebSocketState.Open;
-                await OpenAsync().ConfigureAwait(false);
-            }
-            catch (Exception ex)
-            {
-                await ProcessExceptionAsync(ex, "An exception has occurred while connecting.").ConfigureAwait(false);
-            }
-        }
-
-        #endregion
-
-        #region Public Methods
-
-        /// <summary>
-        /// Closes the WebSocket connection, and releases all associated resources.
-        /// </summary>
-        public Task CloseAsync()
-        {
-            var msg = _readyState.CheckIfClosable();
-            if (msg != null)
-            {
-                error(msg);
-
-                return Task.CompletedTask;
-            }
-
-            var send = _readyState == WebSocketState.Open;
-            return CloseAsync(new PayloadData(), send, send);
-        }
-
-        /// <summary>
-        /// Closes the WebSocket connection with the specified <see cref="CloseStatusCode"/>
-        /// and <see cref="string"/>, and releases all associated resources.
-        /// </summary>
-        /// <remarks>
-        /// This method emits a <see cref="OnError"/> event if the size
-        /// of <paramref name="reason"/> is greater than 123 bytes.
-        /// </remarks>
-        /// <param name="code">
-        /// One of the <see cref="CloseStatusCode"/> enum values, represents the status code
-        /// indicating the reason for the close.
-        /// </param>
-        /// <param name="reason">
-        /// A <see cref="string"/> that represents the reason for the close.
-        /// </param>
-        public async Task CloseAsync(CloseStatusCode code, string reason)
-        {
-            byte[] data = null;
-            var msg = _readyState.CheckIfClosable() ??
-                      (data = await ((ushort)code).AppendAsync(reason).ConfigureAwait(false)).CheckIfValidControlData("reason");
-
-            if (msg != null)
-            {
-                error(msg);
-
-                return;
-            }
-
-            var send = _readyState == WebSocketState.Open && !code.IsReserved();
-            await CloseAsync(new PayloadData(data), send, send).ConfigureAwait(false);
-        }
-
-        /// <summary>
-        /// Sends a binary <paramref name="data"/> asynchronously using the WebSocket connection.
-        /// </summary>
-        /// <remarks>
-        /// This method doesn't wait for the send to be complete.
-        /// </remarks>
-        /// <param name="data">
-        /// An array of <see cref="byte"/> that represents the binary data to send.
-        /// </param>
-        public Task SendAsync(byte[] data)
-        {
-            if (data == null)
-            {
-                throw new ArgumentNullException(nameof(data));
-            }
-
-            var msg = _readyState.CheckIfOpen();
-            if (msg != null)
-            {
-                throw new Exception(msg);
-            }
-
-            return SendAsync(Opcode.Binary, new MemoryStream(data));
-        }
-
-        /// <summary>
-        /// Sends a text <paramref name="data"/> asynchronously using the WebSocket connection.
-        /// </summary>
-        /// <remarks>
-        /// This method doesn't wait for the send to be complete.
-        /// </remarks>
-        /// <param name="data">
-        /// A <see cref="string"/> that represents the text data to send.
-        /// </param>
-        public Task SendAsync(string data)
-        {
-            if (data == null)
-            {
-                throw new ArgumentNullException(nameof(data));
-            }
-
-            var msg = _readyState.CheckIfOpen();
-            if (msg != null)
-            {
-                throw new Exception(msg);
-            }
-
-            return SendAsync(Opcode.Text, new MemoryStream(Encoding.UTF8.GetBytes(data)));
-        }
-
-        #endregion
-
-        #region Explicit Interface Implementation
-
-        /// <summary>
-        /// Closes the WebSocket connection, and releases all associated resources.
-        /// </summary>
-        /// <remarks>
-        /// This method closes the WebSocket connection with <see cref="CloseStatusCode.Away"/>.
-        /// </remarks>
-        void IDisposable.Dispose()
-        {
-            CloseAsync(CloseStatusCode.Away, null).GetAwaiter().GetResult();
-        }
-
-        #endregion
-    }
-}

+ 0 - 61
SocketHttpListener/WebSocketException.cs

@@ -1,61 +0,0 @@
-using System;
-
-namespace SocketHttpListener
-{
-    /// <summary>
-    /// The exception that is thrown when a <see cref="WebSocket"/> gets a fatal error.
-    /// </summary>
-    public class WebSocketException : Exception
-    {
-        #region Internal Constructors
-
-        internal WebSocketException()
-          : this(CloseStatusCode.Abnormal, null, null)
-        {
-        }
-
-        internal WebSocketException(string message)
-          : this(CloseStatusCode.Abnormal, message, null)
-        {
-        }
-
-        internal WebSocketException(CloseStatusCode code)
-          : this(code, null, null)
-        {
-        }
-
-        internal WebSocketException(string message, Exception innerException)
-          : this(CloseStatusCode.Abnormal, message, innerException)
-        {
-        }
-
-        internal WebSocketException(CloseStatusCode code, string message)
-          : this(code, message, null)
-        {
-        }
-
-        internal WebSocketException(CloseStatusCode code, string message, Exception innerException)
-          : base(message ?? code.GetMessage(), innerException)
-        {
-            Code = code;
-        }
-
-        #endregion
-
-        #region Public Properties
-
-        /// <summary>
-        /// Gets the status code indicating the cause for the exception.
-        /// </summary>
-        /// <value>
-        /// One of the <see cref="CloseStatusCode"/> enum values, represents the status code indicating
-        /// the cause for the exception.
-        /// </value>
-        public CloseStatusCode Code
-        {
-            get; private set;
-        }
-
-        #endregion
-    }
-}

+ 0 - 432
SocketHttpListener/WebSocketFrame.cs

@@ -1,432 +0,0 @@
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.IO;
-using System.Threading.Tasks;
-
-namespace SocketHttpListener
-{
-    internal class WebSocketFrame : IEnumerable<byte>
-    {
-        #region Private Fields
-
-        private byte[] _extPayloadLength;
-        private Fin _fin;
-        private Mask _mask;
-        private byte[] _maskingKey;
-        private Opcode _opcode;
-        private PayloadData _payloadData;
-        private byte _payloadLength;
-        private Rsv _rsv1;
-        private Rsv _rsv2;
-        private Rsv _rsv3;
-
-        #endregion
-
-        #region Internal Fields
-
-        internal static readonly byte[] EmptyUnmaskPingData;
-
-        #endregion
-
-        #region Static Constructor
-
-        static WebSocketFrame()
-        {
-            EmptyUnmaskPingData = CreatePingFrame(Mask.Unmask).ToByteArray();
-        }
-
-        #endregion
-
-        #region Private Constructors
-
-        private WebSocketFrame()
-        {
-        }
-
-        #endregion
-
-        #region Internal Constructors
-
-        internal WebSocketFrame(Opcode opcode, PayloadData payload)
-            : this(Fin.Final, opcode, Mask.Mask, payload, false)
-        {
-        }
-
-        internal WebSocketFrame(Opcode opcode, Mask mask, PayloadData payload)
-            : this(Fin.Final, opcode, mask, payload, false)
-        {
-        }
-
-        internal WebSocketFrame(Fin fin, Opcode opcode, Mask mask, PayloadData payload)
-            : this(fin, opcode, mask, payload, false)
-        {
-        }
-
-        internal WebSocketFrame(
-          Fin fin, Opcode opcode, Mask mask, PayloadData payload, bool compressed)
-        {
-            _fin = fin;
-            _rsv1 = isData(opcode) && compressed ? Rsv.On : Rsv.Off;
-            _rsv2 = Rsv.Off;
-            _rsv3 = Rsv.Off;
-            _opcode = opcode;
-            _mask = mask;
-
-            var len = payload.Length;
-            if (len < 126)
-            {
-                _payloadLength = (byte)len;
-                _extPayloadLength = new byte[0];
-            }
-            else if (len < 0x010000)
-            {
-                _payloadLength = (byte)126;
-                _extPayloadLength = ((ushort)len).ToByteArrayInternally(ByteOrder.Big);
-            }
-            else
-            {
-                _payloadLength = (byte)127;
-                _extPayloadLength = len.ToByteArrayInternally(ByteOrder.Big);
-            }
-
-            if (mask == Mask.Mask)
-            {
-                _maskingKey = createMaskingKey();
-                payload.Mask(_maskingKey);
-            }
-            else
-            {
-                _maskingKey = new byte[0];
-            }
-
-            _payloadData = payload;
-        }
-
-        #endregion
-
-        #region Public Properties
-
-        public byte[] ExtendedPayloadLength => _extPayloadLength;
-
-        public Fin Fin => _fin;
-
-        public bool IsBinary => _opcode == Opcode.Binary;
-
-        public bool IsClose => _opcode == Opcode.Close;
-
-        public bool IsCompressed => _rsv1 == Rsv.On;
-
-        public bool IsContinuation => _opcode == Opcode.Cont;
-
-        public bool IsControl => _opcode == Opcode.Close || _opcode == Opcode.Ping || _opcode == Opcode.Pong;
-
-        public bool IsData => _opcode == Opcode.Binary || _opcode == Opcode.Text;
-
-        public bool IsFinal => _fin == Fin.Final;
-
-        public bool IsFragmented => _fin == Fin.More || _opcode == Opcode.Cont;
-
-        public bool IsMasked => _mask == Mask.Mask;
-
-        public bool IsPerMessageCompressed => (_opcode == Opcode.Binary || _opcode == Opcode.Text) && _rsv1 == Rsv.On;
-
-        public bool IsPing => _opcode == Opcode.Ping;
-
-        public bool IsPong => _opcode == Opcode.Pong;
-
-        public bool IsText => _opcode == Opcode.Text;
-
-        public ulong Length => 2 + (ulong)(_extPayloadLength.Length + _maskingKey.Length) + _payloadData.Length;
-
-        public Mask Mask => _mask;
-
-        public byte[] MaskingKey => _maskingKey;
-
-        public Opcode Opcode => _opcode;
-
-        public PayloadData PayloadData => _payloadData;
-
-        public byte PayloadLength => _payloadLength;
-
-        public Rsv Rsv1 => _rsv1;
-
-        public Rsv Rsv2 => _rsv2;
-
-        public Rsv Rsv3 => _rsv3;
-
-        #endregion
-
-        #region Private Methods
-
-        private byte[] createMaskingKey()
-        {
-            var key = new byte[4];
-            var rand = new Random();
-            rand.NextBytes(key);
-
-            return key;
-        }
-
-        private static bool isControl(Opcode opcode)
-        {
-            return opcode == Opcode.Close || opcode == Opcode.Ping || opcode == Opcode.Pong;
-        }
-
-        private static bool isData(Opcode opcode)
-        {
-            return opcode == Opcode.Text || opcode == Opcode.Binary;
-        }
-
-        private static async Task<WebSocketFrame> ReadAsync(byte[] header, Stream stream, bool unmask)
-        {
-            /* Header */
-
-            // FIN
-            var fin = (header[0] & 0x80) == 0x80 ? Fin.Final : Fin.More;
-            // RSV1
-            var rsv1 = (header[0] & 0x40) == 0x40 ? Rsv.On : Rsv.Off;
-            // RSV2
-            var rsv2 = (header[0] & 0x20) == 0x20 ? Rsv.On : Rsv.Off;
-            // RSV3
-            var rsv3 = (header[0] & 0x10) == 0x10 ? Rsv.On : Rsv.Off;
-            // Opcode
-            var opcode = (Opcode)(header[0] & 0x0f);
-            // MASK
-            var mask = (header[1] & 0x80) == 0x80 ? Mask.Mask : Mask.Unmask;
-            // Payload Length
-            var payloadLen = (byte)(header[1] & 0x7f);
-
-            // Check if correct frame.
-            var incorrect = isControl(opcode) && fin == Fin.More
-                            ? "A control frame is fragmented."
-                            : !isData(opcode) && rsv1 == Rsv.On
-                              ? "A non data frame is compressed."
-                              : null;
-
-            if (incorrect != null)
-                throw new WebSocketException(CloseStatusCode.IncorrectData, incorrect);
-
-            // Check if consistent frame.
-            if (isControl(opcode) && payloadLen > 125)
-                throw new WebSocketException(
-                  CloseStatusCode.InconsistentData,
-                  "The length of payload data of a control frame is greater than 125 bytes.");
-
-            var frame = new WebSocketFrame();
-            frame._fin = fin;
-            frame._rsv1 = rsv1;
-            frame._rsv2 = rsv2;
-            frame._rsv3 = rsv3;
-            frame._opcode = opcode;
-            frame._mask = mask;
-            frame._payloadLength = payloadLen;
-
-            /* Extended Payload Length */
-
-            var size = payloadLen < 126
-                       ? 0
-                       : payloadLen == 126
-                         ? 2
-                         : 8;
-
-            var extPayloadLen = size > 0 ? await stream.ReadBytesAsync(size).ConfigureAwait(false) : Array.Empty<byte>();
-            if (size > 0 && extPayloadLen.Length != size)
-                throw new WebSocketException(
-                  "The 'Extended Payload Length' of a frame cannot be read from the data source.");
-
-            frame._extPayloadLength = extPayloadLen;
-
-            /* Masking Key */
-
-            var masked = mask == Mask.Mask;
-            var maskingKey = masked ? await stream.ReadBytesAsync(4).ConfigureAwait(false) : Array.Empty<byte>();
-            if (masked && maskingKey.Length != 4)
-                throw new WebSocketException(
-                  "The 'Masking Key' of a frame cannot be read from the data source.");
-
-            frame._maskingKey = maskingKey;
-
-            /* Payload Data */
-
-            ulong len = payloadLen < 126
-                        ? payloadLen
-                        : payloadLen == 126
-                          ? extPayloadLen.ToUInt16(ByteOrder.Big)
-                          : extPayloadLen.ToUInt64(ByteOrder.Big);
-
-            byte[] data = null;
-            if (len > 0)
-            {
-                // Check if allowable payload data length.
-                if (payloadLen > 126 && len > PayloadData.MaxLength)
-                    throw new WebSocketException(
-                      CloseStatusCode.TooBig,
-                      "The length of 'Payload Data' of a frame is greater than the allowable length.");
-
-                data = payloadLen > 126
-                       ? await stream.ReadBytesAsync((long)len, 1024).ConfigureAwait(false)
-                       : await stream.ReadBytesAsync((int)len).ConfigureAwait(false);
-
-                //if (data.LongLength != (long)len)
-                //    throw new WebSocketException(
-                //      "The 'Payload Data' of a frame cannot be read from the data source.");
-            }
-            else
-            {
-                data = Array.Empty<byte>();
-            }
-
-            var payload = new PayloadData(data, masked);
-            if (masked && unmask)
-            {
-                payload.Mask(maskingKey);
-                frame._mask = Mask.Unmask;
-                frame._maskingKey = Array.Empty<byte>();
-            }
-
-            frame._payloadData = payload;
-            return frame;
-        }
-
-        #endregion
-
-        #region Internal Methods
-
-        internal static WebSocketFrame CreateCloseFrame(Mask mask, byte[] data)
-        {
-            return new WebSocketFrame(Opcode.Close, mask, new PayloadData(data));
-        }
-
-        internal static WebSocketFrame CreateCloseFrame(Mask mask, PayloadData payload)
-        {
-            return new WebSocketFrame(Opcode.Close, mask, payload);
-        }
-
-        internal static async Task<WebSocketFrame> CreateCloseFrameAsync(Mask mask, CloseStatusCode code, string reason)
-        {
-            return new WebSocketFrame(
-              Opcode.Close, mask, new PayloadData(await ((ushort)code).AppendAsync(reason).ConfigureAwait(false)));
-        }
-
-        internal static WebSocketFrame CreatePingFrame(Mask mask)
-        {
-            return new WebSocketFrame(Opcode.Ping, mask, new PayloadData());
-        }
-
-        internal static WebSocketFrame CreatePingFrame(Mask mask, byte[] data)
-        {
-            return new WebSocketFrame(Opcode.Ping, mask, new PayloadData(data));
-        }
-
-        internal static WebSocketFrame CreatePongFrame(Mask mask, PayloadData payload)
-        {
-            return new WebSocketFrame(Opcode.Pong, mask, payload);
-        }
-
-        internal static WebSocketFrame CreateWebSocketFrame(
-          Fin fin, Opcode opcode, Mask mask, byte[] data, bool compressed)
-        {
-            return new WebSocketFrame(fin, opcode, mask, new PayloadData(data), compressed);
-        }
-
-        internal static Task<WebSocketFrame> ReadAsync(Stream stream)
-            => ReadAsync(stream, true);
-
-        internal static async Task<WebSocketFrame> ReadAsync(Stream stream, bool unmask)
-        {
-            var header = await stream.ReadBytesAsync(2).ConfigureAwait(false);
-            if (header.Length != 2)
-            {
-                throw new WebSocketException(
-                  "The header part of a frame cannot be read from the data source.");
-            }
-
-            return await ReadAsync(header, stream, unmask).ConfigureAwait(false);
-        }
-
-        internal static async Task ReadAsync(
-          Stream stream, bool unmask, Action<WebSocketFrame> completed, Action<Exception> error)
-        {
-            try
-            {
-                var header = await stream.ReadBytesAsync(2).ConfigureAwait(false);
-                if (header.Length != 2)
-                {
-                    throw new WebSocketException(
-                      "The header part of a frame cannot be read from the data source.");
-                }
-
-                var frame = await ReadAsync(header, stream, unmask).ConfigureAwait(false);
-                completed?.Invoke(frame);
-            }
-            catch (Exception ex)
-            {
-                error.Invoke(ex);
-            }
-        }
-
-        #endregion
-
-        #region Public Methods
-
-        public IEnumerator<byte> GetEnumerator()
-        {
-            foreach (var b in ToByteArray())
-                yield return b;
-        }
-
-        public void Print(bool dumped)
-        {
-            //Console.WriteLine(dumped ? dump(this) : print(this));
-        }
-
-        public byte[] ToByteArray()
-        {
-            using (var buff = new MemoryStream())
-            {
-                var header = (int)_fin;
-                header = (header << 1) + (int)_rsv1;
-                header = (header << 1) + (int)_rsv2;
-                header = (header << 1) + (int)_rsv3;
-                header = (header << 4) + (int)_opcode;
-                header = (header << 1) + (int)_mask;
-                header = (header << 7) + (int)_payloadLength;
-                buff.Write(((ushort)header).ToByteArrayInternally(ByteOrder.Big), 0, 2);
-
-                if (_payloadLength > 125)
-                    buff.Write(_extPayloadLength, 0, _extPayloadLength.Length);
-
-                if (_mask == Mask.Mask)
-                    buff.Write(_maskingKey, 0, _maskingKey.Length);
-
-                if (_payloadLength > 0)
-                {
-                    var payload = _payloadData.ToByteArray();
-                    if (_payloadLength < 127)
-                        buff.Write(payload, 0, payload.Length);
-                    else
-                        buff.WriteBytes(payload);
-                }
-
-                return buff.ToArray();
-            }
-        }
-
-        public override string ToString()
-        {
-            return BitConverter.ToString(ToByteArray());
-        }
-
-        #endregion
-
-        #region Explicitly Implemented Interface Members
-
-        IEnumerator IEnumerable.GetEnumerator()
-        {
-            return GetEnumerator();
-        }
-
-        #endregion
-    }
-}