diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 376bdfd86..000000000
--- a/.gitignore
+++ /dev/null
@@ -1,14 +0,0 @@
-## Ignore build results and temporary files.
-
-Backup*
-_UpgradeReport_Files
-bin
-obj
-
-*.mdb
-*.pdb
-*.pidb
-*.suo
-*.user
-*.userprefs
-UpgradeLog*.*
diff --git a/Example/AssemblyInfo.cs b/Example/AssemblyInfo.cs
deleted file mode 100644
index 9a9617356..000000000
--- a/Example/AssemblyInfo.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-
-// Information about this assembly is defined by the following attributes.
-// Change them to the values specific to your project.
-
-[assembly: AssemblyTitle("Example")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("")]
-[assembly: AssemblyCopyright("sta.blockhead")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
-// The form "{Major}.{Minor}.*" will automatically update the build and revision,
-// and "{Major}.{Minor}.{Build}.*" will update just the revision.
-
-[assembly: AssemblyVersion("1.0.*")]
-
-// The following attributes are used to specify the signing key for the assembly,
-// if desired. See the Mono documentation for more information about signing.
-
-//[assembly: AssemblyDelaySign(false)]
-//[assembly: AssemblyKeyFile("")]
diff --git a/Example/Example.csproj b/Example/Example.csproj
deleted file mode 100644
index ee89d9f6e..000000000
--- a/Example/Example.csproj
+++ /dev/null
@@ -1,65 +0,0 @@
-
-
-
- Debug
- AnyCPU
- 9.0.21022
- 2.0
- {52805AEC-EFB1-4F42-BB8E-3ED4E692C568}
- Exe
- Example
- example
- v3.5
-
-
- true
- full
- false
- bin\Debug
- DEBUG
- prompt
- 4
- true
-
-
- none
- false
- bin\Release
- prompt
- 4
- true
-
-
- true
- full
- false
- bin\Debug_Ubuntu
- DEBUG
- prompt
- 4
- true
-
-
- none
- false
- bin\Release_Ubuntu
- prompt
- 4
- true
-
-
-
-
-
-
-
- {B357BAC7-529E-4D81-A0D2-71041B19C8DE}
- websocket-sharp
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Example/Program.cs b/Example/Program.cs
deleted file mode 100644
index 8d16c0794..000000000
--- a/Example/Program.cs
+++ /dev/null
@@ -1,149 +0,0 @@
-using System;
-using System.Threading;
-using WebSocketSharp;
-using WebSocketSharp.Net;
-
-namespace Example
-{
- public class Program
- {
- public static void Main (string[] args)
- {
- // Create a new instance of the WebSocket class.
- //
- // The WebSocket class inherits the System.IDisposable interface, so you can
- // use the using statement. And the WebSocket connection will be closed with
- // close status 1001 (going away) when the control leaves the using block.
- //
- // If you would like to connect to the server with the secure connection,
- // you should create a new instance with a wss scheme WebSocket URL.
-
- //using (var ws = new WebSocket ("ws://localhost:4649/Echo"))
- //using (var ws = new WebSocket ("wss://localhost:5963/Echo"))
- using (var ws = new WebSocket ("ws://localhost:4649/Chat"))
- //using (var ws = new WebSocket ("wss://localhost:5963/Chat"))
- //using (var ws = new WebSocket ("ws://localhost:4649/Chat?name=nobita"))
- //using (var ws = new WebSocket ("wss://localhost:5963/Chat?name=nobita"))
- {
-#if DEBUG
- // To change the logging level.
- ws.Log.Level = LogLevel.Trace;
-
- // To enable the Per-message Compression extension.
- //ws.Compression = CompressionMethod.Deflate;
-
- // To emit a WebSocket.OnMessage event when receives a ping.
- //ws.EmitOnPing = true;
-
- // To enable the redirection.
- //ws.EnableRedirection = true;
-
- // To disable a delay when send or receive buffer of the underlying
- // TCP socket is not full.
- ws.NoDelay = true;
-
- // To send the Origin header.
- //ws.Origin = "http://localhost:4649";
-
- // To send the cookies.
- //ws.SetCookie (new Cookie ("name", "nobita"));
- //ws.SetCookie (new Cookie ("roles", "\"idiot, gunfighter\""));
-
- // To send the credentials for the HTTP Authentication (Basic/Digest).
- //ws.SetCredentials ("nobita", "password", false);
-
- // To connect through the HTTP Proxy server.
- //ws.SetProxy ("http://localhost:3128", "nobita", "password");
-
- // To send a user header.
-
- var reqHeader = "RequestForID";
- var resHeader = "ID";
-
- ws.SetUserHeader (reqHeader, resHeader);
-
-
- // To validate the server certificate.
- /*
- ws.SslConfiguration.ServerCertificateValidationCallback =
- (sender, certificate, chain, sslPolicyErrors) => {
- var fmt = "Certificate:\n- Issuer: {0}\n- Subject: {1}";
- var msg = String.Format (
- fmt,
- certificate.Issuer,
- certificate.Subject
- );
-
- ws.Log.Debug (msg);
-
- return true; // If the server certificate is valid.
- };
- */
-
- // To change the wait time for the response to the Ping or Close.
- //ws.WaitTime = TimeSpan.FromSeconds (10);
-#endif
- // Set the WebSocket events.
-
- ws.OnClose +=
- (sender, e) => {
- var fmt = "[WebSocket Close ({0})] {1}";
-
- Console.WriteLine (fmt, e.Code, e.Reason);
- };
-
- ws.OnError +=
- (sender, e) => {
- var fmt = "[WebSocket Error] {0}";
-
- Console.WriteLine (fmt, e.Message);
- };
-
- ws.OnMessage +=
- (sender, e) => {
- var fmt = e.IsPing
- ? "[WebSocket Ping] {0}"
- : "[WebSocket Message] {0}";
-
- Console.WriteLine (fmt, e.Data);
- };
-
- ws.OnOpen +=
- (sender, e) => {
-#if DEBUG
- var val = ws.HandshakeResponseHeaders[resHeader];
-
- if (!val.IsNullOrEmpty ()) {
- var fmt = "[WebSocket Open] {0}: {1}";
-
- Console.WriteLine (fmt, resHeader, val);
- }
-#endif
- ws.Send ("Hi, there!");
- };
-
- // Connect to the server.
- ws.Connect ();
-
- // Connect to the server asynchronously.
- //ws.ConnectAsync ();
-
- Console.WriteLine ("\nType \"exit\" to exit.\n");
-
- while (true) {
- Thread.Sleep (1000);
-
- Console.Write ("> ");
-
- var msg = Console.ReadLine ();
-
- if (msg == "exit")
- break;
-
- // Send a text message.
- ws.Send (msg);
- }
- }
- }
- }
-}
diff --git a/Example2/App.config b/Example2/App.config
deleted file mode 100644
index 3a02690ea..000000000
--- a/Example2/App.config
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
diff --git a/Example2/AssemblyInfo.cs b/Example2/AssemblyInfo.cs
deleted file mode 100644
index 55cd94f77..000000000
--- a/Example2/AssemblyInfo.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-
-// Information about this assembly is defined by the following attributes.
-// Change them to the values specific to your project.
-
-[assembly: AssemblyTitle("Example2")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("")]
-[assembly: AssemblyCopyright("sta.blockhead")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
-// The form "{Major}.{Minor}.*" will automatically update the build and revision,
-// and "{Major}.{Minor}.{Build}.*" will update just the revision.
-
-[assembly: AssemblyVersion("1.0.*")]
-
-// The following attributes are used to specify the signing key for the assembly,
-// if desired. See the Mono documentation for more information about signing.
-
-//[assembly: AssemblyDelaySign(false)]
-//[assembly: AssemblyKeyFile("")]
diff --git a/Example2/Chat.cs b/Example2/Chat.cs
deleted file mode 100644
index 2391bf313..000000000
--- a/Example2/Chat.cs
+++ /dev/null
@@ -1,70 +0,0 @@
-using System;
-using System.Threading;
-using WebSocketSharp;
-using WebSocketSharp.Server;
-
-namespace Example2
-{
- public class Chat : WebSocketBehavior
- {
- private string _name;
- private static int _number = 0;
- private string _prefix;
-
- public Chat ()
- {
- _prefix = "anon#";
- }
-
- public string Prefix {
- get {
- return _prefix;
- }
-
- set {
- _prefix = !value.IsNullOrEmpty () ? value : "anon#";
- }
- }
-
- private string getName ()
- {
- var name = QueryString["name"];
-
- return !name.IsNullOrEmpty () ? name : _prefix + getNumber ();
- }
-
- private static int getNumber ()
- {
- return Interlocked.Increment (ref _number);
- }
-
- protected override void OnClose (CloseEventArgs e)
- {
- if (_name == null)
- return;
-
- var fmt = "{0} got logged off...";
- var msg = String.Format (fmt, _name);
-
- Sessions.Broadcast (msg);
- }
-
- protected override void OnMessage (MessageEventArgs e)
- {
- var fmt = "{0}: {1}";
- var msg = String.Format (fmt, _name, e.Data);
-
- Sessions.Broadcast (msg);
- }
-
- protected override void OnOpen ()
- {
- _name = getName ();
-
- var fmt = "{0} has logged in!";
- var msg = String.Format (fmt, _name);
-
- Sessions.Broadcast (msg);
- }
- }
-}
diff --git a/Example2/Echo.cs b/Example2/Echo.cs
deleted file mode 100644
index edc8872f9..000000000
--- a/Example2/Echo.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using System;
-using WebSocketSharp;
-using WebSocketSharp.Server;
-
-namespace Example2
-{
- public class Echo : WebSocketBehavior
- {
- protected override void OnMessage (MessageEventArgs e)
- {
- Send (e.Data);
- }
- }
-}
diff --git a/Example2/Example2.csproj b/Example2/Example2.csproj
deleted file mode 100644
index 685a1ef6d..000000000
--- a/Example2/Example2.csproj
+++ /dev/null
@@ -1,70 +0,0 @@
-
-
-
- Debug
- AnyCPU
- 9.0.21022
- 2.0
- {B81A24C8-25BB-42B2-AF99-1E1EACCE74C7}
- Exe
- Example2
- example2
- v3.5
-
-
- true
- full
- false
- bin\Debug
- DEBUG;
- prompt
- 4
- true
-
-
- none
- false
- bin\Release
- prompt
- 4
- true
-
-
- true
- full
- false
- bin\Debug_Ubuntu
- DEBUG;
- prompt
- 4
- true
-
-
- none
- false
- bin\Release_Ubuntu
- prompt
- 4
- true
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {B357BAC7-529E-4D81-A0D2-71041B19C8DE}
- websocket-sharp
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Example2/Program.cs b/Example2/Program.cs
deleted file mode 100644
index 4a2e8c0bf..000000000
--- a/Example2/Program.cs
+++ /dev/null
@@ -1,172 +0,0 @@
-using System;
-using System.Configuration;
-using System.Security.Cryptography.X509Certificates;
-using WebSocketSharp;
-using WebSocketSharp.Net;
-using WebSocketSharp.Server;
-
-namespace Example2
-{
- public class Program
- {
- public static void Main (string[] args)
- {
- // Create a new instance of the WebSocketServer class.
- //
- // If you would like to provide the secure connection, you should
- // create a new instance with the "secure" parameter set to true or
- // with a wss scheme WebSocket URL.
-
- var wssv = new WebSocketServer (4649);
- //var wssv = new WebSocketServer (5963, true);
-
- //var wssv = new WebSocketServer (System.Net.IPAddress.Any, 4649);
- //var wssv = new WebSocketServer (System.Net.IPAddress.Any, 5963, true);
-
- //var wssv = new WebSocketServer (System.Net.IPAddress.IPv6Any, 4649);
- //var wssv = new WebSocketServer (System.Net.IPAddress.IPv6Any, 5963, true);
-
- //var wssv = new WebSocketServer ("ws://0.0.0.0:4649");
- //var wssv = new WebSocketServer ("wss://0.0.0.0:5963");
-
- //var wssv = new WebSocketServer ("ws://[::0]:4649");
- //var wssv = new WebSocketServer ("wss://[::0]:5963");
-
- //var wssv = new WebSocketServer (System.Net.IPAddress.Loopback, 4649);
- //var wssv = new WebSocketServer (System.Net.IPAddress.Loopback, 5963, true);
-
- //var wssv = new WebSocketServer (System.Net.IPAddress.IPv6Loopback, 4649);
- //var wssv = new WebSocketServer (System.Net.IPAddress.IPv6Loopback, 5963, true);
-
- //var wssv = new WebSocketServer ("ws://localhost:4649");
- //var wssv = new WebSocketServer ("wss://localhost:5963");
-
- //var wssv = new WebSocketServer ("ws://127.0.0.1:4649");
- //var wssv = new WebSocketServer ("wss://127.0.0.1:5963");
-
- //var wssv = new WebSocketServer ("ws://[::1]:4649");
- //var wssv = new WebSocketServer ("wss://[::1]:5963");
-#if DEBUG
- // To change the logging level.
- wssv.Log.Level = LogLevel.Trace;
-
- // To provide the HTTP Authentication (Basic/Digest).
- /*
- wssv.AuthenticationSchemes = AuthenticationSchemes.Basic;
- wssv.Realm = "WebSocket Test";
- wssv.UserCredentialsFinder =
- id => {
- var name = id.Name;
-
- // Return user name, password, and roles.
- return name == "nobita"
- ? new NetworkCredential (name, "password", "gunfighter")
- : null; // If the user credentials are not found.
- };
- */
-
- // To remove the inactive sessions periodically.
- //wssv.KeepClean = true;
-
- // To resolve to wait for socket in TIME_WAIT state.
- //wssv.ReuseAddress = true;
-
- // To provide the secure connection.
- /*
- var cert = ConfigurationManager.AppSettings["ServerCertFile"];
- var passwd = ConfigurationManager.AppSettings["CertFilePassword"];
-
- wssv.SslConfiguration.ServerCertificate = new X509Certificate2 (
- cert,
- passwd
- );
- */
-
- // To change the wait time for the response to the WebSocket Ping or Close.
- //wssv.WaitTime = TimeSpan.FromSeconds (2);
-#endif
- // Add the WebSocket services.
-
- wssv.AddWebSocketService ("/Echo");
-
- // With initializing.
- wssv.AddWebSocketService (
- "/Chat",
- s => {
- s.Prefix = "Anon#";
-#if DEBUG
- // To respond to the cookies.
- /*
- s.CookiesResponder =
- (reqCookies, resCookies) => {
- foreach (var cookie in reqCookies) {
- cookie.Expired = true;
-
- resCookies.Add (cookie);
- }
- };
- */
-
- // To emit a WebSocket.OnMessage event when receives a ping.
- //s.EmitOnPing = true;
-
- // To ignore the Sec-WebSocket-Extensions header.
- //s.IgnoreExtensions = true;
-
- // To disable a delay when send or receive buffer of the underlying
- // TCP socket is not full.
- s.NoDelay = true;
-
- // To validate the Origin header.
- /*
- s.OriginValidator =
- val => {
- // Check the value of the Origin header, and return true if valid.
-
- Uri origin;
-
- return !val.IsNullOrEmpty ()
- && Uri.TryCreate (val, UriKind.Absolute, out origin)
- && origin.Host == "localhost";
- };
- */
-
- // To send the Sec-WebSocket-Protocol header that has a subprotocol
- // name.
- //s.Protocol = "chat";
-
- // To respond to the user headers.
-
- s.UserHeadersResponder =
- (reqHeaders, userHeaders) => {
- var val = reqHeaders["RequestForID"];
-
- if (!val.IsNullOrEmpty ())
- userHeaders[val] = s.ID;
- };
-
-#endif
- }
- );
-
- // Start the server.
- wssv.Start ();
-
- if (wssv.IsListening) {
- var fmt = "Listening on port {0}, and providing WebSocket services:";
-
- Console.WriteLine (fmt, wssv.Port);
-
- foreach (var path in wssv.WebSocketServices.Paths)
- Console.WriteLine ("- {0}", path);
- }
-
- Console.WriteLine ("\nPress Enter key to stop the server...");
-
- Console.ReadLine ();
-
- // Stop the server.
- wssv.Stop ();
- }
- }
-}
diff --git a/Example3/App.config b/Example3/App.config
deleted file mode 100644
index fa624b42b..000000000
--- a/Example3/App.config
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/Example3/AssemblyInfo.cs b/Example3/AssemblyInfo.cs
deleted file mode 100644
index b9a88a257..000000000
--- a/Example3/AssemblyInfo.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-
-// Information about this assembly is defined by the following attributes.
-// Change them to the values specific to your project.
-
-[assembly: AssemblyTitle("Example3")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("")]
-[assembly: AssemblyCopyright("sta.blockhead")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
-// The form "{Major}.{Minor}.*" will automatically update the build and revision,
-// and "{Major}.{Minor}.{Build}.*" will update just the revision.
-
-[assembly: AssemblyVersion("1.0.*")]
-
-// The following attributes are used to specify the signing key for the assembly,
-// if desired. See the Mono documentation for more information about signing.
-
-//[assembly: AssemblyDelaySign(false)]
-//[assembly: AssemblyKeyFile("")]
diff --git a/Example3/Chat.cs b/Example3/Chat.cs
deleted file mode 100644
index 0e3f38214..000000000
--- a/Example3/Chat.cs
+++ /dev/null
@@ -1,70 +0,0 @@
-using System;
-using System.Threading;
-using WebSocketSharp;
-using WebSocketSharp.Server;
-
-namespace Example3
-{
- public class Chat : WebSocketBehavior
- {
- private string _name;
- private static int _number = 0;
- private string _prefix;
-
- public Chat ()
- {
- _prefix = "anon#";
- }
-
- public string Prefix {
- get {
- return _prefix;
- }
-
- set {
- _prefix = !value.IsNullOrEmpty () ? value : "anon#";
- }
- }
-
- private string getName ()
- {
- var name = QueryString["name"];
-
- return !name.IsNullOrEmpty () ? name : _prefix + getNumber ();
- }
-
- private static int getNumber ()
- {
- return Interlocked.Increment (ref _number);
- }
-
- protected override void OnClose (CloseEventArgs e)
- {
- if (_name == null)
- return;
-
- var fmt = "{0} got logged off...";
- var msg = String.Format (fmt, _name);
-
- Sessions.Broadcast (msg);
- }
-
- protected override void OnMessage (MessageEventArgs e)
- {
- var fmt = "{0}: {1}";
- var msg = String.Format (fmt, _name, e.Data);
-
- Sessions.Broadcast (msg);
- }
-
- protected override void OnOpen ()
- {
- _name = getName ();
-
- var fmt = "{0} has logged in!";
- var msg = String.Format (fmt, _name);
-
- Sessions.Broadcast (msg);
- }
- }
-}
diff --git a/Example3/Echo.cs b/Example3/Echo.cs
deleted file mode 100644
index 01e2f16af..000000000
--- a/Example3/Echo.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using System;
-using WebSocketSharp;
-using WebSocketSharp.Server;
-
-namespace Example3
-{
- public class Echo : WebSocketBehavior
- {
- protected override void OnMessage (MessageEventArgs e)
- {
- Send (e.Data);
- }
- }
-}
diff --git a/Example3/Example3.csproj b/Example3/Example3.csproj
deleted file mode 100644
index ce4fe265c..000000000
--- a/Example3/Example3.csproj
+++ /dev/null
@@ -1,76 +0,0 @@
-
-
-
- Debug
- AnyCPU
- 9.0.21022
- 2.0
- {C648BA25-77E5-4A40-A97F-D0AA37B9FB26}
- Exe
- Example3
- example3
- v3.5
-
-
- true
- full
- false
- bin\Debug
- DEBUG;
- prompt
- 4
- true
-
-
- none
- false
- bin\Release
- prompt
- 4
- true
-
-
- true
- full
- false
- bin\Debug_Ubuntu
- DEBUG;
- prompt
- 4
- true
-
-
- none
- false
- bin\Release_Ubuntu
- prompt
- 4
- true
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {B357BAC7-529E-4D81-A0D2-71041B19C8DE}
- websocket-sharp
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Example3/Program.cs b/Example3/Program.cs
deleted file mode 100644
index 259b5164b..000000000
--- a/Example3/Program.cs
+++ /dev/null
@@ -1,210 +0,0 @@
-using System;
-using System.Configuration;
-using System.Security.Cryptography.X509Certificates;
-using System.Text;
-using WebSocketSharp;
-using WebSocketSharp.Net;
-using WebSocketSharp.Server;
-
-namespace Example3
-{
- public class Program
- {
- public static void Main (string[] args)
- {
- // Create a new instance of the HttpServer class.
- //
- // If you would like to provide the secure connection, you should
- // create a new instance with the "secure" parameter set to true or
- // with an https scheme HTTP URL.
-
- var httpsv = new HttpServer (4649);
- //var httpsv = new HttpServer (5963, true);
-
- //var httpsv = new HttpServer (System.Net.IPAddress.Any, 4649);
- //var httpsv = new HttpServer (System.Net.IPAddress.Any, 5963, true);
-
- //var httpsv = new HttpServer (System.Net.IPAddress.IPv6Any, 4649);
- //var httpsv = new HttpServer (System.Net.IPAddress.IPv6Any, 5963, true);
-
- //var httpsv = new HttpServer ("http://0.0.0.0:4649");
- //var httpsv = new HttpServer ("https://0.0.0.0:5963");
-
- //var httpsv = new HttpServer ("http://[::0]:4649");
- //var httpsv = new HttpServer ("https://[::0]:5963");
-
- //var httpsv = new HttpServer (System.Net.IPAddress.Loopback, 4649);
- //var httpsv = new HttpServer (System.Net.IPAddress.Loopback, 5963, true);
-
- //var httpsv = new HttpServer (System.Net.IPAddress.IPv6Loopback, 4649);
- //var httpsv = new HttpServer (System.Net.IPAddress.IPv6Loopback, 5963, true);
-
- //var httpsv = new HttpServer ("http://localhost:4649");
- //var httpsv = new HttpServer ("https://localhost:5963");
-
- //var httpsv = new HttpServer ("http://127.0.0.1:4649");
- //var httpsv = new HttpServer ("https://127.0.0.1:5963");
-
- //var httpsv = new HttpServer ("http://[::1]:4649");
- //var httpsv = new HttpServer ("https://[::1]:5963");
-#if DEBUG
- // To change the logging level.
- httpsv.Log.Level = LogLevel.Trace;
-
- // To provide the HTTP Authentication (Basic/Digest).
- /*
- httpsv.AuthenticationSchemes = AuthenticationSchemes.Basic;
- httpsv.Realm = "WebSocket Test";
- httpsv.UserCredentialsFinder =
- id => {
- var name = id.Name;
-
- // Return user name, password, and roles.
- return name == "nobita"
- ? new NetworkCredential (name, "password", "gunfighter")
- : null; // If the user credentials are not found.
- };
- */
-
- // To remove the inactive WebSocket sessions periodically.
- //httpsv.KeepClean = true;
-
- // To resolve to wait for socket in TIME_WAIT state.
- //httpsv.ReuseAddress = true;
-
- // To provide the secure connection.
- /*
- var cert = ConfigurationManager.AppSettings["ServerCertFile"];
- var passwd = ConfigurationManager.AppSettings["CertFilePassword"];
-
- httpsv.SslConfiguration.ServerCertificate = new X509Certificate2 (
- cert,
- passwd
- );
- */
-
- // To change the wait time for the response to the WebSocket Ping or Close.
- //httpsv.WaitTime = TimeSpan.FromSeconds (2);
-#endif
- // Set the document root path.
- httpsv.DocumentRootPath = ConfigurationManager
- .AppSettings["DocumentRootPath"];
-
- // Set the HTTP GET request event.
- httpsv.OnGet +=
- (sender, e) => {
- var req = e.Request;
- var res = e.Response;
-
- var path = req.RawUrl;
-
- if (path == "/")
- path += "index.html";
-
- byte[] contents;
-
- if (!e.TryReadFile (path, out contents)) {
- res.StatusCode = (int) HttpStatusCode.NotFound;
-
- return;
- }
-
- if (path.EndsWith (".html")) {
- res.ContentType = "text/html";
- res.ContentEncoding = Encoding.UTF8;
- }
- else if (path.EndsWith (".js")) {
- res.ContentType = "application/javascript";
- res.ContentEncoding = Encoding.UTF8;
- }
-
- res.ContentLength64 = contents.LongLength;
-
- res.Close (contents, true);
- };
-
- // Add the WebSocket services.
-
- httpsv.AddWebSocketService ("/Echo");
-
- // With initializing.
- httpsv.AddWebSocketService (
- "/Chat",
- s => {
- s.Prefix = "Anon#";
-#if DEBUG
- // To respond to the cookies.
- /*
- s.CookiesResponder =
- (reqCookies, resCookies) => {
- foreach (var cookie in reqCookies) {
- cookie.Expired = true;
-
- resCookies.Add (cookie);
- }
- };
- */
-
- // To emit a WebSocket.OnMessage event when receives a ping.
- //s.EmitOnPing = true;
-
- // To ignore the Sec-WebSocket-Extensions header.
- //s.IgnoreExtensions = true;
-
- // To disable a delay when send or receive buffer of the underlying
- // TCP socket is not full.
- s.NoDelay = true;
-
- // To validate the Origin header.
- /*
- s.OriginValidator =
- val => {
- // Check the value of the Origin header, and return true if valid.
-
- Uri origin;
-
- return !val.IsNullOrEmpty ()
- && Uri.TryCreate (val, UriKind.Absolute, out origin)
- && origin.Host == "localhost";
- };
- */
-
- // To send the Sec-WebSocket-Protocol header that has a subprotocol
- // name.
- //s.Protocol = "chat";
-
- // To respond to the user headers.
-
- s.UserHeadersResponder =
- (reqHeaders, userHeaders) => {
- var val = reqHeaders["RequestForID"];
-
- if (!val.IsNullOrEmpty ())
- userHeaders[val] = s.ID;
- };
-
-#endif
- }
- );
-
- // Start the server.
- httpsv.Start ();
-
- if (httpsv.IsListening) {
- var fmt = "Listening on port {0}, and providing WebSocket services:";
-
- Console.WriteLine (fmt, httpsv.Port);
-
- foreach (var path in httpsv.WebSocketServices.Paths)
- Console.WriteLine ("- {0}", path);
- }
-
- Console.WriteLine ("\nPress Enter key to stop the server...");
-
- Console.ReadLine ();
-
- // Stop the server.
- httpsv.Stop ();
- }
- }
-}
diff --git a/Example3/Public/Js/echotest.js b/Example3/Public/Js/echotest.js
deleted file mode 100644
index a356f0d3e..000000000
--- a/Example3/Public/Js/echotest.js
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * echotest.js
- *
- * Derived from Echo Test of WebSocket.org (http://www.websocket.org/echo.html).
- *
- * Copyright (c) 2012 Kaazing Corporation.
- */
-
-var url = "ws://localhost:4649/Echo";
-//var url = "wss://localhost:5963/Echo";
-var output;
-
-function init () {
- output = document.getElementById ("output");
- doWebSocket ();
-}
-
-function doWebSocket () {
- websocket = new WebSocket (url);
-
- websocket.onopen = function (e) {
- onOpen (e);
- };
-
- websocket.onmessage = function (e) {
- onMessage (e);
- };
-
- websocket.onerror = function (e) {
- onError (e);
- };
-
- websocket.onclose = function (e) {
- onClose (e);
- };
-}
-
-function onOpen (event) {
- writeToScreen ("CONNECTED");
- send ("WebSocket rocks");
-}
-
-function onMessage (event) {
- writeToScreen ('RESPONSE: ' + event.data + '');
- websocket.close ();
-}
-
-function onError (event) {
- writeToScreen ('ERROR: ' + event.data + '');
-}
-
-function onClose (event) {
- writeToScreen ("DISCONNECTED");
-}
-
-function send (message) {
- writeToScreen ("SENT: " + message);
- websocket.send (message);
-}
-
-function writeToScreen (message) {
- var pre = document.createElement ("p");
- pre.style.wordWrap = "break-word";
- pre.innerHTML = message;
- output.appendChild (pre);
-}
-
-window.addEventListener ("load", init, false);
\ No newline at end of file
diff --git a/Example3/Public/index.html b/Example3/Public/index.html
deleted file mode 100644
index 8d6fe43c3..000000000
--- a/Example3/Public/index.html
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
- WebSocket Echo Test
-
-
-
- WebSocket Echo Test
-
-
-
diff --git a/LICENSE.txt b/LICENSE.txt
deleted file mode 100644
index 5f791375f..000000000
--- a/LICENSE.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2010-2026 sta.blockhead
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/README.md b/README.md
deleted file mode 100644
index 4d9a5fd7b..000000000
--- a/README.md
+++ /dev/null
@@ -1,721 +0,0 @@
-
-
-## Welcome to websocket-sharp! ##
-
-websocket-sharp supports:
-
-- [RFC 6455](#supported-websocket-specifications)
-- [WebSocket Client](#websocket-client) and [Server](#websocket-server)
-- [Per-message Compression](#per-message-compression) extension
-- [Secure Connection](#secure-connection)
-- [HTTP Authentication](#http-authentication)
-- [Query string, Origin header, Cookies, and User headers](#query-string-origin-header-cookies-and-user-headers)
-- [Connecting through the HTTP proxy server](#connecting-through-the-http-proxy-server)
-- .NET Framework **3.5** or later versions of .NET Framework (includes compatible environment such as [Mono])
-
-## Branches ##
-
-- [master] for production releases.
-- [hybi-00] for older [draft-ietf-hybi-thewebsocketprotocol-00]. No longer maintained.
-- [draft75] for even more old [draft-hixie-thewebsocketprotocol-75]. No longer maintained.
-
-## Build ##
-
-websocket-sharp is built as a single assembly, **websocket-sharp.dll**.
-
-websocket-sharp is developed with [MonoDevelop]. So a simple way to build is to open **websocket-sharp.sln** and run build for **websocket-sharp project** with any of the build configurations (e.g. `Debug`) in MonoDevelop.
-
-## Install ##
-
-### Self Build ###
-
-You should add your websocket-sharp.dll (e.g. `/path/to/websocket-sharp/bin/Debug/websocket-sharp.dll`) to the library references of your project.
-
-If you would like to use that dll in your [Unity] project, you should add it to any folder of your project (e.g. `Assets/Plugins`) in the **Unity Editor**.
-
-### NuGet Gallery ###
-
-websocket-sharp is available on the [NuGet Gallery], as still a **prerelease** version.
-
-- [NuGet Gallery: websocket-sharp]
-
-You can add websocket-sharp to your project with the NuGet Package Manager, by using the following command in the Package Manager Console.
-
- PM> Install-Package WebSocketSharp -Pre
-
-## Usage ##
-
-### WebSocket Client ###
-
-```csharp
-using System;
-using WebSocketSharp;
-
-namespace Example
-{
- public class Program
- {
- public static void Main (string[] args)
- {
- using (var ws = new WebSocket ("ws://dragonsnest.far/Laputa")) {
- ws.OnMessage += (sender, e) =>
- Console.WriteLine ("Laputa says: " + e.Data);
-
- ws.Connect ();
- ws.Send ("BALUS");
- Console.ReadKey (true);
- }
- }
- }
-}
-```
-
-#### Step 1 ####
-
-Required namespace.
-
-```csharp
-using WebSocketSharp;
-```
-
-The `WebSocket` class exists in the `WebSocketSharp` namespace.
-
-#### Step 2 ####
-
-Creating a new instance of the `WebSocket` class with the WebSocket URL to connect.
-
-```csharp
-var ws = new WebSocket ("ws://example.com");
-```
-
-The `WebSocket` class inherits the `System.IDisposable` interface, so you can create it with the `using` statement.
-
-```csharp
-using (var ws = new WebSocket ("ws://example.com")) {
- ...
-}
-```
-
-This will **close** the WebSocket connection with status code `1001` (going away) when the control leaves the `using` block.
-
-#### Step 3 ####
-
-Setting the `WebSocket` events.
-
-##### WebSocket.OnOpen Event #####
-
-This event occurs when the WebSocket connection has been established.
-
-```csharp
-ws.OnOpen += (sender, e) => {
- ...
- };
-```
-
-`System.EventArgs.Empty` is passed as `e`, so you do not need to use it.
-
-##### WebSocket.OnMessage Event #####
-
-This event occurs when the `WebSocket` instance receives a message.
-
-```csharp
-ws.OnMessage += (sender, e) => {
- ...
- };
-```
-
-A `WebSocketSharp.MessageEventArgs` instance is passed as `e`.
-
-If you would like to get the message data, you should access `e.Data` or `e.RawData` property.
-
-`e.Data` property returns a `string`, so it is mainly used to get the **text** message data.
-
-`e.RawData` property returns a `byte[]`, so it is mainly used to get the **binary** message data.
-
-```csharp
-if (e.IsText) {
- // Do something with e.Data.
- ...
-
- return;
-}
-
-if (e.IsBinary) {
- // Do something with e.RawData.
- ...
-
- return;
-}
-```
-
-And if you would like to notify that a **ping** has been received, via this event, you should set the `WebSocket.EmitOnPing` property to `true`.
-
-```csharp
-ws.EmitOnPing = true;
-ws.OnMessage += (sender, e) => {
- if (e.IsPing) {
- // Do something to notify that a ping has been received.
- ...
-
- return;
- }
- };
-```
-
-##### WebSocket.OnError Event #####
-
-This event occurs when the `WebSocket` instance gets an error.
-
-```csharp
-ws.OnError += (sender, e) => {
- ...
- };
-```
-
-A `WebSocketSharp.ErrorEventArgs` instance is passed as `e`.
-
-If you would like to get the error message, you should access `e.Message` property.
-
-`e.Message` property returns a `string` that represents the error message.
-
-And `e.Exception` property returns a `System.Exception` instance that represents the cause of the error if it is due to an exception.
-
-##### WebSocket.OnClose Event #####
-
-This event occurs when the WebSocket connection has been closed.
-
-```csharp
-ws.OnClose += (sender, e) => {
- ...
- };
-```
-
-A `WebSocketSharp.CloseEventArgs` instance is passed as `e`.
-
-If you would like to get the reason for the close, you should access `e.Code` or `e.Reason` property.
-
-`e.Code` property returns a `ushort` that represents the status code for the close.
-
-`e.Reason` property returns a `string` that represents the reason for the close.
-
-#### Step 4 ####
-
-Connecting to the WebSocket server.
-
-```csharp
-ws.Connect ();
-```
-
-If you would like to connect to the server asynchronously, you should use the `WebSocket.ConnectAsync ()` method.
-
-#### Step 5 ####
-
-Sending data to the WebSocket server.
-
-```csharp
-ws.Send (data);
-```
-
-The `WebSocket.Send` method is overloaded.
-
-You can use the `WebSocket.Send (string)`, `WebSocket.Send (byte[])`, `WebSocket.Send (System.IO.FileInfo)`, or `WebSocket.Send (System.IO.Stream, int)` method to send the data.
-
-If you would like to send the data asynchronously, you should use the `WebSocket.SendAsync` method.
-
-```csharp
-ws.SendAsync (data, completed);
-```
-
-And also if you would like to do something when the send is complete, you should set `completed` to any `Action` delegate.
-
-#### Step 6 ####
-
-Closing the WebSocket connection.
-
-```csharp
-ws.Close (code, reason);
-```
-
-If you would like to close the connection explicitly, you should use the `WebSocket.Close` method.
-
-The `WebSocket.Close` method is overloaded.
-
-You can use the `WebSocket.Close ()`, `WebSocket.Close (ushort)`, `WebSocket.Close (WebSocketSharp.CloseStatusCode)`, `WebSocket.Close (ushort, string)`, or `WebSocket.Close (WebSocketSharp.CloseStatusCode, string)` method to close the connection.
-
-If you would like to close the connection asynchronously, you should use the `WebSocket.CloseAsync` method.
-
-### WebSocket Server ###
-
-```csharp
-using System;
-using WebSocketSharp;
-using WebSocketSharp.Server;
-
-namespace Example
-{
- public class Laputa : WebSocketBehavior
- {
- protected override void OnMessage (MessageEventArgs e)
- {
- var msg = e.Data == "BALUS"
- ? "Are you kidding?"
- : "I'm not available now.";
-
- Send (msg);
- }
- }
-
- public class Program
- {
- public static void Main (string[] args)
- {
- var wssv = new WebSocketServer ("ws://dragonsnest.far");
-
- wssv.AddWebSocketService ("/Laputa");
- wssv.Start ();
- Console.ReadKey (true);
- wssv.Stop ();
- }
- }
-}
-```
-
-#### Step 1 ####
-
-Required namespace.
-
-```csharp
-using WebSocketSharp.Server;
-```
-
-The `WebSocketBehavior` and `WebSocketServer` classes exist in the `WebSocketSharp.Server` namespace.
-
-#### Step 2 ####
-
-Creating the class that inherits the `WebSocketBehavior` class.
-
-For example, if you would like to provide an echo service,
-
-```csharp
-using System;
-using WebSocketSharp;
-using WebSocketSharp.Server;
-
-public class Echo : WebSocketBehavior
-{
- protected override void OnMessage (MessageEventArgs e)
- {
- Send (e.Data);
- }
-}
-```
-
-And if you would like to provide a chat service,
-
-```csharp
-using System;
-using WebSocketSharp;
-using WebSocketSharp.Server;
-
-public class Chat : WebSocketBehavior
-{
- private string _suffix;
-
- public Chat ()
- {
- _suffix = String.Empty;
- }
-
- public string Suffix {
- get {
- return _suffix;
- }
-
- set {
- _suffix = value ?? String.Empty;
- }
- }
-
- protected override void OnMessage (MessageEventArgs e)
- {
- Sessions.Broadcast (e.Data + _suffix);
- }
-}
-```
-
-You can define the behavior of any WebSocket service by creating the class that inherits the `WebSocketBehavior` class.
-
-If you override the `WebSocketBehavior.OnMessage (MessageEventArgs)` method, it will be called when the `WebSocket` used in a session in the service receives a message.
-
-And if you override the `WebSocketBehavior.OnOpen ()`, `WebSocketBehavior.OnError (ErrorEventArgs)`, and `WebSocketBehavior.OnClose (CloseEventArgs)` methods, each of them will be called when each of the `WebSocket` events (`OnOpen`, `OnError`, and `OnClose`) occurs.
-
-The `WebSocketBehavior.Send` method can send data to the client on a session in the service.
-
-If you would like to get the sessions in the service, you should access the `WebSocketBehavior.Sessions` property (returns a `WebSocketSharp.Server.WebSocketSessionManager`).
-
-The `WebSocketBehavior.Sessions.Broadcast` method can send data to every client in the service.
-
-#### Step 3 ####
-
-Creating a new instance of the `WebSocketServer` class.
-
-```csharp
-var wssv = new WebSocketServer (4649);
-
-wssv.AddWebSocketService ("/Echo");
-wssv.AddWebSocketService ("/Chat");
-wssv.AddWebSocketService ("/ChatWithNyan", s => s.Suffix = " Nyan!");
-```
-
-You can add any WebSocket service to your `WebSocketServer` with the specified behavior and absolute path to the service, by using the `WebSocketServer.AddWebSocketService (string)` or `WebSocketServer.AddWebSocketService (string, Action)` method.
-
-The type of `TBehavior` must inherit the `WebSocketBehavior` class, and must have a public parameterless constructor.
-
-So you can use a class in the above Step 2 to add the service.
-
-If you create a new instance of the `WebSocketServer` class without a port number, it sets the port number to **80**. So it is necessary to run with root permission.
-
- $ sudo mono example2.exe
-
-#### Step 4 ####
-
-Starting the WebSocket server.
-
-```csharp
-wssv.Start ();
-```
-
-#### Step 5 ####
-
-Stopping the WebSocket server.
-
-```csharp
-wssv.Stop ();
-```
-
-### HTTP Server with the WebSocket ###
-
-I have modified the `System.Net.HttpListener`, `System.Net.HttpListenerContext`, and some other classes from **[Mono]** to create an HTTP server that allows to accept the WebSocket handshake requests.
-
-So websocket-sharp provides the `WebSocketSharp.Server.HttpServer` class.
-
-You can add any WebSocket service to your `HttpServer` with the specified behavior and path to the service, by using the `HttpServer.AddWebSocketService (string)` or `HttpServer.AddWebSocketService (string, Action)` method.
-
-```csharp
-var httpsv = new HttpServer (4649);
-
-httpsv.AddWebSocketService ("/Echo");
-httpsv.AddWebSocketService ("/Chat");
-httpsv.AddWebSocketService ("/ChatWithNyan", s => s.Suffix = " Nyan!");
-```
-
-For more information, would you see **[Example3]**?
-
-### WebSocket Extensions ###
-
-#### Per-message Compression ####
-
-websocket-sharp supports the [Per-message Compression][rfc7692] extension (but does not support it with the [context take over]).
-
-As a WebSocket client, if you would like to enable this extension, you should set the `WebSocket.Compression` property to a compression method before calling the connect method.
-
-```csharp
-ws.Compression = CompressionMethod.Deflate;
-```
-
-And then the client will send the following header in the handshake request to the server.
-
- Sec-WebSocket-Extensions: permessage-deflate; server_no_context_takeover; client_no_context_takeover
-
-If the server supports this extension, it will return the same header which has the corresponding value.
-
-So eventually this extension will be available when the client receives the header in the handshake response.
-
-#### Ignoring the extensions ####
-
-As a WebSocket server, if you would like to ignore the extensions requested from a client, you should set the `WebSocketBehavior.IgnoreExtensions` property to `true` in your `WebSocketBehavior` constructor or initializing it, such as the following.
-
-```csharp
-wssv.AddWebSocketService (
- "/Chat",
- s => s.IgnoreExtensions = true // To ignore the extensions requested from a client.
-);
-```
-
-If it is set to `true`, the service will not return the Sec-WebSocket-Extensions header in its handshake response.
-
-I think this is useful when you get something error in connecting the server and exclude the extensions as a cause of the error.
-
-### Secure Connection ###
-
-websocket-sharp supports the secure connection with **SSL/TLS**.
-
-As a WebSocket client, you should create a new instance of the `WebSocket` class with a **wss** scheme WebSocket URL.
-
-```csharp
-var ws = new WebSocket ("wss://example.com");
-```
-
-If you would like to set a custom validation for the server certificate, you should set the `WebSocket.SslConfiguration.ServerCertificateValidationCallback` property to a callback for it.
-
-```csharp
-ws.SslConfiguration.ServerCertificateValidationCallback =
- (sender, certificate, chain, sslPolicyErrors) => {
- // Do something to validate the server certificate.
- ...
-
- return true; // If the server certificate is valid.
- };
-```
-
-The default callback always returns `true`.
-
-As a WebSocket server, you should create a new instance of the `WebSocketServer` or `HttpServer` class with some settings for the secure connection, such as the following.
-
-```csharp
-var wssv = new WebSocketServer (5963, true);
-wssv.SslConfiguration.ServerCertificate = new X509Certificate2 (
- "/path/to/cert.pfx", "password for cert.pfx"
- );
-```
-
-### HTTP Authentication ###
-
-websocket-sharp supports the [HTTP Authentication (Basic/Digest)][rfc2617].
-
-As a WebSocket client, you should set a pair of user name and password for the HTTP authentication, by using the `WebSocket.SetCredentials (string, string, bool)` method before calling the connect method.
-
-```csharp
-ws.SetCredentials ("nobita", "password", preAuth);
-```
-
-If `preAuth` is `true`, the client will send the credentials for the Basic authentication in the first handshake request to the server.
-
-Otherwise, it will send the credentials for either the Basic or Digest (determined by the unauthorized response to the first handshake request) authentication in the second handshake request to the server.
-
-As a WebSocket server, you should set an HTTP authentication scheme, a realm, and any function to find the user credentials before calling the start method, such as the following.
-
-```csharp
-wssv.AuthenticationSchemes = AuthenticationSchemes.Basic;
-wssv.Realm = "WebSocket Test";
-wssv.UserCredentialsFinder = id => {
- var name = id.Name;
-
- // Return user name, password, and roles.
- return name == "nobita"
- ? new NetworkCredential (name, "password", "gunfighter")
- : null; // If the user credentials are not found.
- };
-```
-
-If you would like to provide the Digest authentication, you should set such as the following.
-
-```csharp
-wssv.AuthenticationSchemes = AuthenticationSchemes.Digest;
-```
-
-### Query string, Origin header, Cookies, and User headers ###
-
-#### Query string ####
-
-As a WebSocket client, if you would like to send the query string in the handshake request, you should create a new instance of the `WebSocket` class with a WebSocket URL that includes the [Query] string parameters.
-
-```csharp
-var ws = new WebSocket ("ws://example.com/?name=nobita");
-```
-
-As a WebSocket server, if you would like to get the query string included in a handshake request, you should access the `WebSocketBehavior.QueryString` property, such as the following.
-
-```csharp
-public class Chat : WebSocketBehavior
-{
- private string _name;
- ...
-
- protected override void OnOpen ()
- {
- _name = QueryString["name"];
- }
-
- ...
-}
-```
-
-#### Origin header ####
-
-As a WebSocket client, if you would like to send the Origin header in the handshake request, you should set the `WebSocket.Origin` property to an allowable value as the [Origin] header before calling the connect method.
-
-```csharp
-ws.Origin = "http://example.com";
-```
-
-As a WebSocket server, if you would like to validate the Origin header, you should set a validation for it with your `WebSocketBehavior`, for example, by using the `WebSocketServer.AddWebSocketService (string, Action)` method with initializing, such as the following.
-
-```csharp
-wssv.AddWebSocketService (
- "/Chat",
- s => {
- s.OriginValidator =
- val => {
- // Check the value of the Origin header, and return true if valid.
-
- Uri origin;
-
- return !val.IsNullOrEmpty ()
- && Uri.TryCreate (val, UriKind.Absolute, out origin)
- && origin.Host == "example.com";
- };
- }
-);
-```
-
-#### Cookies ####
-
-As a WebSocket client, if you would like to send the cookies in the handshake request, you should set any cookie by using the `WebSocket.SetCookie (WebSocketSharp.Net.Cookie)` method before calling the connect method.
-
-```csharp
-ws.SetCookie (new Cookie ("name", "nobita"));
-```
-
-As a WebSocket server, if you would like to respond to the cookies, you should set a response action for it with your `WebSocketBehavior`, for example, by using the `WebSocketServer.AddWebSocketService (string, Action)` method with initializing, such as the following.
-
-```csharp
-wssv.AddWebSocketService (
- "/Chat",
- s => {
- s.CookiesResponder =
- (reqCookies, resCookies) => {
- foreach (var cookie in reqCookies) {
- cookie.Expired = true;
-
- resCookies.Add (cookie);
- }
- };
- }
-);
-```
-
-#### User headers ####
-
-As a WebSocket client, if you would like to send the user headers in the handshake request, you should set any user defined header by using the `WebSocket.SetUserHeader (string, string)` method before calling the connect method.
-
-```csharp
-ws.SetUserHeader ("RequestForID", "ID");
-```
-
-And if you would like to get the user headers included in the handshake response, you should access the `WebSocket.HandshakeResponseHeaders` property after the handshake is done.
-
-```csharp
-var id = ws.HandshakeResponseHeaders["ID"];
-```
-
-As a WebSocket server, if you would like to respond to the user headers, you should set a response action for it with your `WebSocketBehavior`, for example, by using the `WebSocketServer.AddWebSocketService (string, Action)` method with initializing, such as the following.
-
-```csharp
-wssv.AddWebSocketService (
- "/Chat",
- s => {
- s.UserHeadersResponder =
- (reqHeaders, userHeaders) => {
- var val = reqHeaders["RequestForID"];
-
- if (!val.IsNullOrEmpty ())
- userHeaders[val] = s.ID;
- };
- }
-);
-```
-
-### Connecting through the HTTP proxy server ###
-
-websocket-sharp supports to connect through the HTTP proxy server.
-
-If you would like to connect to a WebSocket server through the HTTP proxy server, you should set the proxy server URL, and if necessary, a pair of user name and password for the proxy server authentication (Basic/Digest), by using the `WebSocket.SetProxy (string, string, string)` method before calling the connect method.
-
-```csharp
-var ws = new WebSocket ("ws://example.com");
-ws.SetProxy ("http://localhost:3128", "nobita", "password");
-```
-
-I have tested this with **[Squid]**. It is necessary to disable the following option in **squid.conf** (e.g. `/etc/squid/squid.conf`).
-
-```
-# Deny CONNECT to other than SSL ports
-#http_access deny CONNECT !SSL_ports
-```
-
-### Logging ###
-
-The `WebSocket` class has the own logging function.
-
-You can use it with the `WebSocket.Log` property (returns a `WebSocketSharp.Logger`).
-
-So if you would like to change the current logging level (`WebSocketSharp.LogLevel.Error` as the default), you should set the `WebSocket.Log.Level` property to any of the `LogLevel` enum values.
-
-```csharp
-ws.Log.Level = LogLevel.Debug;
-```
-
-The above means a log with lower than `LogLevel.Debug` cannot be outputted.
-
-And if you would like to output a log, you should use any of the output methods. The following outputs a log with `LogLevel.Debug`.
-
-```csharp
-ws.Log.Debug ("This is a debug message.");
-```
-
-The `WebSocketServer` and `HttpServer` classes have the same logging function.
-
-## Examples ##
-
-Examples using websocket-sharp.
-
-### Example ###
-
-[Example] connects to the server executed by [Example2] or [Example3].
-
-### Example2 ###
-
-[Example2] starts a WebSocket server.
-
-### Example3 ###
-
-[Example3] starts an HTTP server that allows to accept the WebSocket handshake requests.
-
-Would you access to [http://localhost:4649](http://localhost:4649) to do **WebSocket Echo Test** with your web browser while Example3 is running?
-
-## Supported WebSocket Specifications ##
-
-websocket-sharp supports **RFC 6455**, and it is based on the following references:
-
-- [The WebSocket Protocol][rfc6455]
-- [The WebSocket API][api]
-- [Compression Extensions for WebSocket][rfc7692]
-
-## License ##
-
-websocket-sharp is provided under [The MIT License].
-
-
-[Example]: https://github.com/sta/websocket-sharp/tree/master/Example
-[Example2]: https://github.com/sta/websocket-sharp/tree/master/Example2
-[Example3]: https://github.com/sta/websocket-sharp/tree/master/Example3
-[Mono]: http://www.mono-project.com
-[MonoDevelop]: http://monodevelop.com
-[NuGet Gallery]: http://www.nuget.org
-[NuGet Gallery: websocket-sharp]: http://www.nuget.org/packages/WebSocketSharp
-[Origin]: http://tools.ietf.org/html/rfc6454#section-7
-[Query]: http://tools.ietf.org/html/rfc3986#section-3.4
-[Squid]: http://www.squid-cache.org
-[The MIT License]: https://raw.github.com/sta/websocket-sharp/master/LICENSE.txt
-[Unity]: http://unity3d.com
-[api]: http://www.w3.org/TR/websockets
-[context take over]: https://datatracker.ietf.org/doc/html/rfc7692#section-7.1.1
-[draft-hixie-thewebsocketprotocol-75]: http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-75
-[draft-ietf-hybi-thewebsocketprotocol-00]: http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-00
-[draft75]: https://github.com/sta/websocket-sharp/tree/draft75
-[hybi-00]: https://github.com/sta/websocket-sharp/tree/hybi-00
-[master]: https://github.com/sta/websocket-sharp/tree/master
-[rfc2617]: http://tools.ietf.org/html/rfc2617
-[rfc6455]: http://tools.ietf.org/html/rfc6455
-[rfc7692]: https://datatracker.ietf.org/doc/html/rfc7692
diff --git a/_config.yml b/_config.yml
new file mode 100644
index 000000000..2dad95fc8
--- /dev/null
+++ b/_config.yml
@@ -0,0 +1,8 @@
+title: websocket-sharp
+description: A C# implementation of the WebSocket protocol client and server
+google_analytics: UA-9752433-2
+show_downloads: true
+theme: jekyll-theme-cayman
+
+gems:
+ - jekyll-mentions
diff --git a/fonts/OpenSans-Bold-webfont.eot b/fonts/OpenSans-Bold-webfont.eot
new file mode 100644
index 000000000..e1c767443
Binary files /dev/null and b/fonts/OpenSans-Bold-webfont.eot differ
diff --git a/fonts/OpenSans-Bold-webfont.svg b/fonts/OpenSans-Bold-webfont.svg
new file mode 100644
index 000000000..364b36867
--- /dev/null
+++ b/fonts/OpenSans-Bold-webfont.svg
@@ -0,0 +1,146 @@
+
+
+
\ No newline at end of file
diff --git a/fonts/OpenSans-Bold-webfont.ttf b/fonts/OpenSans-Bold-webfont.ttf
new file mode 100644
index 000000000..2d94f0629
Binary files /dev/null and b/fonts/OpenSans-Bold-webfont.ttf differ
diff --git a/fonts/OpenSans-Bold-webfont.woff b/fonts/OpenSans-Bold-webfont.woff
new file mode 100644
index 000000000..cd86852d0
Binary files /dev/null and b/fonts/OpenSans-Bold-webfont.woff differ
diff --git a/fonts/OpenSans-BoldItalic-webfont.eot b/fonts/OpenSans-BoldItalic-webfont.eot
new file mode 100644
index 000000000..f44ac9a33
Binary files /dev/null and b/fonts/OpenSans-BoldItalic-webfont.eot differ
diff --git a/fonts/OpenSans-BoldItalic-webfont.svg b/fonts/OpenSans-BoldItalic-webfont.svg
new file mode 100644
index 000000000..8392240a1
--- /dev/null
+++ b/fonts/OpenSans-BoldItalic-webfont.svg
@@ -0,0 +1,146 @@
+
+
+
\ No newline at end of file
diff --git a/fonts/OpenSans-BoldItalic-webfont.ttf b/fonts/OpenSans-BoldItalic-webfont.ttf
new file mode 100644
index 000000000..f74e0e3ca
Binary files /dev/null and b/fonts/OpenSans-BoldItalic-webfont.ttf differ
diff --git a/fonts/OpenSans-BoldItalic-webfont.woff b/fonts/OpenSans-BoldItalic-webfont.woff
new file mode 100644
index 000000000..f3248c114
Binary files /dev/null and b/fonts/OpenSans-BoldItalic-webfont.woff differ
diff --git a/fonts/OpenSans-Italic-webfont.eot b/fonts/OpenSans-Italic-webfont.eot
new file mode 100644
index 000000000..277c1899c
Binary files /dev/null and b/fonts/OpenSans-Italic-webfont.eot differ
diff --git a/fonts/OpenSans-Italic-webfont.svg b/fonts/OpenSans-Italic-webfont.svg
new file mode 100644
index 000000000..29c7497fe
--- /dev/null
+++ b/fonts/OpenSans-Italic-webfont.svg
@@ -0,0 +1,146 @@
+
+
+
\ No newline at end of file
diff --git a/fonts/OpenSans-Italic-webfont.ttf b/fonts/OpenSans-Italic-webfont.ttf
new file mode 100644
index 000000000..63f187e98
Binary files /dev/null and b/fonts/OpenSans-Italic-webfont.ttf differ
diff --git a/fonts/OpenSans-Italic-webfont.woff b/fonts/OpenSans-Italic-webfont.woff
new file mode 100644
index 000000000..469a29bbf
Binary files /dev/null and b/fonts/OpenSans-Italic-webfont.woff differ
diff --git a/fonts/OpenSans-Light-webfont.eot b/fonts/OpenSans-Light-webfont.eot
new file mode 100644
index 000000000..837daab8d
Binary files /dev/null and b/fonts/OpenSans-Light-webfont.eot differ
diff --git a/fonts/OpenSans-Light-webfont.svg b/fonts/OpenSans-Light-webfont.svg
new file mode 100644
index 000000000..bdb672653
--- /dev/null
+++ b/fonts/OpenSans-Light-webfont.svg
@@ -0,0 +1,146 @@
+
+
+
\ No newline at end of file
diff --git a/fonts/OpenSans-Light-webfont.ttf b/fonts/OpenSans-Light-webfont.ttf
new file mode 100644
index 000000000..b50ef9dcb
Binary files /dev/null and b/fonts/OpenSans-Light-webfont.ttf differ
diff --git a/fonts/OpenSans-Light-webfont.woff b/fonts/OpenSans-Light-webfont.woff
new file mode 100644
index 000000000..99514d1a8
Binary files /dev/null and b/fonts/OpenSans-Light-webfont.woff differ
diff --git a/fonts/OpenSans-LightItalic-webfont.eot b/fonts/OpenSans-LightItalic-webfont.eot
new file mode 100644
index 000000000..f0ebf2c0e
Binary files /dev/null and b/fonts/OpenSans-LightItalic-webfont.eot differ
diff --git a/fonts/OpenSans-LightItalic-webfont.svg b/fonts/OpenSans-LightItalic-webfont.svg
new file mode 100644
index 000000000..60765da83
--- /dev/null
+++ b/fonts/OpenSans-LightItalic-webfont.svg
@@ -0,0 +1,146 @@
+
+
+
\ No newline at end of file
diff --git a/fonts/OpenSans-LightItalic-webfont.ttf b/fonts/OpenSans-LightItalic-webfont.ttf
new file mode 100644
index 000000000..5898c8c78
Binary files /dev/null and b/fonts/OpenSans-LightItalic-webfont.ttf differ
diff --git a/fonts/OpenSans-LightItalic-webfont.woff b/fonts/OpenSans-LightItalic-webfont.woff
new file mode 100644
index 000000000..9c978dc30
Binary files /dev/null and b/fonts/OpenSans-LightItalic-webfont.woff differ
diff --git a/fonts/OpenSans-Regular-webfont.eot b/fonts/OpenSans-Regular-webfont.eot
new file mode 100644
index 000000000..dd6fd2cb3
Binary files /dev/null and b/fonts/OpenSans-Regular-webfont.eot differ
diff --git a/fonts/OpenSans-Regular-webfont.svg b/fonts/OpenSans-Regular-webfont.svg
new file mode 100644
index 000000000..01038bb1c
--- /dev/null
+++ b/fonts/OpenSans-Regular-webfont.svg
@@ -0,0 +1,146 @@
+
+
+
\ No newline at end of file
diff --git a/fonts/OpenSans-Regular-webfont.ttf b/fonts/OpenSans-Regular-webfont.ttf
new file mode 100644
index 000000000..05951e7b3
Binary files /dev/null and b/fonts/OpenSans-Regular-webfont.ttf differ
diff --git a/fonts/OpenSans-Regular-webfont.woff b/fonts/OpenSans-Regular-webfont.woff
new file mode 100644
index 000000000..274664b28
Binary files /dev/null and b/fonts/OpenSans-Regular-webfont.woff differ
diff --git a/fonts/OpenSans-Semibold-webfont.eot b/fonts/OpenSans-Semibold-webfont.eot
new file mode 100644
index 000000000..289aade3e
Binary files /dev/null and b/fonts/OpenSans-Semibold-webfont.eot differ
diff --git a/fonts/OpenSans-Semibold-webfont.svg b/fonts/OpenSans-Semibold-webfont.svg
new file mode 100644
index 000000000..cc2ca4275
--- /dev/null
+++ b/fonts/OpenSans-Semibold-webfont.svg
@@ -0,0 +1,146 @@
+
+
+
\ No newline at end of file
diff --git a/fonts/OpenSans-Semibold-webfont.ttf b/fonts/OpenSans-Semibold-webfont.ttf
new file mode 100644
index 000000000..6f1507312
Binary files /dev/null and b/fonts/OpenSans-Semibold-webfont.ttf differ
diff --git a/fonts/OpenSans-Semibold-webfont.woff b/fonts/OpenSans-Semibold-webfont.woff
new file mode 100644
index 000000000..4e47cb1a6
Binary files /dev/null and b/fonts/OpenSans-Semibold-webfont.woff differ
diff --git a/fonts/OpenSans-SemiboldItalic-webfont.eot b/fonts/OpenSans-SemiboldItalic-webfont.eot
new file mode 100644
index 000000000..50a8a6f75
Binary files /dev/null and b/fonts/OpenSans-SemiboldItalic-webfont.eot differ
diff --git a/fonts/OpenSans-SemiboldItalic-webfont.svg b/fonts/OpenSans-SemiboldItalic-webfont.svg
new file mode 100644
index 000000000..65b50e2a6
--- /dev/null
+++ b/fonts/OpenSans-SemiboldItalic-webfont.svg
@@ -0,0 +1,146 @@
+
+
+
\ No newline at end of file
diff --git a/fonts/OpenSans-SemiboldItalic-webfont.ttf b/fonts/OpenSans-SemiboldItalic-webfont.ttf
new file mode 100644
index 000000000..55ba3120f
Binary files /dev/null and b/fonts/OpenSans-SemiboldItalic-webfont.ttf differ
diff --git a/fonts/OpenSans-SemiboldItalic-webfont.woff b/fonts/OpenSans-SemiboldItalic-webfont.woff
new file mode 100644
index 000000000..0adc6df16
Binary files /dev/null and b/fonts/OpenSans-SemiboldItalic-webfont.woff differ
diff --git a/images/body-bg.jpg b/images/body-bg.jpg
new file mode 100644
index 000000000..0e0f861ba
Binary files /dev/null and b/images/body-bg.jpg differ
diff --git a/images/bullet.png b/images/bullet.png
new file mode 100644
index 000000000..0614eb65f
Binary files /dev/null and b/images/bullet.png differ
diff --git a/images/checker.png b/images/checker.png
new file mode 100644
index 000000000..ab1454032
Binary files /dev/null and b/images/checker.png differ
diff --git a/images/download-button.png b/images/download-button.png
new file mode 100644
index 000000000..df3f09a63
Binary files /dev/null and b/images/download-button.png differ
diff --git a/images/github-button.png b/images/github-button.png
new file mode 100644
index 000000000..efe07f9ad
Binary files /dev/null and b/images/github-button.png differ
diff --git a/images/header-bg.jpg b/images/header-bg.jpg
new file mode 100644
index 000000000..960bff75f
Binary files /dev/null and b/images/header-bg.jpg differ
diff --git a/images/highlight-bg.jpg b/images/highlight-bg.jpg
new file mode 100644
index 000000000..4c4a78eff
Binary files /dev/null and b/images/highlight-bg.jpg differ
diff --git a/images/hr.gif b/images/hr.gif
new file mode 100644
index 000000000..bdb4168de
Binary files /dev/null and b/images/hr.gif differ
diff --git a/images/nav-bg.gif b/images/nav-bg.gif
new file mode 100644
index 000000000..474396561
Binary files /dev/null and b/images/nav-bg.gif differ
diff --git a/images/sidebar-bg.jpg b/images/sidebar-bg.jpg
new file mode 100644
index 000000000..42890fe73
Binary files /dev/null and b/images/sidebar-bg.jpg differ
diff --git a/index.md b/index.md
new file mode 100644
index 000000000..ac0ef186b
--- /dev/null
+++ b/index.md
@@ -0,0 +1,686 @@
+## Welcome to websocket-sharp! ##
+
+**websocket-sharp** supports:
+
+- **[RFC 6455](#supported-websocket-specifications)**
+- **[WebSocket Client](#websocket-client)** and **[Server](#websocket-server)**
+- **[Per-message Compression](#per-message-compression)** extension
+- **[Secure Connection](#secure-connection)**
+- **[HTTP Authentication](#http-authentication)**
+- **[Query String, Origin header and Cookies](#query-string-origin-header-and-cookies)**
+- **[Connecting through the HTTP Proxy server](#connecting-through-the-http-proxy-server)**
+- .NET Framework **3.5** or later (includes compatible environment such as **[Mono]**)
+
+## Build ##
+
+websocket-sharp is built as a single assembly, **websocket-sharp.dll**.
+
+websocket-sharp is developed with **[MonoDevelop]**. So a simple way to build is to open **websocket-sharp.sln** and run build for **websocket-sharp project** with any of the build configurations (e.g. `Debug`) in MonoDevelop.
+
+## Install ##
+
+### Self Build ###
+
+You should add your **websocket-sharp.dll** (e.g. `/path/to/websocket-sharp/bin/Debug/websocket-sharp.dll`) to the library references of your project.
+
+If you would like to use that dll in your **[Unity]** project, you should add it to any folder of your project (e.g. `Assets/Plugins`) in **Unity Editor**.
+
+### NuGet Gallery ###
+
+websocket-sharp is available on the **[NuGet Gallery]**, as still a **prerelease** version.
+
+- **[NuGet Gallery: websocket-sharp]**
+
+You can add websocket-sharp to your project with the **NuGet Package Manager**, by using the following command in the **Package Manager Console**.
+
+ PM> Install-Package WebSocketSharp -Pre
+
+### Unity Asset Store ###
+
+websocket-sharp is available on the **Unity Asset Store**.
+
+- **[WebSocket-Sharp for Unity]**
+
+It works with **Unity Free**, but there are some limitations:
+
+- **[Security Sandbox of the Webplayer]** (The server isn't available in Web Player)
+- **[WebGL Networking]** (Not available in WebGL)
+- **Incompatible platform** (Not available for such UWP)
+- **Limited support for the System.IO.Compression** (The compression extension isn't available on Windows)
+- **.NET Socket Support for iOS/Android** (It requires iOS/Android Pro if your Unity is earlier than Unity 5)
+- **.NET API 2.0 compatibility level for iOS/Android**
+
+**.NET API 2.0 compatibility level for iOS/Android** may require to fix lack of some features for later than .NET 2.0, such as the `System.Func<...>` delegates (so i have added them in that asset package).
+
+And it's priced at **US$15**. I think your $15 makes this project more better and accelerated, **Thank you!**
+
+## Usage ##
+
+### WebSocket Client ###
+
+```csharp
+using System;
+using WebSocketSharp;
+
+namespace Example
+{
+ public class Program
+ {
+ public static void Main (string[] args)
+ {
+ using (var ws = new WebSocket ("ws://dragonsnest.far/Laputa")) {
+ ws.OnMessage += (sender, e) =>
+ Console.WriteLine ("Laputa says: " + e.Data);
+
+ ws.Connect ();
+ ws.Send ("BALUS");
+ Console.ReadKey (true);
+ }
+ }
+ }
+}
+```
+
+#### Step 1 ####
+
+Required namespace.
+
+```csharp
+using WebSocketSharp;
+```
+
+The `WebSocket` class exists in the `WebSocketSharp` namespace.
+
+#### Step 2 ####
+
+Creating a new instance of the `WebSocket` class with the WebSocket URL to connect.
+
+```csharp
+using (var ws = new WebSocket ("ws://example.com")) {
+ ...
+}
+```
+
+The `WebSocket` class inherits the `System.IDisposable` interface, so you can use the `using` statement. And the WebSocket connection will be closed with close status `1001` (going away) when the control leaves the `using` block.
+
+#### Step 3 ####
+
+Setting the `WebSocket` events.
+
+##### WebSocket.OnOpen Event #####
+
+A `WebSocket.OnOpen` event occurs when the WebSocket connection has been established.
+
+```csharp
+ws.OnOpen += (sender, e) => {
+ ...
+ };
+```
+
+`e` has passed as the `System.EventArgs.Empty`, so you don't need to use it.
+
+##### WebSocket.OnMessage Event #####
+
+A `WebSocket.OnMessage` event occurs when the `WebSocket` receives a message.
+
+```csharp
+ws.OnMessage += (sender, e) => {
+ ...
+ };
+```
+
+`e` has passed as a `WebSocketSharp.MessageEventArgs`.
+
+If you would like to get the message data, you should access `e.Data` or `e.RawData` property.
+
+And you can determine which property you should access by checking `e.IsText` or `e.IsBinary` property.
+
+If `e.IsText` is `true`, you should access `e.Data` that returns a `string` (represents a **text** message).
+
+Or if `e.IsBinary` is `true`, you should access `e.RawData` that returns a `byte[]` (represents a **binary** message).
+
+```csharp
+if (e.IsText) {
+ // Do something with e.Data.
+ ...
+
+ return;
+}
+
+if (e.IsBinary) {
+ // Do something with e.RawData.
+ ...
+
+ return;
+}
+```
+
+And if you would like to notify that a **ping** has been received, via this event, you should set the `WebSocket.EmitOnPing` property to `true`, such as the following.
+
+```csharp
+ws.EmitOnPing = true;
+ws.OnMessage += (sender, e) => {
+ if (e.IsPing) {
+ // Do something to notify that a ping has been received.
+ ...
+
+ return;
+ }
+ };
+```
+
+##### WebSocket.OnError Event #####
+
+A `WebSocket.OnError` event occurs when the `WebSocket` gets an error.
+
+```csharp
+ws.OnError += (sender, e) => {
+ ...
+ };
+```
+
+`e` has passed as a `WebSocketSharp.ErrorEventArgs`.
+
+`e.Message` property returns a `string` that represents the error message.
+
+If the error is due to an exception, `e.Exception` property returns a `System.Exception` instance that caused the error.
+
+##### WebSocket.OnClose Event #####
+
+A `WebSocket.OnClose` event occurs when the WebSocket connection has been closed.
+
+```csharp
+ws.OnClose += (sender, e) => {
+ ...
+ };
+```
+
+`e` has passed as a `WebSocketSharp.CloseEventArgs`.
+
+`e.Code` property returns a `ushort` that represents the status code for the close, and `e.Reason` property returns a `string` that represents the reason for the close.
+
+#### Step 4 ####
+
+Connecting to the WebSocket server.
+
+```csharp
+ws.Connect ();
+```
+
+If you would like to connect to the server asynchronously, you should use the `WebSocket.ConnectAsync ()` method.
+
+#### Step 5 ####
+
+Sending data to the WebSocket server.
+
+```csharp
+ws.Send (data);
+```
+
+The `WebSocket.Send` method is overloaded.
+
+You can use the `WebSocket.Send (string)`, `WebSocket.Send (byte[])`, or `WebSocket.Send (System.IO.FileInfo)` method to send the data.
+
+If you would like to send the data asynchronously, you should use the `WebSocket.SendAsync` method.
+
+```csharp
+ws.SendAsync (data, completed);
+```
+
+And also if you would like to do something when the send is complete, you should set `completed` to any `Action` delegate.
+
+#### Step 6 ####
+
+Closing the WebSocket connection.
+
+```csharp
+ws.Close (code, reason);
+```
+
+If you would like to close the connection explicitly, you should use the `WebSocket.Close` method.
+
+The `WebSocket.Close` method is overloaded.
+
+You can use the `WebSocket.Close ()`, `WebSocket.Close (ushort)`, `WebSocket.Close (WebSocketSharp.CloseStatusCode)`, `WebSocket.Close (ushort, string)`, or `WebSocket.Close (WebSocketSharp.CloseStatusCode, string)` method to close the connection.
+
+If you would like to close the connection asynchronously, you should use the `WebSocket.CloseAsync` method.
+
+### WebSocket Server ###
+
+```csharp
+using System;
+using WebSocketSharp;
+using WebSocketSharp.Server;
+
+namespace Example
+{
+ public class Laputa : WebSocketBehavior
+ {
+ protected override void OnMessage (MessageEventArgs e)
+ {
+ var msg = e.Data == "BALUS"
+ ? "I've been balused already..."
+ : "I'm not available now.";
+
+ Send (msg);
+ }
+ }
+
+ public class Program
+ {
+ public static void Main (string[] args)
+ {
+ var wssv = new WebSocketServer ("ws://dragonsnest.far");
+ wssv.AddWebSocketService ("/Laputa");
+ wssv.Start ();
+ Console.ReadKey (true);
+ wssv.Stop ();
+ }
+ }
+}
+```
+
+#### Step 1 ####
+
+Required namespace.
+
+```csharp
+using WebSocketSharp.Server;
+```
+
+The `WebSocketBehavior` and `WebSocketServer` classes exist in the `WebSocketSharp.Server` namespace.
+
+#### Step 2 ####
+
+Creating the class that inherits the `WebSocketBehavior` class.
+
+For example, if you would like to provide an echo service,
+
+```csharp
+using System;
+using WebSocketSharp;
+using WebSocketSharp.Server;
+
+public class Echo : WebSocketBehavior
+{
+ protected override void OnMessage (MessageEventArgs e)
+ {
+ Send (e.Data);
+ }
+}
+```
+
+And if you would like to provide a chat service,
+
+```csharp
+using System;
+using WebSocketSharp;
+using WebSocketSharp.Server;
+
+public class Chat : WebSocketBehavior
+{
+ private string _suffix;
+
+ public Chat ()
+ : this (null)
+ {
+ }
+
+ public Chat (string suffix)
+ {
+ _suffix = suffix ?? String.Empty;
+ }
+
+ protected override void OnMessage (MessageEventArgs e)
+ {
+ Sessions.Broadcast (e.Data + _suffix);
+ }
+}
+```
+
+You can define the behavior of any WebSocket service by creating the class that inherits the `WebSocketBehavior` class.
+
+If you override the `WebSocketBehavior.OnMessage (MessageEventArgs)` method, it will be called when the `WebSocket` used in a session in the service receives a message.
+
+And if you override the `WebSocketBehavior.OnOpen ()`, `WebSocketBehavior.OnError (ErrorEventArgs)`, and `WebSocketBehavior.OnClose (CloseEventArgs)` methods, each of them will be called when each of the `WebSocket` events (`OnOpen`, `OnError`, and `OnClose`) occurs.
+
+The `WebSocketBehavior.Send` method can send data to the client on a session in the service.
+
+If you would like to get the sessions in the service, you should access the `WebSocketBehavior.Sessions` property (returns a `WebSocketSharp.Server.WebSocketSessionManager`).
+
+The `WebSocketBehavior.Sessions.Broadcast` method can send data to every client in the service.
+
+#### Step 3 ####
+
+Creating a new instance of the `WebSocketServer` class.
+
+```csharp
+var wssv = new WebSocketServer (4649);
+wssv.AddWebSocketService ("/Echo");
+wssv.AddWebSocketService ("/Chat");
+wssv.AddWebSocketService ("/ChatWithNyan", () => new Chat (" Nyan!"));
+```
+
+You can add any WebSocket service to your `WebSocketServer` with the specified behavior and path to the service, by using the `WebSocketServer.AddWebSocketService (string)` or `WebSocketServer.AddWebSocketService (string, Func)` method.
+
+The type of `TBehaviorWithNew` must inherit the `WebSocketBehavior` class, and must have a public parameterless constructor.
+
+And also the type of `TBehavior` must inherit the `WebSocketBehavior` class.
+
+So you can use the classes created in **Step 2** to add the service.
+
+If you create a instance of the `WebSocketServer` class without a port number, the `WebSocketServer` class set the port number to **80** automatically. So it's necessary to run with root permission.
+
+ $ sudo mono example2.exe
+
+#### Step 4 ####
+
+Starting the WebSocket server.
+
+```csharp
+wssv.Start ();
+```
+
+#### Step 5 ####
+
+Stopping the WebSocket server.
+
+```csharp
+wssv.Stop (code, reason);
+```
+
+The `WebSocketServer.Stop` method is overloaded.
+
+You can use the `WebSocketServer.Stop ()`, `WebSocketServer.Stop (ushort, string)`, or `WebSocketServer.Stop (WebSocketSharp.CloseStatusCode, string)` method to stop the server.
+
+### HTTP Server with the WebSocket ###
+
+I have modified the `System.Net.HttpListener`, `System.Net.HttpListenerContext`, and some other classes from **[Mono]** to create an HTTP server that allows to accept the WebSocket handshake requests.
+
+So websocket-sharp provides the `WebSocketSharp.Server.HttpServer` class.
+
+You can add any WebSocket service to your `HttpServer` with the specified behavior and path to the service, by using the `HttpServer.AddWebSocketService (string)` or `HttpServer.AddWebSocketService (string, Func)` method.
+
+```csharp
+var httpsv = new HttpServer (4649);
+httpsv.AddWebSocketService ("/Echo");
+httpsv.AddWebSocketService ("/Chat");
+httpsv.AddWebSocketService ("/ChatWithNyan", () => new Chat (" Nyan!"));
+```
+
+For more information, would you see **[Example3]**?
+
+### WebSocket Extensions ###
+
+#### Per-message Compression ####
+
+websocket-sharp supports the **[Per-message Compression][compression]** extension (but doesn't support this extension with the [context take over]).
+
+As a WebSocket client, if you would like to enable this extension, you should set such as the following.
+
+```csharp
+ws.Compression = CompressionMethod.Deflate;
+```
+
+And then your client will send the following header in the handshake request to the server.
+
+ Sec-WebSocket-Extensions: permessage-deflate; server_no_context_takeover; client_no_context_takeover
+
+If the server accepts this extension, it will return the same header which has the corresponding value. And when your client receives it, this extension will be available.
+
+#### Ignoring the extensions ####
+
+As a WebSocket server, if you would like to ignore the extensions requested from a client, you should set the `WebSocketBehavior.IgnoreExtensions` property to `true` in your `WebSocketBehavior` constructor or initializing it, such as the following.
+
+```csharp
+wssv.AddWebSocketService (
+ "/Chat",
+ () =>
+ new Chat () {
+ // To ignore the extensions requested from a client.
+ IgnoreExtensions = true
+ }
+);
+```
+
+If it's set to `true`, the service will not return the **Sec-WebSocket-Extensions** header in its handshake response.
+
+I think this is useful when you get something error in connecting the server and exclude the extensions as a cause of the error.
+
+### Secure Connection ###
+
+websocket-sharp supports the **Secure Connection** with **SSL/TLS**.
+
+As a **WebSocket Client**, you should create a new instance of the `WebSocket` class with the **wss** scheme WebSocket URL.
+
+```csharp
+using (var ws = new WebSocket ("wss://example.com")) {
+ ...
+}
+```
+
+And if you would like to use the custom validation for the server certificate, you should set the `WebSocket.SslConfiguration.ServerCertificateValidationCallback` property.
+
+```csharp
+ws.SslConfiguration.ServerCertificateValidationCallback =
+ (sender, certificate, chain, sslPolicyErrors) => {
+ // Do something to validate the server certificate.
+ ...
+
+ return true; // If the server certificate is valid.
+ };
+```
+
+If you set this property to nothing, the validation does nothing with the server certificate, and returns `true`.
+
+As a **WebSocket Server**, you should create a new instance of the `WebSocketServer` or `HttpServer` class with some settings for secure connection, such as the following.
+
+```csharp
+var wssv = new WebSocketServer (5963, true);
+wssv.SslConfiguration.ServerCertificate =
+ new X509Certificate2 ("/path/to/cert.pfx", "password for cert.pfx");
+```
+
+### HTTP Authentication ###
+
+websocket-sharp supports the **[HTTP Authentication (Basic/Digest)][rfc2617]**.
+
+As a **WebSocket Client**, you should set a pair of user name and password for the HTTP authentication, by using the `WebSocket.SetCredentials (string, string, bool)` method before connecting.
+
+```csharp
+ws.SetCredentials ("nobita", "password", preAuth);
+```
+
+If `preAuth` is `true`, the `WebSocket` sends the Basic authentication credentials with the first handshake request to the server.
+
+Or if `preAuth` is `false`, the `WebSocket` sends either the Basic or Digest (determined by the unauthorized response to the first handshake request) authentication credentials with the second handshake request to the server.
+
+As a **WebSocket Server**, you should set an HTTP authentication scheme, a realm, and any function to find the user credentials before starting, such as the following.
+
+```csharp
+wssv.AuthenticationSchemes = AuthenticationSchemes.Basic;
+wssv.Realm = "WebSocket Test";
+wssv.UserCredentialsFinder = id => {
+ var name = id.Name;
+
+ // Return user name, password, and roles.
+ return name == "nobita"
+ ? new NetworkCredential (name, "password", "gunfighter")
+ : null; // If the user credentials aren't found.
+ };
+```
+
+If you would like to provide the Digest authentication, you should set such as the following.
+
+```csharp
+wssv.AuthenticationSchemes = AuthenticationSchemes.Digest;
+```
+
+### Query String, Origin header and Cookies ###
+
+As a **WebSocket Client**, if you would like to send the **Query String** with the handshake request to the server, you should create a new instance of the `WebSocket` class with the WebSocket URL that includes the [Query] string parameters.
+
+```csharp
+using (var ws = new WebSocket ("ws://example.com/?name=nobita")) {
+ ...
+}
+```
+
+And if you would like to send the **Origin** header with the handshake request to the server, you should set the `WebSocket.Origin` property to an allowable value as the [Origin] header before connecting, such as the following.
+
+```csharp
+ws.Origin = "http://example.com";
+```
+
+And also if you would like to send the **Cookies** with the handshake request to the server, you should set any cookie by using the `WebSocket.SetCookie (WebSocketSharp.Net.Cookie)` method before connecting, such as the following.
+
+```csharp
+ws.SetCookie (new Cookie ("name", "nobita"));
+```
+
+As a **WebSocket Server**, if you would like to get the **Query String** included in a handshake request, you should access the `WebSocketBehavior.Context.QueryString` property, such as the following.
+
+```csharp
+public class Chat : WebSocketBehavior
+{
+ private string _name;
+ ...
+
+ protected override void OnOpen ()
+ {
+ _name = Context.QueryString["name"];
+ }
+
+ ...
+}
+```
+
+And if you would like to validate the **Origin** header, **Cookies**, or both included in a handshake request, you should set each validation with your `WebSocketBehavior`, for example, by using the `AddWebSocketService (string, Func)` method with initializing, such as the following.
+
+```csharp
+wssv.AddWebSocketService (
+ "/Chat",
+ () =>
+ new Chat () {
+ OriginValidator = val => {
+ // Check the value of the Origin header, and return true if valid.
+ Uri origin;
+ return !val.IsNullOrEmpty ()
+ && Uri.TryCreate (val, UriKind.Absolute, out origin)
+ && origin.Host == "example.com";
+ },
+ CookiesValidator = (req, res) => {
+ // Check the cookies in 'req', and set the cookies to send to
+ // the client with 'res' if necessary.
+ foreach (Cookie cookie in req) {
+ cookie.Expired = true;
+ res.Add (cookie);
+ }
+
+ return true; // If valid.
+ }
+ }
+);
+```
+
+And also if you would like to get each value of the Origin header and cookies, you should access each of the `WebSocketBehavior.Context.Origin` and `WebSocketBehavior.Context.CookieCollection` properties.
+
+### Connecting through the HTTP Proxy server ###
+
+websocket-sharp supports to connect through the **HTTP Proxy** server.
+
+If you would like to connect to a WebSocket server through the HTTP proxy server, you should set the proxy server URL, and if necessary, a pair of user name and password for the proxy server authentication (Basic/Digest), by using the `WebSocket.SetProxy (string, string, string)` method before connecting.
+
+```csharp
+var ws = new WebSocket ("ws://example.com");
+ws.SetProxy ("http://localhost:3128", "nobita", "password");
+```
+
+I have tested this with **[Squid]**. It's necessary to disable the following configuration option in **squid.conf** (e.g. `/etc/squid/squid.conf`).
+
+```
+# Deny CONNECT to other than SSL ports
+#http_access deny CONNECT !SSL_ports
+```
+
+### Logging ###
+
+The `WebSocket` class has the own logging function.
+
+You can use it with the `WebSocket.Log` property (returns a `WebSocketSharp.Logger`).
+
+So if you would like to change the current logging level (`WebSocketSharp.LogLevel.Error` as the default), you should set the `WebSocket.Log.Level` property to any of the `LogLevel` enum values.
+
+```csharp
+ws.Log.Level = LogLevel.Debug;
+```
+
+The above means a log with lower than `LogLevel.Debug` cannot be outputted.
+
+And if you would like to output a log, you should use any of the output methods. The following outputs a log with `LogLevel.Debug`.
+
+```csharp
+ws.Log.Debug ("This is a debug message.");
+```
+
+The `WebSocketServer` and `HttpServer` classes have the same logging function.
+
+## Examples ##
+
+Examples using websocket-sharp.
+
+### Example ###
+
+**[Example]** connects to the **[Echo server]** with the WebSocket.
+
+### Example2 ###
+
+**[Example2]** starts a WebSocket server.
+
+### Example3 ###
+
+**[Example3]** starts an HTTP server that allows to accept the WebSocket handshake requests.
+
+Would you access to [http://localhost:4649](http://localhost:4649) to do **WebSocket Echo Test** with your web browser while Example3 is running?
+
+## Supported WebSocket Specifications ##
+
+websocket-sharp supports **[RFC 6455][rfc6455]**, and it's based on the following WebSocket references:
+
+- **[The WebSocket Protocol][rfc6455]**
+- **[The WebSocket API][api]**
+- **[Compression Extensions for WebSocket][compression]**
+
+Thanks for translating to japanese.
+
+- **[The WebSocket Protocol 日本語訳][rfc6455_ja]**
+- **[The WebSocket API 日本語訳][api_ja]**
+
+## License ##
+
+websocket-sharp is provided under **[The MIT License]**.
+
+
+[Echo server]: http://www.websocket.org/echo.html
+[Example]: https://github.com/sta/websocket-sharp/tree/master/Example
+[Example2]: https://github.com/sta/websocket-sharp/tree/master/Example2
+[Example3]: https://github.com/sta/websocket-sharp/tree/master/Example3
+[Mono]: http://www.mono-project.com
+[MonoDevelop]: http://monodevelop.com
+[NuGet Gallery]: http://www.nuget.org
+[NuGet Gallery: websocket-sharp]: http://www.nuget.org/packages/WebSocketSharp
+[Origin]: http://tools.ietf.org/html/rfc6454#section-7
+[Query]: http://tools.ietf.org/html/rfc3986#section-3.4
+[Security Sandbox of the Webplayer]: http://docs.unity3d.com/Manual/SecuritySandbox.html
+[Squid]: http://www.squid-cache.org
+[The MIT License]: https://raw.github.com/sta/websocket-sharp/master/LICENSE.txt
+[Unity]: http://unity3d.com
+[WebGL Networking]: http://docs.unity3d.com/Manual/webgl-networking.html
+[WebSocket-Sharp for Unity]: http://u3d.as/content/sta-blockhead/websocket-sharp-for-unity
+[api]: http://www.w3.org/TR/websockets
+[api_ja]: http://www.hcn.zaq.ne.jp/___/WEB/WebSocket-ja.html
+[compression]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-19
+[context take over]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-19#section-8.1.1
+[rfc2617]: http://tools.ietf.org/html/rfc2617
+[rfc6455]: http://tools.ietf.org/html/rfc6455
+[rfc6455_ja]: http://www.hcn.zaq.ne.jp/___/WEB/RFC6455-ja.html
diff --git a/javascripts/main.js b/javascripts/main.js
new file mode 100644
index 000000000..d8135d37b
--- /dev/null
+++ b/javascripts/main.js
@@ -0,0 +1 @@
+console.log('This would be the main JS file.');
diff --git a/javascripts/respond.js b/javascripts/respond.js
new file mode 100644
index 000000000..76bc26048
--- /dev/null
+++ b/javascripts/respond.js
@@ -0,0 +1,779 @@
+if(typeof Object.create!=="function"){
+Object.create=function(o){
+function F(){
+};
+F.prototype=o;
+return new F();
+};
+}
+var ua={toString:function(){
+return navigator.userAgent;
+},test:function(s){
+return this.toString().toLowerCase().indexOf(s.toLowerCase())>-1;
+}};
+ua.version=(ua.toString().toLowerCase().match(/[\s\S]+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)||[])[1];
+ua.webkit=ua.test("webkit");
+ua.gecko=ua.test("gecko")&&!ua.webkit;
+ua.opera=ua.test("opera");
+ua.ie=ua.test("msie")&&!ua.opera;
+ua.ie6=ua.ie&&document.compatMode&&typeof document.documentElement.style.maxHeight==="undefined";
+ua.ie7=ua.ie&&document.documentElement&&typeof document.documentElement.style.maxHeight!=="undefined"&&typeof XDomainRequest==="undefined";
+ua.ie8=ua.ie&&typeof XDomainRequest!=="undefined";
+var domReady=function(){
+var _1=[];
+var _2=function(){
+if(!arguments.callee.done){
+arguments.callee.done=true;
+for(var i=0;i<_1.length;i++){
+_1[i]();
+}
+}
+};
+if(document.addEventListener){
+document.addEventListener("DOMContentLoaded",_2,false);
+}
+if(ua.ie){
+(function(){
+try{
+document.documentElement.doScroll("left");
+}
+catch(e){
+setTimeout(arguments.callee,50);
+return;
+}
+_2();
+})();
+document.onreadystatechange=function(){
+if(document.readyState==="complete"){
+document.onreadystatechange=null;
+_2();
+}
+};
+}
+if(ua.webkit&&document.readyState){
+(function(){
+if(document.readyState!=="loading"){
+_2();
+}else{
+setTimeout(arguments.callee,10);
+}
+})();
+}
+window.onload=_2;
+return function(fn){
+if(typeof fn==="function"){
+_1[_1.length]=fn;
+}
+return fn;
+};
+}();
+var cssHelper=function(){
+var _3={BLOCKS:/[^\s{][^{]*\{(?:[^{}]*\{[^{}]*\}[^{}]*|[^{}]*)*\}/g,BLOCKS_INSIDE:/[^\s{][^{]*\{[^{}]*\}/g,DECLARATIONS:/[a-zA-Z\-]+[^;]*:[^;]+;/g,RELATIVE_URLS:/url\(['"]?([^\/\)'"][^:\)'"]+)['"]?\)/g,REDUNDANT_COMPONENTS:/(?:\/\*([^*\\\\]|\*(?!\/))+\*\/|@import[^;]+;)/g,REDUNDANT_WHITESPACE:/\s*(,|:|;|\{|\})\s*/g,MORE_WHITESPACE:/\s{2,}/g,FINAL_SEMICOLONS:/;\}/g,NOT_WHITESPACE:/\S+/g};
+var _4,_5=false;
+var _6=[];
+var _7=function(fn){
+if(typeof fn==="function"){
+_6[_6.length]=fn;
+}
+};
+var _8=function(){
+for(var i=0;i<_6.length;i++){
+_6[i](_4);
+}
+};
+var _9={};
+var _a=function(n,v){
+if(_9[n]){
+var _b=_9[n].listeners;
+if(_b){
+for(var i=0;i<_b.length;i++){
+_b[i](v);
+}
+}
+}
+};
+var _c=function(_d,_e,_f){
+if(ua.ie&&!window.XMLHttpRequest){
+window.XMLHttpRequest=function(){
+return new ActiveXObject("Microsoft.XMLHTTP");
+};
+}
+if(!XMLHttpRequest){
+return "";
+}
+var r=new XMLHttpRequest();
+try{
+r.open("get",_d,true);
+r.setRequestHeader("X_REQUESTED_WITH","XMLHttpRequest");
+}
+catch(e){
+_f();
+return;
+}
+var _10=false;
+setTimeout(function(){
+_10=true;
+},5000);
+document.documentElement.style.cursor="progress";
+r.onreadystatechange=function(){
+if(r.readyState===4&&!_10){
+if(!r.status&&location.protocol==="file:"||(r.status>=200&&r.status<300)||r.status===304||navigator.userAgent.indexOf("Safari")>-1&&typeof r.status==="undefined"){
+_e(r.responseText);
+}else{
+_f();
+}
+document.documentElement.style.cursor="";
+r=null;
+}
+};
+r.send("");
+};
+var _11=function(_12){
+_12=_12.replace(_3.REDUNDANT_COMPONENTS,"");
+_12=_12.replace(_3.REDUNDANT_WHITESPACE,"$1");
+_12=_12.replace(_3.MORE_WHITESPACE," ");
+_12=_12.replace(_3.FINAL_SEMICOLONS,"}");
+return _12;
+};
+var _13={mediaQueryList:function(s){
+var o={};
+var idx=s.indexOf("{");
+var lt=s.substring(0,idx);
+s=s.substring(idx+1,s.length-1);
+var mqs=[],rs=[];
+var qts=lt.toLowerCase().substring(7).split(",");
+for(var i=0;i-1&&_23.href&&_23.href.length!==0&&!_23.disabled){
+_1f[_1f.length]=_23;
+}
+}
+if(_1f.length>0){
+var c=0;
+var _24=function(){
+c++;
+if(c===_1f.length){
+_20();
+}
+};
+var _25=function(_26){
+var _27=_26.href;
+_c(_27,function(_28){
+_28=_11(_28).replace(_3.RELATIVE_URLS,"url("+_27.substring(0,_27.lastIndexOf("/"))+"/$1)");
+_26.cssHelperText=_28;
+_24();
+},_24);
+};
+for(i=0;i<_1f.length;i++){
+_25(_1f[i]);
+}
+}else{
+_20();
+}
+};
+var _29={mediaQueryLists:"array",rules:"array",selectors:"object",declarations:"array",properties:"object"};
+var _2a={mediaQueryLists:null,rules:null,selectors:null,declarations:null,properties:null};
+var _2b=function(_2c,v){
+if(_2a[_2c]!==null){
+if(_29[_2c]==="array"){
+return (_2a[_2c]=_2a[_2c].concat(v));
+}else{
+var c=_2a[_2c];
+for(var n in v){
+if(v.hasOwnProperty(n)){
+if(!c[n]){
+c[n]=v[n];
+}else{
+c[n]=c[n].concat(v[n]);
+}
+}
+}
+return c;
+}
+}
+};
+var _2d=function(_2e){
+_2a[_2e]=(_29[_2e]==="array")?[]:{};
+for(var i=0;i<_4.length;i++){
+_2b(_2e,_4[i].cssHelperParsed[_2e]);
+}
+return _2a[_2e];
+};
+domReady(function(){
+var els=document.body.getElementsByTagName("*");
+for(var i=0;i=_44)||(max&&_46<_44)||(!min&&!max&&_46===_44));
+}else{
+return false;
+}
+}else{
+return _46>0;
+}
+}else{
+if("device-height"===_41.substring(l-13,l)){
+_47=screen.height;
+if(_42!==null){
+if(_43==="length"){
+return ((min&&_47>=_44)||(max&&_47<_44)||(!min&&!max&&_47===_44));
+}else{
+return false;
+}
+}else{
+return _47>0;
+}
+}else{
+if("width"===_41.substring(l-5,l)){
+_46=document.documentElement.clientWidth||document.body.clientWidth;
+if(_42!==null){
+if(_43==="length"){
+return ((min&&_46>=_44)||(max&&_46<_44)||(!min&&!max&&_46===_44));
+}else{
+return false;
+}
+}else{
+return _46>0;
+}
+}else{
+if("height"===_41.substring(l-6,l)){
+_47=document.documentElement.clientHeight||document.body.clientHeight;
+if(_42!==null){
+if(_43==="length"){
+return ((min&&_47>=_44)||(max&&_47<_44)||(!min&&!max&&_47===_44));
+}else{
+return false;
+}
+}else{
+return _47>0;
+}
+}else{
+if("device-aspect-ratio"===_41.substring(l-19,l)){
+return _43==="aspect-ratio"&&screen.width*_44[1]===screen.height*_44[0];
+}else{
+if("color-index"===_41.substring(l-11,l)){
+var _48=Math.pow(2,screen.colorDepth);
+if(_42!==null){
+if(_43==="absolute"){
+return ((min&&_48>=_44)||(max&&_48<_44)||(!min&&!max&&_48===_44));
+}else{
+return false;
+}
+}else{
+return _48>0;
+}
+}else{
+if("color"===_41.substring(l-5,l)){
+var _49=screen.colorDepth;
+if(_42!==null){
+if(_43==="absolute"){
+return ((min&&_49>=_44)||(max&&_49<_44)||(!min&&!max&&_49===_44));
+}else{
+return false;
+}
+}else{
+return _49>0;
+}
+}else{
+if("resolution"===_41.substring(l-10,l)){
+var res;
+if(_45==="dpcm"){
+res=_3d("1cm");
+}else{
+res=_3d("1in");
+}
+if(_42!==null){
+if(_43==="resolution"){
+return ((min&&res>=_44)||(max&&res<_44)||(!min&&!max&&res===_44));
+}else{
+return false;
+}
+}else{
+return res>0;
+}
+}else{
+return false;
+}
+}
+}
+}
+}
+}
+}
+}
+};
+var _4a=function(mq){
+var _4b=mq.getValid();
+var _4c=mq.getExpressions();
+var l=_4c.length;
+if(l>0){
+for(var i=0;i0){
+s[c++]=",";
+}
+s[c++]=n;
+}
+}
+if(s.length>0){
+_39[_39.length]=cssHelper.addStyle("@media "+s.join("")+"{"+mql.getCssText()+"}",false);
+}
+};
+var _4e=function(_4f){
+for(var i=0;i<_4f.length;i++){
+_4d(_4f[i]);
+}
+if(ua.ie){
+document.documentElement.style.display="block";
+setTimeout(function(){
+document.documentElement.style.display="";
+},0);
+setTimeout(function(){
+cssHelper.broadcast("cssMediaQueriesTested");
+},100);
+}else{
+cssHelper.broadcast("cssMediaQueriesTested");
+}
+};
+var _50=function(){
+for(var i=0;i<_39.length;i++){
+cssHelper.removeStyle(_39[i]);
+}
+_39=[];
+cssHelper.mediaQueryLists(_4e);
+};
+var _51=0;
+var _52=function(){
+var _53=cssHelper.getViewportWidth();
+var _54=cssHelper.getViewportHeight();
+if(ua.ie){
+var el=document.createElement("div");
+el.style.position="absolute";
+el.style.top="-9999em";
+el.style.overflow="scroll";
+document.body.appendChild(el);
+_51=el.offsetWidth-el.clientWidth;
+document.body.removeChild(el);
+}
+var _55;
+var _56=function(){
+var vpw=cssHelper.getViewportWidth();
+var vph=cssHelper.getViewportHeight();
+if(Math.abs(vpw-_53)>_51||Math.abs(vph-_54)>_51){
+_53=vpw;
+_54=vph;
+clearTimeout(_55);
+_55=setTimeout(function(){
+if(!_3a()){
+_50();
+}else{
+cssHelper.broadcast("cssMediaQueriesTested");
+}
+},500);
+}
+};
+window.onresize=function(){
+var x=window.onresize||function(){
+};
+return function(){
+x();
+_56();
+};
+}();
+};
+var _57=document.documentElement;
+_57.style.marginLeft="-32767px";
+setTimeout(function(){
+_57.style.marginTop="";
+},20000);
+return function(){
+if(!_3a()){
+cssHelper.addListener("newStyleParsed",function(el){
+_4e(el.cssHelperParsed.mediaQueryLists);
+});
+cssHelper.addListener("cssMediaQueriesTested",function(){
+if(ua.ie){
+_57.style.width="1px";
+}
+setTimeout(function(){
+_57.style.width="";
+_57.style.marginLeft="";
+},0);
+cssHelper.removeListener("cssMediaQueriesTested",arguments.callee);
+});
+_3c();
+_50();
+}else{
+_57.style.marginLeft="";
+}
+_52();
+};
+}());
+try{
+document.execCommand("BackgroundImageCache",false,true);
+}
+catch(e){
+}
+
diff --git a/javascripts/scale.fix.js b/javascripts/scale.fix.js
new file mode 100644
index 000000000..08716c006
--- /dev/null
+++ b/javascripts/scale.fix.js
@@ -0,0 +1,20 @@
+fixScale = function(doc) {
+
+ var addEvent = 'addEventListener',
+ type = 'gesturestart',
+ qsa = 'querySelectorAll',
+ scales = [1, 1],
+ meta = qsa in doc ? doc[qsa]('meta[name=viewport]') : [];
+
+ function fix() {
+ meta.content = 'width=device-width,minimum-scale=' + scales[0] + ',maximum-scale=' + scales[1];
+ doc.removeEventListener(type, fix, true);
+ }
+
+ if ((meta = meta[meta.length - 1]) && addEvent in doc) {
+ fix();
+ scales = [.25, 1.6];
+ doc[addEvent](type, fix, true);
+ }
+
+};
\ No newline at end of file
diff --git a/stylesheets/github-light.css b/stylesheets/github-light.css
new file mode 100644
index 000000000..0c6b24d82
--- /dev/null
+++ b/stylesheets/github-light.css
@@ -0,0 +1,124 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 GitHub, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+*/
+
+.pl-c /* comment */ {
+ color: #969896;
+}
+
+.pl-c1 /* constant, variable.other.constant, support, meta.property-name, support.constant, support.variable, meta.module-reference, markup.raw, meta.diff.header */,
+.pl-s .pl-v /* string variable */ {
+ color: #0086b3;
+}
+
+.pl-e /* entity */,
+.pl-en /* entity.name */ {
+ color: #795da3;
+}
+
+.pl-smi /* variable.parameter.function, storage.modifier.package, storage.modifier.import, storage.type.java, variable.other */,
+.pl-s .pl-s1 /* string source */ {
+ color: #333;
+}
+
+.pl-ent /* entity.name.tag */ {
+ color: #63a35c;
+}
+
+.pl-k /* keyword, storage, storage.type */ {
+ color: #a71d5d;
+}
+
+.pl-s /* string */,
+.pl-pds /* punctuation.definition.string, string.regexp.character-class */,
+.pl-s .pl-pse .pl-s1 /* string punctuation.section.embedded source */,
+.pl-sr /* string.regexp */,
+.pl-sr .pl-cce /* string.regexp constant.character.escape */,
+.pl-sr .pl-sre /* string.regexp source.ruby.embedded */,
+.pl-sr .pl-sra /* string.regexp string.regexp.arbitrary-repitition */ {
+ color: #183691;
+}
+
+.pl-v /* variable */ {
+ color: #ed6a43;
+}
+
+.pl-id /* invalid.deprecated */ {
+ color: #b52a1d;
+}
+
+.pl-ii /* invalid.illegal */ {
+ color: #f8f8f8;
+ background-color: #b52a1d;
+}
+
+.pl-sr .pl-cce /* string.regexp constant.character.escape */ {
+ font-weight: bold;
+ color: #63a35c;
+}
+
+.pl-ml /* markup.list */ {
+ color: #693a17;
+}
+
+.pl-mh /* markup.heading */,
+.pl-mh .pl-en /* markup.heading entity.name */,
+.pl-ms /* meta.separator */ {
+ font-weight: bold;
+ color: #1d3e81;
+}
+
+.pl-mq /* markup.quote */ {
+ color: #008080;
+}
+
+.pl-mi /* markup.italic */ {
+ font-style: italic;
+ color: #333;
+}
+
+.pl-mb /* markup.bold */ {
+ font-weight: bold;
+ color: #333;
+}
+
+.pl-md /* markup.deleted, meta.diff.header.from-file */ {
+ color: #bd2c00;
+ background-color: #ffecec;
+}
+
+.pl-mi1 /* markup.inserted, meta.diff.header.to-file */ {
+ color: #55a532;
+ background-color: #eaffea;
+}
+
+.pl-mdr /* meta.diff.range */ {
+ font-weight: bold;
+ color: #795da3;
+}
+
+.pl-mo /* meta.output */ {
+ color: #1d3e81;
+}
+
diff --git a/stylesheets/ie.css b/stylesheets/ie.css
new file mode 100644
index 000000000..43882f2ee
--- /dev/null
+++ b/stylesheets/ie.css
@@ -0,0 +1,3 @@
+nav {
+ display: none;
+}
diff --git a/stylesheets/normalize.css b/stylesheets/normalize.css
new file mode 100644
index 000000000..30366a6e9
--- /dev/null
+++ b/stylesheets/normalize.css
@@ -0,0 +1,424 @@
+/*! normalize.css v3.0.2 | MIT License | git.io/normalize */
+
+/**
+ * 1. Set default font family to sans-serif.
+ * 2. Prevent iOS text size adjust after orientation change, without disabling
+ * user zoom.
+ */
+
+html {
+ font-family: sans-serif; /* 1 */
+ -ms-text-size-adjust: 100%; /* 2 */
+ -webkit-text-size-adjust: 100%; /* 2 */
+}
+
+/**
+ * Remove default margin.
+ */
+
+body {
+ margin: 0;
+}
+
+/* HTML5 display definitions
+ ========================================================================== */
+
+/**
+ * Correct `block` display not defined for any HTML5 element in IE 8/9.
+ * Correct `block` display not defined for `details` or `summary` in IE 10/11
+ * and Firefox.
+ * Correct `block` display not defined for `main` in IE 11.
+ */
+
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+main,
+menu,
+nav,
+section,
+summary {
+ display: block;
+}
+
+/**
+ * 1. Correct `inline-block` display not defined in IE 8/9.
+ * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
+ */
+
+audio,
+canvas,
+progress,
+video {
+ display: inline-block; /* 1 */
+ vertical-align: baseline; /* 2 */
+}
+
+/**
+ * Prevent modern browsers from displaying `audio` without controls.
+ * Remove excess height in iOS 5 devices.
+ */
+
+audio:not([controls]) {
+ display: none;
+ height: 0;
+}
+
+/**
+ * Address `[hidden]` styling not present in IE 8/9/10.
+ * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22.
+ */
+
+[hidden],
+template {
+ display: none;
+}
+
+/* Links
+ ========================================================================== */
+
+/**
+ * Remove the gray background color from active links in IE 10.
+ */
+
+a {
+ background-color: transparent;
+}
+
+/**
+ * Improve readability when focused and also mouse hovered in all browsers.
+ */
+
+a:active,
+a:hover {
+ outline: 0;
+}
+
+/* Text-level semantics
+ ========================================================================== */
+
+/**
+ * Address styling not present in IE 8/9/10/11, Safari, and Chrome.
+ */
+
+abbr[title] {
+ border-bottom: 1px dotted;
+}
+
+/**
+ * Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
+ */
+
+b,
+strong {
+ font-weight: bold;
+}
+
+/**
+ * Address styling not present in Safari and Chrome.
+ */
+
+dfn {
+ font-style: italic;
+}
+
+/**
+ * Address variable `h1` font-size and margin within `section` and `article`
+ * contexts in Firefox 4+, Safari, and Chrome.
+ */
+
+h1 {
+ font-size: 2em;
+ margin: 0.67em 0;
+}
+
+/**
+ * Address styling not present in IE 8/9.
+ */
+
+mark {
+ background: #ff0;
+ color: #000;
+}
+
+/**
+ * Address inconsistent and variable font size in all browsers.
+ */
+
+small {
+ font-size: 80%;
+}
+
+/**
+ * Prevent `sub` and `sup` affecting `line-height` in all browsers.
+ */
+
+sub,
+sup {
+ font-size: 75%;
+ line-height: 0;
+ position: relative;
+ vertical-align: baseline;
+}
+
+sup {
+ top: -0.5em;
+}
+
+sub {
+ bottom: -0.25em;
+}
+
+/* Embedded content
+ ========================================================================== */
+
+/**
+ * Remove border when inside `a` element in IE 8/9/10.
+ */
+
+img {
+ border: 0;
+}
+
+/**
+ * Correct overflow not hidden in IE 9/10/11.
+ */
+
+svg:not(:root) {
+ overflow: hidden;
+}
+
+/* Grouping content
+ ========================================================================== */
+
+/**
+ * Address margin not present in IE 8/9 and Safari.
+ */
+
+figure {
+ margin: 1em 40px;
+}
+
+/**
+ * Address differences between Firefox and other browsers.
+ */
+
+hr {
+ box-sizing: content-box;
+ height: 0;
+}
+
+/**
+ * Contain overflow in all browsers.
+ */
+
+pre {
+ overflow: auto;
+}
+
+/**
+ * Address odd `em`-unit font size rendering in all browsers.
+ */
+
+code,
+kbd,
+pre,
+samp {
+ font-family: monospace, monospace;
+ font-size: 1em;
+}
+
+/* Forms
+ ========================================================================== */
+
+/**
+ * Known limitation: by default, Chrome and Safari on OS X allow very limited
+ * styling of `select`, unless a `border` property is set.
+ */
+
+/**
+ * 1. Correct color not being inherited.
+ * Known issue: affects color of disabled elements.
+ * 2. Correct font properties not being inherited.
+ * 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
+ */
+
+button,
+input,
+optgroup,
+select,
+textarea {
+ color: inherit; /* 1 */
+ font: inherit; /* 2 */
+ margin: 0; /* 3 */
+}
+
+/**
+ * Address `overflow` set to `hidden` in IE 8/9/10/11.
+ */
+
+button {
+ overflow: visible;
+}
+
+/**
+ * Address inconsistent `text-transform` inheritance for `button` and `select`.
+ * All other form control elements do not inherit `text-transform` values.
+ * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
+ * Correct `select` style inheritance in Firefox.
+ */
+
+button,
+select {
+ text-transform: none;
+}
+
+/**
+ * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
+ * and `video` controls.
+ * 2. Correct inability to style clickable `input` types in iOS.
+ * 3. Improve usability and consistency of cursor style between image-type
+ * `input` and others.
+ */
+
+button,
+html input[type="button"], /* 1 */
+input[type="reset"],
+input[type="submit"] {
+ -webkit-appearance: button; /* 2 */
+ cursor: pointer; /* 3 */
+}
+
+/**
+ * Re-set default cursor for disabled elements.
+ */
+
+button[disabled],
+html input[disabled] {
+ cursor: default;
+}
+
+/**
+ * Remove inner padding and border in Firefox 4+.
+ */
+
+button::-moz-focus-inner,
+input::-moz-focus-inner {
+ border: 0;
+ padding: 0;
+}
+
+/**
+ * Address Firefox 4+ setting `line-height` on `input` using `!important` in
+ * the UA stylesheet.
+ */
+
+input {
+ line-height: normal;
+}
+
+/**
+ * It's recommended that you don't attempt to style these elements.
+ * Firefox's implementation doesn't respect box-sizing, padding, or width.
+ *
+ * 1. Address box sizing set to `content-box` in IE 8/9/10.
+ * 2. Remove excess padding in IE 8/9/10.
+ */
+
+input[type="checkbox"],
+input[type="radio"] {
+ box-sizing: border-box; /* 1 */
+ padding: 0; /* 2 */
+}
+
+/**
+ * Fix the cursor style for Chrome's increment/decrement buttons. For certain
+ * `font-size` values of the `input`, it causes the cursor style of the
+ * decrement button to change from `default` to `text`.
+ */
+
+input[type="number"]::-webkit-inner-spin-button,
+input[type="number"]::-webkit-outer-spin-button {
+ height: auto;
+}
+
+/**
+ * 1. Address `appearance` set to `searchfield` in Safari and Chrome.
+ * 2. Address `box-sizing` set to `border-box` in Safari and Chrome
+ * (include `-moz` to future-proof).
+ */
+
+input[type="search"] {
+ -webkit-appearance: textfield; /* 1 */ /* 2 */
+ box-sizing: content-box;
+}
+
+/**
+ * Remove inner padding and search cancel button in Safari and Chrome on OS X.
+ * Safari (but not Chrome) clips the cancel button when the search input has
+ * padding (and `textfield` appearance).
+ */
+
+input[type="search"]::-webkit-search-cancel-button,
+input[type="search"]::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+
+/**
+ * Define consistent border, margin, and padding.
+ */
+
+fieldset {
+ border: 1px solid #c0c0c0;
+ margin: 0 2px;
+ padding: 0.35em 0.625em 0.75em;
+}
+
+/**
+ * 1. Correct `color` not being inherited in IE 8/9/10/11.
+ * 2. Remove padding so people aren't caught out if they zero out fieldsets.
+ */
+
+legend {
+ border: 0; /* 1 */
+ padding: 0; /* 2 */
+}
+
+/**
+ * Remove default vertical scrollbar in IE 8/9/10/11.
+ */
+
+textarea {
+ overflow: auto;
+}
+
+/**
+ * Don't inherit the `font-weight` (applied by a rule above).
+ * NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
+ */
+
+optgroup {
+ font-weight: bold;
+}
+
+/* Tables
+ ========================================================================== */
+
+/**
+ * Remove most spacing between table cells.
+ */
+
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+
+td,
+th {
+ padding: 0;
+}
diff --git a/stylesheets/print.css b/stylesheets/print.css
new file mode 100644
index 000000000..541695bfd
--- /dev/null
+++ b/stylesheets/print.css
@@ -0,0 +1,226 @@
+html, body, div, span, applet, object, iframe,
+h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+a, abbr, acronym, address, big, cite, code,
+del, dfn, em, img, ins, kbd, q, s, samp,
+small, strike, strong, sub, sup, tt, var,
+b, u, i, center,
+dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td,
+article, aside, canvas, details, embed,
+figure, figcaption, footer, header, hgroup,
+menu, nav, output, ruby, section, summary,
+time, mark, audio, video {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ font-size: 100%;
+ font: inherit;
+ vertical-align: baseline;
+}
+/* HTML5 display-role reset for older browsers */
+article, aside, details, figcaption, figure,
+footer, header, hgroup, menu, nav, section {
+ display: block;
+}
+body {
+ line-height: 1;
+}
+ol, ul {
+ list-style: none;
+}
+blockquote, q {
+ quotes: none;
+}
+blockquote:before, blockquote:after,
+q:before, q:after {
+ content: '';
+ content: none;
+}
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+body {
+ font-size: 13px;
+ line-height: 1.5;
+ font-family: 'Helvetica Neue', Helvetica, Arial, serif;
+ color: #000;
+}
+
+a {
+ color: #d5000d;
+ font-weight: bold;
+}
+
+header {
+ padding-top: 35px;
+ padding-bottom: 10px;
+}
+
+header h1 {
+ font-weight: bold;
+ letter-spacing: -1px;
+ font-size: 48px;
+ color: #303030;
+ line-height: 1.2;
+}
+
+header h2 {
+ letter-spacing: -1px;
+ font-size: 24px;
+ color: #aaa;
+ font-weight: normal;
+ line-height: 1.3;
+}
+#downloads {
+ display: none;
+}
+#main_content {
+ padding-top: 20px;
+}
+
+code, pre {
+ font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal;
+ color: #222;
+ margin-bottom: 30px;
+ font-size: 12px;
+}
+
+code {
+ padding: 0 3px;
+}
+
+pre {
+ border: solid 1px #ddd;
+ padding: 20px;
+ overflow: auto;
+}
+pre code {
+ padding: 0;
+}
+
+ul, ol, dl {
+ margin-bottom: 20px;
+}
+
+
+/* COMMON STYLES */
+
+table {
+ width: 100%;
+ border: 1px solid #ebebeb;
+}
+
+th {
+ font-weight: 500;
+}
+
+td {
+ border: 1px solid #ebebeb;
+ text-align: center;
+ font-weight: 300;
+}
+
+form {
+ background: #f2f2f2;
+ padding: 20px;
+
+}
+
+
+/* GENERAL ELEMENT TYPE STYLES */
+
+h1 {
+ font-size: 2.8em;
+}
+
+h2 {
+ font-size: 22px;
+ font-weight: bold;
+ color: #303030;
+ margin-bottom: 8px;
+}
+
+h3 {
+ color: #d5000d;
+ font-size: 18px;
+ font-weight: bold;
+ margin-bottom: 8px;
+}
+
+h4 {
+ font-size: 16px;
+ color: #303030;
+ font-weight: bold;
+}
+
+h5 {
+ font-size: 1em;
+ color: #303030;
+}
+
+h6 {
+ font-size: .8em;
+ color: #303030;
+}
+
+p {
+ font-weight: 300;
+ margin-bottom: 20px;
+}
+
+a {
+ text-decoration: none;
+}
+
+p a {
+ font-weight: 400;
+}
+
+blockquote {
+ font-size: 1.6em;
+ border-left: 10px solid #e9e9e9;
+ margin-bottom: 20px;
+ padding: 0 0 0 30px;
+}
+
+ul li {
+ list-style: disc inside;
+ padding-left: 20px;
+}
+
+ol li {
+ list-style: decimal inside;
+ padding-left: 3px;
+}
+
+dl dd {
+ font-style: italic;
+ font-weight: 100;
+}
+
+footer {
+ margin-top: 40px;
+ padding-top: 20px;
+ padding-bottom: 30px;
+ font-size: 13px;
+ color: #aaa;
+}
+
+footer a {
+ color: #666;
+}
+
+/* MISC */
+.clearfix:after {
+ clear: both;
+ content: '.';
+ display: block;
+ visibility: hidden;
+ height: 0;
+}
+
+.clearfix {display: inline-block;}
+* html .clearfix {height: 1%;}
+.clearfix {display: block;}
\ No newline at end of file
diff --git a/stylesheets/pygment_trac.css b/stylesheets/pygment_trac.css
new file mode 100644
index 000000000..c79bef456
--- /dev/null
+++ b/stylesheets/pygment_trac.css
@@ -0,0 +1,70 @@
+.highlight .hll { background-color: #404040 }
+.highlight { color: #d0d0d0 }
+.highlight .c { color: #999999; font-style: italic } /* Comment */
+.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
+.highlight .g { color: #d0d0d0 } /* Generic */
+.highlight .k { color: #6ab825; font-weight: normal } /* Keyword */
+.highlight .l { color: #d0d0d0 } /* Literal */
+.highlight .n { color: #d0d0d0 } /* Name */
+.highlight .o { color: #d0d0d0 } /* Operator */
+.highlight .x { color: #d0d0d0 } /* Other */
+.highlight .p { color: #d0d0d0 } /* Punctuation */
+.highlight .cm { color: #999999; font-style: italic } /* Comment.Multiline */
+.highlight .cp { color: #cd2828; font-weight: normal } /* Comment.Preproc */
+.highlight .c1 { color: #999999; font-style: italic } /* Comment.Single */
+.highlight .cs { color: #e50808; font-weight: normal; background-color: #520000 } /* Comment.Special */
+.highlight .gd { color: #d22323 } /* Generic.Deleted */
+.highlight .ge { color: #d0d0d0; font-style: italic } /* Generic.Emph */
+.highlight .gr { color: #d22323 } /* Generic.Error */
+.highlight .gh { color: #ffffff; font-weight: normal } /* Generic.Heading */
+.highlight .gi { color: #589819 } /* Generic.Inserted */
+.highlight .go { color: #cccccc } /* Generic.Output */
+.highlight .gp { color: #aaaaaa } /* Generic.Prompt */
+.highlight .gs { color: #d0d0d0; font-weight: normal } /* Generic.Strong */
+.highlight .gu { color: #ffffff; text-decoration: underline } /* Generic.Subheading */
+.highlight .gt { color: #d22323 } /* Generic.Traceback */
+.highlight .kc { color: #6ab825; font-weight: normal } /* Keyword.Constant */
+.highlight .kd { color: #6ab825; font-weight: normal } /* Keyword.Declaration */
+.highlight .kn { color: #6ab825; font-weight: normal } /* Keyword.Namespace */
+.highlight .kp { color: #6ab825 } /* Keyword.Pseudo */
+.highlight .kr { color: #6ab825; font-weight: normal } /* Keyword.Reserved */
+.highlight .kt { color: #6ab825; font-weight: normal } /* Keyword.Type */
+.highlight .ld { color: #d0d0d0 } /* Literal.Date */
+.highlight .m { color: #3677a9 } /* Literal.Number */
+.highlight .s { color: #9dd5f1 } /* Literal.String */
+.highlight .na { color: #bbbbbb } /* Name.Attribute */
+.highlight .nb { color: #24909d } /* Name.Builtin */
+.highlight .nc { color: #447fcf; text-decoration: underline } /* Name.Class */
+.highlight .no { color: #40ffff } /* Name.Constant */
+.highlight .nd { color: #ffa500 } /* Name.Decorator */
+.highlight .ni { color: #d0d0d0 } /* Name.Entity */
+.highlight .ne { color: #bbbbbb } /* Name.Exception */
+.highlight .nf { color: #447fcf } /* Name.Function */
+.highlight .nl { color: #d0d0d0 } /* Name.Label */
+.highlight .nn { color: #447fcf; text-decoration: underline } /* Name.Namespace */
+.highlight .nx { color: #d0d0d0 } /* Name.Other */
+.highlight .py { color: #d0d0d0 } /* Name.Property */
+.highlight .nt { color: #6ab825;} /* Name.Tag */
+.highlight .nv { color: #40ffff } /* Name.Variable */
+.highlight .ow { color: #6ab825; font-weight: normal } /* Operator.Word */
+.highlight .w { color: #666666 } /* Text.Whitespace */
+.highlight .mf { color: #3677a9 } /* Literal.Number.Float */
+.highlight .mh { color: #3677a9 } /* Literal.Number.Hex */
+.highlight .mi { color: #3677a9 } /* Literal.Number.Integer */
+.highlight .mo { color: #3677a9 } /* Literal.Number.Oct */
+.highlight .sb { color: #9dd5f1 } /* Literal.String.Backtick */
+.highlight .sc { color: #9dd5f1 } /* Literal.String.Char */
+.highlight .sd { color: #9dd5f1 } /* Literal.String.Doc */
+.highlight .s2 { color: #9dd5f1 } /* Literal.String.Double */
+.highlight .se { color: #9dd5f1 } /* Literal.String.Escape */
+.highlight .sh { color: #9dd5f1 } /* Literal.String.Heredoc */
+.highlight .si { color: #9dd5f1 } /* Literal.String.Interpol */
+.highlight .sx { color: #ffa500 } /* Literal.String.Other */
+.highlight .sr { color: #9dd5f1 } /* Literal.String.Regex */
+.highlight .s1 { color: #9dd5f1 } /* Literal.String.Single */
+.highlight .ss { color: #9dd5f1 } /* Literal.String.Symbol */
+.highlight .bp { color: #24909d } /* Name.Builtin.Pseudo */
+.highlight .vc { color: #40ffff } /* Name.Variable.Class */
+.highlight .vg { color: #40ffff } /* Name.Variable.Global */
+.highlight .vi { color: #40ffff } /* Name.Variable.Instance */
+.highlight .il { color: #3677a9 } /* Literal.Number.Integer.Long */
\ No newline at end of file
diff --git a/stylesheets/styles.css b/stylesheets/styles.css
new file mode 100644
index 000000000..e7b4ffccd
--- /dev/null
+++ b/stylesheets/styles.css
@@ -0,0 +1,851 @@
+@font-face {
+ font-family: 'OpenSansLight';
+ src: url("../fonts/OpenSans-Light-webfont.eot");
+ src: url("../fonts/OpenSans-Light-webfont.eot?#iefix") format("embedded-opentype"), url("../fonts/OpenSans-Light-webfont.woff") format("woff"), url("../fonts/OpenSans-Light-webfont.ttf") format("truetype"), url("../fonts/OpenSans-Light-webfont.svg#OpenSansLight") format("svg");
+ font-weight: normal;
+ font-style: normal;
+}
+
+@font-face {
+ font-family: 'OpenSansLightItalic';
+ src: url("../fonts/OpenSans-LightItalic-webfont.eot");
+ src: url("../fonts/OpenSans-LightItalic-webfont.eot?#iefix") format("embedded-opentype"), url("../fonts/OpenSans-LightItalic-webfont.woff") format("woff"), url("../fonts/OpenSans-LightItalic-webfont.ttf") format("truetype"), url("../fonts/OpenSans-LightItalic-webfont.svg#OpenSansLightItalic") format("svg");
+ font-weight: normal;
+ font-style: normal;
+}
+
+@font-face {
+ font-family: 'OpenSansRegular';
+ src: url("../fonts/OpenSans-Regular-webfont.eot");
+ src: url("../fonts/OpenSans-Regular-webfont.eot?#iefix") format("embedded-opentype"), url("../fonts/OpenSans-Regular-webfont.woff") format("woff"), url("../fonts/OpenSans-Regular-webfont.ttf") format("truetype"), url("../fonts/OpenSans-Regular-webfont.svg#OpenSansRegular") format("svg");
+ font-weight: normal;
+ font-style: normal;
+ -webkit-font-smoothing: antialiased;
+}
+
+@font-face {
+ font-family: 'OpenSansItalic';
+ src: url("../fonts/OpenSans-Italic-webfont.eot");
+ src: url("../fonts/OpenSans-Italic-webfont.eot?#iefix") format("embedded-opentype"), url("../fonts/OpenSans-Italic-webfont.woff") format("woff"), url("../fonts/OpenSans-Italic-webfont.ttf") format("truetype"), url("../fonts/OpenSans-Italic-webfont.svg#OpenSansItalic") format("svg");
+ font-weight: normal;
+ font-style: normal;
+ -webkit-font-smoothing: antialiased;
+}
+
+@font-face {
+ font-family: 'OpenSansSemibold';
+ src: url("../fonts/OpenSans-Semibold-webfont.eot");
+ src: url("../fonts/OpenSans-Semibold-webfont.eot?#iefix") format("embedded-opentype"), url("../fonts/OpenSans-Semibold-webfont.woff") format("woff"), url("../fonts/OpenSans-Semibold-webfont.ttf") format("truetype"), url("../fonts/OpenSans-Semibold-webfont.svg#OpenSansSemibold") format("svg");
+ font-weight: normal;
+ font-style: normal;
+ -webkit-font-smoothing: antialiased;
+}
+
+@font-face {
+ font-family: 'OpenSansSemiboldItalic';
+ src: url("../fonts/OpenSans-SemiboldItalic-webfont.eot");
+ src: url("../fonts/OpenSans-SemiboldItalic-webfont.eot?#iefix") format("embedded-opentype"), url("../fonts/OpenSans-SemiboldItalic-webfont.woff") format("woff"), url("../fonts/OpenSans-SemiboldItalic-webfont.ttf") format("truetype"), url("../fonts/OpenSans-SemiboldItalic-webfont.svg#OpenSansSemiboldItalic") format("svg");
+ font-weight: normal;
+ font-style: normal;
+ -webkit-font-smoothing: antialiased;
+}
+
+@font-face {
+ font-family: 'OpenSansBold';
+ src: url("../fonts/OpenSans-Bold-webfont.eot");
+ src: url("../fonts/OpenSans-Bold-webfont.eot?#iefix") format("embedded-opentype"), url("../fonts/OpenSans-Bold-webfont.woff") format("woff"), url("../fonts/OpenSans-Bold-webfont.ttf") format("truetype"), url("../fonts/OpenSans-Bold-webfont.svg#OpenSansBold") format("svg");
+ font-weight: normal;
+ font-style: normal;
+ -webkit-font-smoothing: antialiased;
+}
+
+@font-face {
+ font-family: 'OpenSansBoldItalic';
+ src: url("../fonts/OpenSans-BoldItalic-webfont.eot");
+ src: url("../fonts/OpenSans-BoldItalic-webfont.eot?#iefix") format("embedded-opentype"), url("../fonts/OpenSans-BoldItalic-webfont.woff") format("woff"), url("../fonts/OpenSans-BoldItalic-webfont.ttf") format("truetype"), url("../fonts/OpenSans-BoldItalic-webfont.svg#OpenSansBoldItalic") format("svg");
+ font-weight: normal;
+ font-style: normal;
+ -webkit-font-smoothing: antialiased;
+}
+
+/* normalize.css 2012-02-07T12:37 UTC - http://github.com/necolas/normalize.css */
+/* =============================================================================
+ HTML5 display definitions
+ ========================================================================== */
+/*
+ * Corrects block display not defined in IE6/7/8/9 & FF3
+ */
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+nav,
+section,
+summary {
+ display: block;
+}
+
+/*
+ * Corrects inline-block display not defined in IE6/7/8/9 & FF3
+ */
+audio,
+canvas,
+video {
+ display: inline-block;
+ *display: inline;
+ *zoom: 1;
+}
+
+/*
+ * Prevents modern browsers from displaying 'audio' without controls
+ */
+audio:not([controls]) {
+ display: none;
+}
+
+/*
+ * Addresses styling for 'hidden' attribute not present in IE7/8/9, FF3, S4
+ * Known issue: no IE6 support
+ */
+[hidden] {
+ display: none;
+}
+
+/* =============================================================================
+ Base
+ ========================================================================== */
+/*
+ * 1. Corrects text resizing oddly in IE6/7 when body font-size is set using em units
+ * http://clagnut.com/blog/348/#c790
+ * 2. Prevents iOS text size adjust after orientation change, without disabling user zoom
+ * www.456bereastreet.com/archive/201012/controlling_text_size_in_safari_for_ios_without_disabling_user_zoom/
+ */
+html {
+ font-size: 100%;
+ /* 1 */
+ -webkit-text-size-adjust: 100%;
+ /* 2 */
+ -ms-text-size-adjust: 100%;
+ /* 2 */
+}
+
+/*
+ * Addresses font-family inconsistency between 'textarea' and other form elements.
+ */
+html,
+button,
+input,
+select,
+textarea {
+ font-family: sans-serif;
+}
+
+/*
+ * Addresses margins handled incorrectly in IE6/7
+ */
+body {
+ margin: 0;
+}
+
+/* =============================================================================
+ Links
+ ========================================================================== */
+/*
+ * Addresses outline displayed oddly in Chrome
+ */
+a:focus {
+ outline: thin dotted;
+}
+
+/*
+ * Improves readability when focused and also mouse hovered in all browsers
+ * people.opera.com/patrickl/experiments/keyboard/test
+ */
+a:hover,
+a:active {
+ outline: 0;
+}
+
+/* =============================================================================
+ Typography
+ ========================================================================== */
+/*
+ * Addresses font sizes and margins set differently in IE6/7
+ * Addresses font sizes within 'section' and 'article' in FF4+, Chrome, S5
+ */
+h1 {
+ font-size: 2em;
+ margin: 0.67em 0;
+}
+
+h2 {
+ font-size: 1.5em;
+ margin: 0.83em 0;
+}
+
+h3 {
+ font-size: 1.17em;
+ margin: 1em 0;
+}
+
+h4 {
+ font-size: 1em;
+ margin: 1.33em 0;
+}
+
+h5 {
+ font-size: 0.83em;
+ margin: 1.67em 0;
+}
+
+h6 {
+ font-size: 0.75em;
+ margin: 2.33em 0;
+}
+
+/*
+ * Addresses styling not present in IE7/8/9, S5, Chrome
+ */
+abbr[title] {
+ border-bottom: 1px dotted;
+}
+
+/*
+ * Addresses style set to 'bolder' in FF3+, S4/5, Chrome
+*/
+b,
+strong {
+ font-weight: bold;
+}
+
+blockquote {
+ margin: 1em 40px;
+}
+
+/*
+ * Addresses styling not present in S5, Chrome
+ */
+dfn {
+ font-style: italic;
+}
+
+/*
+ * Addresses styling not present in IE6/7/8/9
+ */
+mark {
+ background: #ff0;
+ color: #000;
+}
+
+/*
+ * Addresses margins set differently in IE6/7
+ */
+p,
+pre {
+ margin: 1em 0;
+}
+
+/*
+ * Corrects font family set oddly in IE6, S4/5, Chrome
+ * en.wikipedia.org/wiki/User:Davidgothberg/Test59
+ */
+pre,
+code,
+kbd,
+samp {
+ font-family: monospace, serif;
+ _font-family: 'courier new', monospace;
+ font-size: 1em;
+}
+
+/*
+ * 1. Addresses CSS quotes not supported in IE6/7
+ * 2. Addresses quote property not supported in S4
+ */
+/* 1 */
+q {
+ quotes: none;
+}
+
+/* 2 */
+q:before,
+q:after {
+ content: '';
+ content: none;
+}
+
+small {
+ font-size: 75%;
+}
+
+/*
+ * Prevents sub and sup affecting line-height in all browsers
+ * gist.github.com/413930
+ */
+sub,
+sup {
+ font-size: 75%;
+ line-height: 0;
+ position: relative;
+ vertical-align: baseline;
+}
+
+sup {
+ top: -0.5em;
+}
+
+sub {
+ bottom: -0.25em;
+}
+
+/* =============================================================================
+ Lists
+ ========================================================================== */
+/*
+ * Addresses margins set differently in IE6/7
+ */
+dl,
+menu,
+ol,
+ul {
+ margin: 1em 0;
+}
+
+dd {
+ margin: 0 0 0 40px;
+}
+
+/*
+ * Addresses paddings set differently in IE6/7
+ */
+menu,
+ol,
+ul {
+ padding: 0 0 0 40px;
+}
+
+/*
+ * Corrects list images handled incorrectly in IE7
+ */
+nav ul,
+nav ol {
+ list-style: none;
+ list-style-image: none;
+}
+
+/* =============================================================================
+ Embedded content
+ ========================================================================== */
+/*
+ * 1. Removes border when inside 'a' element in IE6/7/8/9, FF3
+ * 2. Improves image quality when scaled in IE7
+ * code.flickr.com/blog/2008/11/12/on-ui-quality-the-little-things-client-side-image-resizing/
+ */
+img {
+ border: 0;
+ /* 1 */
+ -ms-interpolation-mode: bicubic;
+ /* 2 */
+}
+
+/*
+ * Corrects overflow displayed oddly in IE9
+ */
+svg:not(:root) {
+ overflow: hidden;
+}
+
+/* =============================================================================
+ Figures
+ ========================================================================== */
+/*
+ * Addresses margin not present in IE6/7/8/9, S5, O11
+ */
+figure {
+ margin: 0;
+}
+
+/* =============================================================================
+ Forms
+ ========================================================================== */
+/*
+ * Corrects margin displayed oddly in IE6/7
+ */
+form {
+ margin: 0;
+}
+
+/*
+ * Define consistent border, margin, and padding
+ */
+fieldset {
+ border: 1px solid #c0c0c0;
+ margin: 0 2px;
+ padding: 0.35em 0.625em 0.75em;
+}
+
+/*
+ * 1. Corrects color not being inherited in IE6/7/8/9
+ * 2. Corrects text not wrapping in FF3
+ * 3. Corrects alignment displayed oddly in IE6/7
+ */
+legend {
+ border: 0;
+ /* 1 */
+ padding: 0;
+ white-space: normal;
+ /* 2 */
+ *margin-left: -7px;
+ /* 3 */
+}
+
+/*
+ * 1. Corrects font size not being inherited in all browsers
+ * 2. Addresses margins set differently in IE6/7, FF3+, S5, Chrome
+ * 3. Improves appearance and consistency in all browsers
+ */
+button,
+input,
+select,
+textarea {
+ font-size: 100%;
+ /* 1 */
+ margin: 0;
+ /* 2 */
+ vertical-align: baseline;
+ /* 3 */
+ *vertical-align: middle;
+ /* 3 */
+}
+
+/*
+ * Addresses FF3/4 setting line-height on 'input' using !important in the UA stylesheet
+ */
+button,
+input {
+ line-height: normal;
+ /* 1 */
+}
+
+/*
+ * 1. Improves usability and consistency of cursor style between image-type 'input' and others
+ * 2. Corrects inability to style clickable 'input' types in iOS
+ * 3. Removes inner spacing in IE7 without affecting normal text inputs
+ * Known issue: inner spacing remains in IE6
+ */
+button,
+input[type="button"],
+input[type="reset"],
+input[type="submit"] {
+ cursor: pointer;
+ /* 1 */
+ -webkit-appearance: button;
+ /* 2 */
+ *overflow: visible;
+ /* 3 */
+}
+
+/*
+ * Re-set default cursor for disabled elements
+ */
+button[disabled],
+input[disabled] {
+ cursor: default;
+}
+
+/*
+ * 1. Addresses box sizing set to content-box in IE8/9
+ * 2. Removes excess padding in IE8/9
+ * 3. Removes excess padding in IE7
+ Known issue: excess padding remains in IE6
+ */
+input[type="checkbox"],
+input[type="radio"] {
+ box-sizing: border-box;
+ /* 1 */
+ padding: 0;
+ /* 2 */
+ *height: 13px;
+ /* 3 */
+ *width: 13px;
+ /* 3 */
+}
+
+/*
+ * 1. Addresses appearance set to searchfield in S5, Chrome
+ * 2. Addresses box-sizing set to border-box in S5, Chrome (include -moz to future-proof)
+ */
+input[type="search"] {
+ -webkit-appearance: textfield;
+ /* 1 */
+ -moz-box-sizing: content-box;
+ -webkit-box-sizing: content-box;
+ /* 2 */
+ box-sizing: content-box;
+}
+
+/*
+ * Removes inner padding and search cancel button in S5, Chrome on OS X
+ */
+input[type="search"]::-webkit-search-decoration,
+input[type="search"]::-webkit-search-cancel-button {
+ -webkit-appearance: none;
+}
+
+/*
+ * Removes inner padding and border in FF3+
+ * www.sitepen.com/blog/2008/05/14/the-devils-in-the-details-fixing-dojos-toolbar-buttons/
+ */
+button::-moz-focus-inner,
+input::-moz-focus-inner {
+ border: 0;
+ padding: 0;
+}
+
+/*
+ * 1. Removes default vertical scrollbar in IE6/7/8/9
+ * 2. Improves readability and alignment in all browsers
+ */
+textarea {
+ overflow: auto;
+ /* 1 */
+ vertical-align: top;
+ /* 2 */
+}
+
+/* =============================================================================
+ Tables
+ ========================================================================== */
+/*
+ * Remove most spacing between table cells
+ */
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+
+body {
+ padding: 0px 0 20px 0px;
+ margin: 0px;
+ font: 14px/1.5 "OpenSansRegular", "Helvetica Neue", Helvetica, Arial, sans-serif;
+ color: #f0e7d5;
+ font-weight: normal;
+ background: #252525;
+ background-attachment: fixed !important;
+ background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #2a2a29), color-stop(100%, #1c1c1c));
+ background: -webkit-linear-gradient(#2a2a29, #1c1c1c);
+ background: -moz-linear-gradient(#2a2a29, #1c1c1c);
+ background: -o-linear-gradient(#2a2a29, #1c1c1c);
+ background: -ms-linear-gradient(#2a2a29, #1c1c1c);
+ background: linear-gradient(#2a2a29, #1c1c1c);
+}
+
+h1, h2, h3, h4, h5, h6 {
+ color: #e8e8e8;
+ margin: 0 0 10px;
+ font-family: 'OpenSansRegular', "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-weight: normal;
+}
+
+p, ul, ol, table, pre, dl {
+ margin: 0 0 20px;
+}
+
+h1, h2, h3 {
+ line-height: 1.1;
+}
+
+h1 {
+ font-size: 28px;
+}
+
+h2 {
+ font-size: 24px;
+}
+
+h4, h5, h6 {
+ color: #e8e8e8;
+}
+
+h3 {
+ font-size: 18px;
+ line-height: 24px;
+ font-family: 'OpenSansRegular', "Helvetica Neue", Helvetica, Arial, sans-serif !important;
+ font-weight: normal;
+ color: #b6b6b6;
+}
+
+a {
+ color: #ffcc00;
+ font-weight: 400;
+ text-decoration: none;
+}
+a:hover {
+ color: #ffeb9b;
+}
+
+a small {
+ font-size: 11px;
+ color: #666;
+ margin-top: -0.6em;
+ display: block;
+}
+
+ul {
+ list-style-image: url("../images/bullet.png");
+}
+
+strong {
+ font-family: 'OpenSansBold', "Helvetica Neue", Helvetica, Arial, sans-serif !important;
+ font-weight: normal;
+}
+
+.wrapper {
+ max-width: 650px;
+ margin: 0 auto;
+ position: relative;
+ padding: 0 20px;
+}
+
+section img {
+ max-width: 100%;
+}
+
+blockquote {
+ border-left: 3px solid #ffcc00;
+ margin: 0;
+ padding: 0 0 0 20px;
+ font-style: italic;
+}
+
+code {
+ font-family: "Lucida Sans", Monaco, Bitstream Vera Sans Mono, Lucida Console, Terminal;
+ color: #efefef;
+ font-size: 13px;
+ margin: 0 4px;
+ padding: 4px 6px;
+ -moz-border-radius: 2px;
+ -webkit-border-radius: 2px;
+ -o-border-radius: 2px;
+ -ms-border-radius: 2px;
+ -khtml-border-radius: 2px;
+ border-radius: 2px;
+}
+
+pre {
+ padding: 8px 15px;
+ background: #191919;
+ -moz-border-radius: 2px;
+ -webkit-border-radius: 2px;
+ -o-border-radius: 2px;
+ -ms-border-radius: 2px;
+ -khtml-border-radius: 2px;
+ border-radius: 2px;
+ border: 1px solid #121212;
+ -moz-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.3);
+ -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.3);
+ -o-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.3);
+ box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.3);
+ overflow: auto;
+ overflow-y: hidden;
+}
+pre code {
+ color: #efefef;
+ text-shadow: 0px 1px 0px #000;
+ margin: 0;
+ padding: 0;
+}
+
+table {
+ width: 100%;
+ border-collapse: collapse;
+}
+
+th {
+ text-align: left;
+ padding: 5px 10px;
+ border-bottom: 1px solid #434343;
+ color: #b6b6b6;
+ font-family: 'OpenSansSemibold', "Helvetica Neue", Helvetica, Arial, sans-serif !important;
+ font-weight: normal;
+}
+
+td {
+ text-align: left;
+ padding: 5px 10px;
+ border-bottom: 1px solid #434343;
+}
+
+hr {
+ border: 0;
+ outline: none;
+ height: 3px;
+ background: transparent url("../images/hr.gif") center center repeat-x;
+ margin: 0 0 20px;
+}
+
+dt {
+ color: #F0E7D5;
+ font-family: 'OpenSansSemibold', "Helvetica Neue", Helvetica, Arial, sans-serif !important;
+ font-weight: normal;
+}
+
+#header {
+ z-index: 100;
+ left: 0;
+ top: 0px;
+ height: 60px;
+ width: 100%;
+ position: fixed;
+ background: url(../images/nav-bg.gif) #353535;
+ border-bottom: 4px solid #434343;
+ -moz-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.25);
+ -webkit-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.25);
+ -o-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.25);
+ box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.25);
+}
+#header nav {
+ max-width: 650px;
+ margin: 0 auto;
+ padding: 0 10px;
+ background: blue;
+ margin: 6px auto;
+}
+#header nav li {
+ font-family: 'OpenSansLight', "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-weight: normal;
+ list-style: none;
+ display: inline;
+ color: white;
+ line-height: 50px;
+ text-shadow: 0px 1px 0px rgba(0, 0, 0, 0.2);
+ font-size: 14px;
+}
+#header nav li a {
+ color: white;
+ border: 1px solid #5d910b;
+ background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #93bd20), color-stop(100%, #659e10));
+ background: -webkit-linear-gradient(#93bd20, #659e10);
+ background: -moz-linear-gradient(#93bd20, #659e10);
+ background: -o-linear-gradient(#93bd20, #659e10);
+ background: -ms-linear-gradient(#93bd20, #659e10);
+ background: linear-gradient(#93bd20, #659e10);
+ -moz-border-radius: 2px;
+ -webkit-border-radius: 2px;
+ -o-border-radius: 2px;
+ -ms-border-radius: 2px;
+ -khtml-border-radius: 2px;
+ border-radius: 2px;
+ -moz-box-shadow: inset 0px 1px 0px rgba(255, 255, 255, 0.3), 0px 3px 7px rgba(0, 0, 0, 0.7);
+ -webkit-box-shadow: inset 0px 1px 0px rgba(255, 255, 255, 0.3), 0px 3px 7px rgba(0, 0, 0, 0.7);
+ -o-box-shadow: inset 0px 1px 0px rgba(255, 255, 255, 0.3), 0px 3px 7px rgba(0, 0, 0, 0.7);
+ box-shadow: inset 0px 1px 0px rgba(255, 255, 255, 0.3), 0px 3px 7px rgba(0, 0, 0, 0.7);
+ background-color: #93bd20;
+ padding: 10px 12px;
+ margin-top: 6px;
+ line-height: 14px;
+ font-size: 14px;
+ display: inline-block;
+ text-align: center;
+}
+#header nav li a:hover {
+ background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #749619), color-stop(100%, #527f0e));
+ background: -webkit-linear-gradient(#749619, #527f0e);
+ background: -moz-linear-gradient(#749619, #527f0e);
+ background: -o-linear-gradient(#749619, #527f0e);
+ background: -ms-linear-gradient(#749619, #527f0e);
+ background: linear-gradient(#749619, #527f0e);
+ background-color: #659e10;
+ border: 1px solid #527f0e;
+ -moz-box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.2), 0px 1px 0px rgba(0, 0, 0, 0);
+ -webkit-box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.2), 0px 1px 0px rgba(0, 0, 0, 0);
+ -o-box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.2), 0px 1px 0px rgba(0, 0, 0, 0);
+ box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.2), 0px 1px 0px rgba(0, 0, 0, 0);
+}
+#header nav li.fork {
+ float: left;
+ margin-left: 0px;
+}
+#header nav li.downloads {
+ float: right;
+ margin-left: 6px;
+}
+#header nav li.title {
+ float: right;
+ margin-right: 10px;
+ font-size: 11px;
+}
+
+section {
+ max-width: 650px;
+ padding: 30px 0px 50px 0px;
+ margin: 20px 0;
+ margin-top: 70px;
+}
+section #title {
+ border: 0;
+ outline: none;
+ margin: 0 0 50px 0;
+ padding: 0 0 5px 0;
+}
+section #title h1 {
+ font-family: 'OpenSansLight', "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-weight: normal;
+ font-size: 40px;
+ text-align: center;
+ line-height: 36px;
+}
+section #title p {
+ color: #d7cfbe;
+ font-family: 'OpenSansLight', "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-weight: normal;
+ font-size: 18px;
+ text-align: center;
+}
+section #title .credits {
+ font-size: 11px;
+ font-family: 'OpenSansRegular', "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-weight: normal;
+ color: #696969;
+ margin-top: -10px;
+}
+section #title .credits.left {
+ float: left;
+}
+section #title .credits.right {
+ float: right;
+}
+
+@media print, screen and (max-width: 720px) {
+ #title .credits {
+ display: block;
+ width: 100%;
+ line-height: 30px;
+ text-align: center;
+ }
+ #title .credits .left {
+ float: none;
+ display: block;
+ }
+ #title .credits .right {
+ float: none;
+ display: block;
+ }
+}
+@media print, screen and (max-width: 480px) {
+ #header {
+ margin-top: -20px;
+ }
+
+ section {
+ margin-top: 40px;
+ }
+
+ nav {
+ display: none;
+ }
+}
diff --git a/stylesheets/stylesheet.css b/stylesheets/stylesheet.css
new file mode 100644
index 000000000..b5f20c235
--- /dev/null
+++ b/stylesheets/stylesheet.css
@@ -0,0 +1,245 @@
+* {
+ box-sizing: border-box; }
+
+body {
+ padding: 0;
+ margin: 0;
+ font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 16px;
+ line-height: 1.5;
+ color: #606c71; }
+
+a {
+ color: #1e6bb8;
+ text-decoration: none; }
+ a:hover {
+ text-decoration: underline; }
+
+.btn {
+ display: inline-block;
+ margin-bottom: 1rem;
+ color: rgba(255, 255, 255, 0.7);
+ background-color: rgba(255, 255, 255, 0.08);
+ border-color: rgba(255, 255, 255, 0.2);
+ border-style: solid;
+ border-width: 1px;
+ border-radius: 0.3rem;
+ transition: color 0.2s, background-color 0.2s, border-color 0.2s; }
+ .btn + .btn {
+ margin-left: 1rem; }
+
+.btn:hover {
+ color: rgba(255, 255, 255, 0.8);
+ text-decoration: none;
+ background-color: rgba(255, 255, 255, 0.2);
+ border-color: rgba(255, 255, 255, 0.3); }
+
+@media screen and (min-width: 64em) {
+ .btn {
+ padding: 0.75rem 1rem; } }
+
+@media screen and (min-width: 42em) and (max-width: 64em) {
+ .btn {
+ padding: 0.6rem 0.9rem;
+ font-size: 0.9rem; } }
+
+@media screen and (max-width: 42em) {
+ .btn {
+ display: block;
+ width: 100%;
+ padding: 0.75rem;
+ font-size: 0.9rem; }
+ .btn + .btn {
+ margin-top: 1rem;
+ margin-left: 0; } }
+
+.page-header {
+ color: #fff;
+ text-align: center;
+ background-color: #159957;
+ background-image: linear-gradient(120deg, #155799, #159957); }
+
+@media screen and (min-width: 64em) {
+ .page-header {
+ padding: 5rem 6rem; } }
+
+@media screen and (min-width: 42em) and (max-width: 64em) {
+ .page-header {
+ padding: 3rem 4rem; } }
+
+@media screen and (max-width: 42em) {
+ .page-header {
+ padding: 2rem 1rem; } }
+
+.project-name {
+ margin-top: 0;
+ margin-bottom: 0.1rem; }
+
+@media screen and (min-width: 64em) {
+ .project-name {
+ font-size: 3.25rem; } }
+
+@media screen and (min-width: 42em) and (max-width: 64em) {
+ .project-name {
+ font-size: 2.25rem; } }
+
+@media screen and (max-width: 42em) {
+ .project-name {
+ font-size: 1.75rem; } }
+
+.project-tagline {
+ margin-bottom: 2rem;
+ font-weight: normal;
+ opacity: 0.7; }
+
+@media screen and (min-width: 64em) {
+ .project-tagline {
+ font-size: 1.25rem; } }
+
+@media screen and (min-width: 42em) and (max-width: 64em) {
+ .project-tagline {
+ font-size: 1.15rem; } }
+
+@media screen and (max-width: 42em) {
+ .project-tagline {
+ font-size: 1rem; } }
+
+.main-content :first-child {
+ margin-top: 0; }
+.main-content img {
+ max-width: 100%; }
+.main-content h1, .main-content h2, .main-content h3, .main-content h4, .main-content h5, .main-content h6 {
+ margin-top: 2rem;
+ margin-bottom: 1rem;
+ font-weight: normal;
+ color: #159957; }
+.main-content p {
+ margin-bottom: 1em; }
+.main-content code {
+ padding: 2px 4px;
+ font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
+ font-size: 0.9rem;
+ color: #383e41;
+ background-color: #f3f6fa;
+ border-radius: 0.3rem; }
+.main-content pre {
+ padding: 0.8rem;
+ margin-top: 0;
+ margin-bottom: 1rem;
+ font: 1rem Consolas, "Liberation Mono", Menlo, Courier, monospace;
+ color: #567482;
+ word-wrap: normal;
+ background-color: #f3f6fa;
+ border: solid 1px #dce6f0;
+ border-radius: 0.3rem; }
+ .main-content pre > code {
+ padding: 0;
+ margin: 0;
+ font-size: 0.9rem;
+ color: #567482;
+ word-break: normal;
+ white-space: pre;
+ background: transparent;
+ border: 0; }
+.main-content .highlight {
+ margin-bottom: 1rem; }
+ .main-content .highlight pre {
+ margin-bottom: 0;
+ word-break: normal; }
+.main-content .highlight pre, .main-content pre {
+ padding: 0.8rem;
+ overflow: auto;
+ font-size: 0.9rem;
+ line-height: 1.45;
+ border-radius: 0.3rem; }
+.main-content pre code, .main-content pre tt {
+ display: inline;
+ max-width: initial;
+ padding: 0;
+ margin: 0;
+ overflow: initial;
+ line-height: inherit;
+ word-wrap: normal;
+ background-color: transparent;
+ border: 0; }
+ .main-content pre code:before, .main-content pre code:after, .main-content pre tt:before, .main-content pre tt:after {
+ content: normal; }
+.main-content ul, .main-content ol {
+ margin-top: 0; }
+.main-content blockquote {
+ padding: 0 1rem;
+ margin-left: 0;
+ color: #819198;
+ border-left: 0.3rem solid #dce6f0; }
+ .main-content blockquote > :first-child {
+ margin-top: 0; }
+ .main-content blockquote > :last-child {
+ margin-bottom: 0; }
+.main-content table {
+ display: block;
+ width: 100%;
+ overflow: auto;
+ word-break: normal;
+ word-break: keep-all; }
+ .main-content table th {
+ font-weight: bold; }
+ .main-content table th, .main-content table td {
+ padding: 0.5rem 1rem;
+ border: 1px solid #e9ebec; }
+.main-content dl {
+ padding: 0; }
+ .main-content dl dt {
+ padding: 0;
+ margin-top: 1rem;
+ font-size: 1rem;
+ font-weight: bold; }
+ .main-content dl dd {
+ padding: 0;
+ margin-bottom: 1rem; }
+.main-content hr {
+ height: 2px;
+ padding: 0;
+ margin: 1rem 0;
+ background-color: #eff0f1;
+ border: 0; }
+
+@media screen and (min-width: 64em) {
+ .main-content {
+ max-width: 64rem;
+ padding: 2rem 6rem;
+ margin: 0 auto;
+ font-size: 1.1rem; } }
+
+@media screen and (min-width: 42em) and (max-width: 64em) {
+ .main-content {
+ padding: 2rem 4rem;
+ font-size: 1.1rem; } }
+
+@media screen and (max-width: 42em) {
+ .main-content {
+ padding: 2rem 1rem;
+ font-size: 1rem; } }
+
+.site-footer {
+ padding-top: 2rem;
+ margin-top: 2rem;
+ border-top: solid 1px #eff0f1; }
+
+.site-footer-owner {
+ display: block;
+ font-weight: bold; }
+
+.site-footer-credits {
+ color: #819198; }
+
+@media screen and (min-width: 64em) {
+ .site-footer {
+ font-size: 1rem; } }
+
+@media screen and (min-width: 42em) and (max-width: 64em) {
+ .site-footer {
+ font-size: 1rem; } }
+
+@media screen and (max-width: 42em) {
+ .site-footer {
+ font-size: 0.9rem; } }
diff --git a/websocket-sharp.sln b/websocket-sharp.sln
deleted file mode 100644
index 6ff1c0362..000000000
--- a/websocket-sharp.sln
+++ /dev/null
@@ -1,64 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 10.00
-# Visual Studio 2008
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "websocket-sharp", "websocket-sharp\websocket-sharp.csproj", "{B357BAC7-529E-4D81-A0D2-71041B19C8DE}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Example", "Example\Example.csproj", "{52805AEC-EFB1-4F42-BB8E-3ED4E692C568}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Example2", "Example2\Example2.csproj", "{B81A24C8-25BB-42B2-AF99-1E1EACCE74C7}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Example3", "Example3\Example3.csproj", "{C648BA25-77E5-4A40-A97F-D0AA37B9FB26}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- Debug_Ubuntu|Any CPU = Debug_Ubuntu|Any CPU
- Release_Ubuntu|Any CPU = Release_Ubuntu|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {52805AEC-EFB1-4F42-BB8E-3ED4E692C568}.Debug_Ubuntu|Any CPU.ActiveCfg = Debug_Ubuntu|Any CPU
- {52805AEC-EFB1-4F42-BB8E-3ED4E692C568}.Debug_Ubuntu|Any CPU.Build.0 = Debug_Ubuntu|Any CPU
- {52805AEC-EFB1-4F42-BB8E-3ED4E692C568}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {52805AEC-EFB1-4F42-BB8E-3ED4E692C568}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {52805AEC-EFB1-4F42-BB8E-3ED4E692C568}.Release_Ubuntu|Any CPU.ActiveCfg = Release_Ubuntu|Any CPU
- {52805AEC-EFB1-4F42-BB8E-3ED4E692C568}.Release_Ubuntu|Any CPU.Build.0 = Release_Ubuntu|Any CPU
- {52805AEC-EFB1-4F42-BB8E-3ED4E692C568}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {52805AEC-EFB1-4F42-BB8E-3ED4E692C568}.Release|Any CPU.Build.0 = Release|Any CPU
- {B357BAC7-529E-4D81-A0D2-71041B19C8DE}.Debug_Ubuntu|Any CPU.ActiveCfg = Debug_Ubuntu|Any CPU
- {B357BAC7-529E-4D81-A0D2-71041B19C8DE}.Debug_Ubuntu|Any CPU.Build.0 = Debug_Ubuntu|Any CPU
- {B357BAC7-529E-4D81-A0D2-71041B19C8DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {B357BAC7-529E-4D81-A0D2-71041B19C8DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {B357BAC7-529E-4D81-A0D2-71041B19C8DE}.Release_Ubuntu|Any CPU.ActiveCfg = Release_Ubuntu|Any CPU
- {B357BAC7-529E-4D81-A0D2-71041B19C8DE}.Release_Ubuntu|Any CPU.Build.0 = Release_Ubuntu|Any CPU
- {B357BAC7-529E-4D81-A0D2-71041B19C8DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {B357BAC7-529E-4D81-A0D2-71041B19C8DE}.Release|Any CPU.Build.0 = Release|Any CPU
- {B81A24C8-25BB-42B2-AF99-1E1EACCE74C7}.Debug_Ubuntu|Any CPU.ActiveCfg = Debug_Ubuntu|Any CPU
- {B81A24C8-25BB-42B2-AF99-1E1EACCE74C7}.Debug_Ubuntu|Any CPU.Build.0 = Debug_Ubuntu|Any CPU
- {B81A24C8-25BB-42B2-AF99-1E1EACCE74C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {B81A24C8-25BB-42B2-AF99-1E1EACCE74C7}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {B81A24C8-25BB-42B2-AF99-1E1EACCE74C7}.Release_Ubuntu|Any CPU.ActiveCfg = Release_Ubuntu|Any CPU
- {B81A24C8-25BB-42B2-AF99-1E1EACCE74C7}.Release_Ubuntu|Any CPU.Build.0 = Release_Ubuntu|Any CPU
- {B81A24C8-25BB-42B2-AF99-1E1EACCE74C7}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {B81A24C8-25BB-42B2-AF99-1E1EACCE74C7}.Release|Any CPU.Build.0 = Release|Any CPU
- {C648BA25-77E5-4A40-A97F-D0AA37B9FB26}.Debug_Ubuntu|Any CPU.ActiveCfg = Debug_Ubuntu|Any CPU
- {C648BA25-77E5-4A40-A97F-D0AA37B9FB26}.Debug_Ubuntu|Any CPU.Build.0 = Debug_Ubuntu|Any CPU
- {C648BA25-77E5-4A40-A97F-D0AA37B9FB26}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {C648BA25-77E5-4A40-A97F-D0AA37B9FB26}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {C648BA25-77E5-4A40-A97F-D0AA37B9FB26}.Release_Ubuntu|Any CPU.ActiveCfg = Release_Ubuntu|Any CPU
- {C648BA25-77E5-4A40-A97F-D0AA37B9FB26}.Release_Ubuntu|Any CPU.Build.0 = Release_Ubuntu|Any CPU
- {C648BA25-77E5-4A40-A97F-D0AA37B9FB26}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {C648BA25-77E5-4A40-A97F-D0AA37B9FB26}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(MonoDevelopProperties) = preSolution
- StartupItem = websocket-sharp\websocket-sharp.csproj
- Policies = $0
- $0.TextStylePolicy = $1
- $1.inheritsSet = null
- $1.scope = text/x-csharp
- $0.CSharpFormattingPolicy = $2
- $2.inheritsSet = Mono
- $2.inheritsScope = text/x-csharp
- $2.scope = text/x-csharp
- EndGlobalSection
-EndGlobal
diff --git a/websocket-sharp/AssemblyInfo.cs b/websocket-sharp/AssemblyInfo.cs
deleted file mode 100644
index c85deaa45..000000000
--- a/websocket-sharp/AssemblyInfo.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-
-// Information about this assembly is defined by the following attributes.
-// Change them to the values specific to your project.
-
-[assembly: AssemblyTitle("websocket-sharp")]
-[assembly: AssemblyDescription("A C# implementation of the WebSocket protocol client and server")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("websocket-sharp.dll")]
-[assembly: AssemblyCopyright("sta.blockhead")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
-// The form "{Major}.{Minor}.*" will automatically update the build and revision,
-// and "{Major}.{Minor}.{Build}.*" will update just the revision.
-
-[assembly: AssemblyVersion("1.0.2.*")]
-
-// The following attributes are used to specify the signing key for the assembly,
-// if desired. See the Mono documentation for more information about signing.
-
-//[assembly: AssemblyDelaySign(false)]
-//[assembly: AssemblyKeyFile("")]
diff --git a/websocket-sharp/ByteOrder.cs b/websocket-sharp/ByteOrder.cs
deleted file mode 100644
index 317f462ea..000000000
--- a/websocket-sharp/ByteOrder.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-#region License
-/*
- * ByteOrder.cs
- *
- * The MIT License
- *
- * Copyright (c) 2012-2015 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-using System;
-
-namespace WebSocketSharp
-{
- ///
- /// Specifies the byte order.
- ///
- public enum ByteOrder
- {
- ///
- /// Specifies Little-endian.
- ///
- Little,
- ///
- /// Specifies Big-endian.
- ///
- Big
- }
-}
diff --git a/websocket-sharp/CloseEventArgs.cs b/websocket-sharp/CloseEventArgs.cs
deleted file mode 100644
index 8aa46e2d2..000000000
--- a/websocket-sharp/CloseEventArgs.cs
+++ /dev/null
@@ -1,118 +0,0 @@
-#region License
-/*
- * CloseEventArgs.cs
- *
- * The MIT License
- *
- * Copyright (c) 2012-2024 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-using System;
-
-namespace WebSocketSharp
-{
- ///
- /// Represents the event data for the event.
- ///
- ///
- ///
- /// The close event occurs when the WebSocket connection has been closed.
- ///
- ///
- /// If you would like to get the reason for the connection close,
- /// you should access the or
- /// property.
- ///
- ///
- public class CloseEventArgs : EventArgs
- {
- #region Private Fields
-
- private PayloadData _payloadData;
- private bool _wasClean;
-
- #endregion
-
- #region Internal Constructors
-
- internal CloseEventArgs (PayloadData payloadData, bool clean)
- {
- _payloadData = payloadData;
- _wasClean = clean;
- }
-
- #endregion
-
- #region Public Properties
-
- ///
- /// Gets the status code for the connection close.
- ///
- ///
- ///
- /// A that represents the status code for
- /// the connection close.
- ///
- ///
- /// 1005 (no status) if not present.
- ///
- ///
- public ushort Code {
- get {
- return _payloadData.Code;
- }
- }
-
- ///
- /// Gets the reason for the connection close.
- ///
- ///
- ///
- /// A that represents the reason for
- /// the connection close.
- ///
- ///
- /// An empty string if not present.
- ///
- ///
- public string Reason {
- get {
- return _payloadData.Reason;
- }
- }
-
- ///
- /// Gets a value indicating whether the connection has been closed cleanly.
- ///
- ///
- /// true if the connection has been closed cleanly; otherwise,
- /// false.
- ///
- public bool WasClean {
- get {
- return _wasClean;
- }
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/CloseStatusCode.cs b/websocket-sharp/CloseStatusCode.cs
deleted file mode 100644
index 81f3317a4..000000000
--- a/websocket-sharp/CloseStatusCode.cs
+++ /dev/null
@@ -1,120 +0,0 @@
-#region License
-/*
- * CloseStatusCode.cs
- *
- * The MIT License
- *
- * Copyright (c) 2012-2016 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-using System;
-
-namespace WebSocketSharp
-{
- ///
- /// Indicates the status code for the WebSocket connection close.
- ///
- ///
- ///
- /// The values of this enumeration are defined in
- ///
- /// Section 7.4 of RFC 6455.
- ///
- ///
- /// "Reserved value" cannot be sent as a status code in
- /// closing handshake by an endpoint.
- ///
- ///
- public enum CloseStatusCode : ushort
- {
- ///
- /// Equivalent to close status 1000. Indicates normal close.
- ///
- Normal = 1000,
- ///
- /// Equivalent to close status 1001. Indicates that an endpoint is
- /// going away.
- ///
- Away = 1001,
- ///
- /// Equivalent to close status 1002. Indicates that an endpoint is
- /// terminating the connection due to a protocol error.
- ///
- ProtocolError = 1002,
- ///
- /// Equivalent to close status 1003. Indicates that an endpoint is
- /// terminating the connection because it has received a type of
- /// data that it cannot accept.
- ///
- UnsupportedData = 1003,
- ///
- /// Equivalent to close status 1004. Still undefined. A Reserved value.
- ///
- Undefined = 1004,
- ///
- /// Equivalent to close status 1005. Indicates that no status code was
- /// actually present. A Reserved value.
- ///
- NoStatus = 1005,
- ///
- /// Equivalent to close status 1006. Indicates that the connection was
- /// closed abnormally. A Reserved value.
- ///
- Abnormal = 1006,
- ///
- /// Equivalent to close status 1007. Indicates that an endpoint is
- /// terminating the connection because it has received a message that
- /// contains data that is not consistent with the type of the message.
- ///
- InvalidData = 1007,
- ///
- /// Equivalent to close status 1008. Indicates that an endpoint is
- /// terminating the connection because it has received a message that
- /// violates its policy.
- ///
- PolicyViolation = 1008,
- ///
- /// 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.
- ///
- TooBig = 1009,
- ///
- /// Equivalent to close status 1010. Indicates that a client is
- /// terminating the connection because it has expected the server to
- /// negotiate one or more extension, but the server did not return
- /// them in the handshake response.
- ///
- MandatoryExtension = 1010,
- ///
- /// Equivalent to close status 1011. Indicates that a server is
- /// terminating the connection because it has encountered an unexpected
- /// condition that prevented it from fulfilling the request.
- ///
- ServerError = 1011,
- ///
- /// Equivalent to close status 1015. Indicates that the connection was
- /// closed due to a failure to perform a TLS handshake. A Reserved value.
- ///
- TlsHandshakeFailure = 1015
- }
-}
diff --git a/websocket-sharp/CompressionMethod.cs b/websocket-sharp/CompressionMethod.cs
deleted file mode 100644
index 42ab230a6..000000000
--- a/websocket-sharp/CompressionMethod.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-#region License
-/*
- * CompressionMethod.cs
- *
- * The MIT License
- *
- * Copyright (c) 2013-2017 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-using System;
-
-namespace WebSocketSharp
-{
- ///
- /// Specifies the method for compression.
- ///
- ///
- /// The methods are defined in
- ///
- /// Compression Extensions for WebSocket.
- ///
- public enum CompressionMethod : byte
- {
- ///
- /// Specifies no compression.
- ///
- None,
- ///
- /// Specifies DEFLATE.
- ///
- Deflate
- }
-}
diff --git a/websocket-sharp/ErrorEventArgs.cs b/websocket-sharp/ErrorEventArgs.cs
deleted file mode 100644
index c02d0e000..000000000
--- a/websocket-sharp/ErrorEventArgs.cs
+++ /dev/null
@@ -1,115 +0,0 @@
-#region License
-/*
- * ErrorEventArgs.cs
- *
- * The MIT License
- *
- * Copyright (c) 2012-2022 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-#region Contributors
-/*
- * Contributors:
- * - Frank Razenberg
- */
-#endregion
-
-using System;
-
-namespace WebSocketSharp
-{
- ///
- /// Represents the event data for the event.
- ///
- ///
- ///
- /// The error event occurs when the interface
- /// gets an error.
- ///
- ///
- /// If you would like to get the error message, you should access
- /// the property.
- ///
- ///
- /// If the error is due to an exception, you can get it by accessing
- /// the property.
- ///
- ///
- public class ErrorEventArgs : EventArgs
- {
- #region Private Fields
-
- private Exception _exception;
- private string _message;
-
- #endregion
-
- #region Internal Constructors
-
- internal ErrorEventArgs (string message)
- : this (message, null)
- {
- }
-
- internal ErrorEventArgs (string message, Exception exception)
- {
- _message = message;
- _exception = exception;
- }
-
- #endregion
-
- #region Public Properties
-
- ///
- /// Gets the exception that caused the error.
- ///
- ///
- ///
- /// An instance that represents
- /// the cause of the error.
- ///
- ///
- /// if not present.
- ///
- ///
- public Exception Exception {
- get {
- return _exception;
- }
- }
-
- ///
- /// Gets the error message.
- ///
- ///
- /// A that represents the error message.
- ///
- public string Message {
- get {
- return _message;
- }
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Ext.cs b/websocket-sharp/Ext.cs
deleted file mode 100644
index 2540f803e..000000000
--- a/websocket-sharp/Ext.cs
+++ /dev/null
@@ -1,1902 +0,0 @@
-#region License
-/*
- * Ext.cs
- *
- * Some parts of this code are derived from Mono (http://www.mono-project.com):
- * - The GetStatusDescription method is derived from HttpListenerResponse.cs (System.Net)
- * - The MaybeUri method is derived from Uri.cs (System)
- * - The isPredefinedScheme method is derived from Uri.cs (System)
- *
- * The MIT License
- *
- * Copyright (c) 2001 Garrett Rooney
- * Copyright (c) 2003 Ian MacLean
- * Copyright (c) 2003 Ben Maurer
- * Copyright (c) 2003, 2005, 2009 Novell, Inc. (http://www.novell.com)
- * Copyright (c) 2009 Stephane Delcroix
- * Copyright (c) 2010-2025 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-#region Contributors
-/*
- * Contributors:
- * - Liryna
- * - Nikola Kovacevic
- * - Chris Swiedler
- */
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Collections.Specialized;
-using System.IO;
-using System.IO.Compression;
-using System.Net.Sockets;
-using System.Security.Cryptography.X509Certificates;
-using System.Text;
-using WebSocketSharp.Net;
-using WebSocketSharp.Net.WebSockets;
-using WebSocketSharp.Server;
-
-namespace WebSocketSharp
-{
- ///
- /// Provides a set of static methods for websocket-sharp.
- ///
- public static class Ext
- {
- #region Private Fields
-
- private static readonly byte[] _last = new byte[] { 0x00 };
- private static readonly int _maxRetry = 5;
- private const string _tspecials = "()<>@,;:\\\"/[]?={} \t";
-
- #endregion
-
- #region Private Methods
-
- private static byte[] compress (this byte[] data)
- {
- if (data.LongLength == 0)
- return data;
-
- using (var input = new MemoryStream (data))
- return input.compressToArray ();
- }
-
- private static MemoryStream compress (this Stream stream)
- {
- var ret = new MemoryStream ();
-
- if (stream.Length == 0)
- return ret;
-
- stream.Position = 0;
-
- var mode = CompressionMode.Compress;
-
- using (var ds = new DeflateStream (ret, mode, true)) {
- stream.CopyTo (ds, 1024);
- ds.Close (); // BFINAL set to 1.
- ret.Write (_last, 0, 1);
-
- ret.Position = 0;
-
- return ret;
- }
- }
-
- private static byte[] compressToArray (this Stream stream)
- {
- using (var output = stream.compress ()) {
- output.Close ();
-
- return output.ToArray ();
- }
- }
-
- private static byte[] decompress (this byte[] data)
- {
- if (data.LongLength == 0)
- return data;
-
- using (var input = new MemoryStream (data))
- return input.decompressToArray ();
- }
-
- private static MemoryStream decompress (this Stream stream)
- {
- var ret = new MemoryStream ();
-
- if (stream.Length == 0)
- return ret;
-
- stream.Position = 0;
-
- var mode = CompressionMode.Decompress;
-
- using (var ds = new DeflateStream (stream, mode, true)) {
- ds.CopyTo (ret, 1024);
-
- ret.Position = 0;
-
- return ret;
- }
- }
-
- private static byte[] decompressToArray (this Stream stream)
- {
- using (var output = stream.decompress ()) {
- output.Close ();
-
- return output.ToArray ();
- }
- }
-
- private static bool isPredefinedScheme (this string value)
- {
- 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 == 'g')
- return value == "gopher";
-
- if (c == 'm')
- return value == "mailto";
-
- if (c == 'n') {
- c = value[1];
-
- return c == 'e'
- ? value == "news" || value == "net.pipe" || value == "net.tcp"
- : value == "nntp";
- }
-
- return false;
- }
-
- #endregion
-
- #region Internal Methods
-
- internal static byte[] Append (this ushort code, string reason)
- {
- var codeAsBytes = code.ToByteArray (ByteOrder.Big);
-
- if (reason == null || reason.Length == 0)
- return codeAsBytes;
-
- var buff = new List (codeAsBytes);
- var reasonAsBytes = Encoding.UTF8.GetBytes (reason);
-
- buff.AddRange (reasonAsBytes);
-
- return buff.ToArray ();
- }
-
- internal static byte[] Compress (
- this byte[] data,
- CompressionMethod method
- )
- {
- return method == CompressionMethod.Deflate ? data.compress () : data;
- }
-
- internal static Stream Compress (
- this Stream stream,
- CompressionMethod method
- )
- {
- return method == CompressionMethod.Deflate ? stream.compress () : stream;
- }
-
- internal static bool Contains (this string value, params char[] anyOf)
- {
- return anyOf != null && anyOf.Length > 0
- ? value.IndexOfAny (anyOf) > -1
- : false;
- }
-
- internal static bool Contains (
- this NameValueCollection collection,
- string name
- )
- {
- return collection[name] != null;
- }
-
- internal static bool Contains (
- this NameValueCollection collection,
- string name,
- string value,
- StringComparison comparisonTypeForValue
- )
- {
- var val = collection[name];
-
- if (val == null)
- return false;
-
- foreach (var elm in val.Split (',')) {
- if (elm.Trim ().Equals (value, comparisonTypeForValue))
- return true;
- }
-
- return false;
- }
-
- internal static bool Contains (
- this IEnumerable source,
- Func condition
- )
- {
- foreach (T elm in source) {
- if (condition (elm))
- return true;
- }
-
- return false;
- }
-
- internal static bool ContainsTwice (this string[] values)
- {
- var len = values.Length;
- var end = len - 1;
-
- Func seek = null;
- seek = idx => {
- if (idx == end)
- return false;
-
- var val = values[idx];
-
- for (var i = idx + 1; i < len; i++) {
- if (values[i] == val)
- return true;
- }
-
- return seek (++idx);
- };
-
- return seek (0);
- }
-
- internal static T[] Copy (this T[] sourceArray, int length)
- {
- var dest = new T[length];
-
- Array.Copy (sourceArray, 0, dest, 0, length);
-
- return dest;
- }
-
- internal static T[] Copy (this T[] sourceArray, long length)
- {
- var dest = new T[length];
-
- Array.Copy (sourceArray, 0, dest, 0, length);
-
- return dest;
- }
-
- internal static void CopyTo (
- this Stream sourceStream,
- Stream destinationStream,
- int bufferLength
- )
- {
- var buff = new byte[bufferLength];
-
- while (true) {
- var nread = sourceStream.Read (buff, 0, bufferLength);
-
- if (nread <= 0)
- break;
-
- destinationStream.Write (buff, 0, nread);
- }
- }
-
- internal static void CopyToAsync (
- this Stream sourceStream,
- Stream destinationStream,
- int bufferLength,
- Action completed,
- Action error
- )
- {
- var buff = new byte[bufferLength];
-
- AsyncCallback callback = null;
- callback =
- ar => {
- try {
- var nread = sourceStream.EndRead (ar);
-
- if (nread <= 0) {
- if (completed != null)
- completed ();
-
- return;
- }
-
- destinationStream.Write (buff, 0, nread);
-
- sourceStream.BeginRead (buff, 0, bufferLength, callback, null);
- }
- catch (Exception ex) {
- if (error != null)
- error (ex);
- }
- };
-
- try {
- sourceStream.BeginRead (buff, 0, bufferLength, callback, null);
- }
- catch (Exception ex) {
- if (error != null)
- error (ex);
- }
- }
-
- internal static byte[] Decompress (
- this byte[] data,
- CompressionMethod method
- )
- {
- return method == CompressionMethod.Deflate ? data.decompress () : data;
- }
-
- internal static Stream Decompress (
- this Stream stream,
- CompressionMethod method
- )
- {
- return method == CompressionMethod.Deflate
- ? stream.decompress ()
- : stream;
- }
-
- internal static byte[] DecompressToArray (
- this Stream stream,
- CompressionMethod method
- )
- {
- return method == CompressionMethod.Deflate
- ? stream.decompressToArray ()
- : stream.ToByteArray ();
- }
-
- internal static void Emit (
- this EventHandler eventHandler,
- object sender,
- EventArgs e
- )
- {
- if (eventHandler == null)
- return;
-
- eventHandler (sender, e);
- }
-
- internal static void Emit (
- this EventHandler eventHandler,
- object sender,
- TEventArgs e
- )
- where TEventArgs : EventArgs
- {
- if (eventHandler == null)
- return;
-
- eventHandler (sender, e);
- }
-
- internal static string GetAbsolutePath (this Uri uri)
- {
- if (uri.IsAbsoluteUri)
- return uri.AbsolutePath;
-
- var original = uri.OriginalString;
-
- if (original[0] != '/')
- return null;
-
- var idx = original.IndexOfAny (new[] { '?', '#' });
-
- return idx > 0 ? original.Substring (0, idx) : original;
- }
-
- internal static CookieCollection GetCookies (
- this NameValueCollection headers,
- bool response
- )
- {
- var name = response ? "Set-Cookie" : "Cookie";
- var val = headers[name];
-
- return val != null
- ? CookieCollection.Parse (val, response)
- : new CookieCollection ();
- }
-
- internal static string GetDnsSafeHost (this Uri uri, bool bracketIPv6)
- {
- return bracketIPv6 && uri.HostNameType == UriHostNameType.IPv6
- ? uri.Host
- : uri.DnsSafeHost;
- }
-
- internal static string GetErrorMessage (this ushort code)
- {
- switch (code) {
- case 1002:
- return "A protocol error has occurred.";
- case 1003:
- return "Unsupported data has been received.";
- case 1006:
- return "An abnormal error has occurred.";
- case 1007:
- return "Invalid data has been received.";
- case 1008:
- return "A policy violation has occurred.";
- case 1009:
- return "A too big message has been received.";
- case 1010:
- return "The client did not receive expected extension(s).";
- case 1011:
- return "The server got an internal error.";
- case 1015:
- return "An error has occurred during a TLS handshake.";
- default:
- return String.Empty;
- }
- }
-
- internal static string GetErrorMessage (this CloseStatusCode code)
- {
- return ((ushort) code).GetErrorMessage ();
- }
-
- internal static string GetName (this string nameAndValue, char separator)
- {
- var idx = nameAndValue.IndexOf (separator);
-
- return idx > 0 ? nameAndValue.Substring (0, idx).Trim () : null;
- }
-
- internal static string GetUTF8DecodedString (this byte[] bytes)
- {
- try {
- return Encoding.UTF8.GetString (bytes);
- }
- catch {
- return null;
- }
- }
-
- internal static byte[] GetUTF8EncodedBytes (this string s)
- {
- try {
- return Encoding.UTF8.GetBytes (s);
- }
- catch {
- return null;
- }
- }
-
- internal static string GetValue (this string nameAndValue, char separator)
- {
- return nameAndValue.GetValue (separator, false);
- }
-
- internal static string GetValue (
- this string nameAndValue,
- char separator,
- bool unquote
- )
- {
- var idx = nameAndValue.IndexOf (separator);
-
- if (idx < 0 || idx == nameAndValue.Length - 1)
- return null;
-
- var val = nameAndValue.Substring (idx + 1).Trim ();
-
- return unquote ? val.Unquote () : val;
- }
-
- internal static bool IsCompressionExtension (
- this string value,
- CompressionMethod method
- )
- {
- var extStr = method.ToExtensionString ();
- var compType = StringComparison.Ordinal;
-
- return value.StartsWith (extStr, compType);
- }
-
- internal static bool IsDefined (this CloseStatusCode code)
- {
- return Enum.IsDefined (typeof (CloseStatusCode), code);
- }
-
- internal static bool IsEqualTo (
- this int value,
- char c,
- Action beforeComparing
- )
- {
- beforeComparing (value);
-
- return value == c - 0;
- }
-
- internal static bool IsHttpMethod (this string value)
- {
- return value == "GET"
- || value == "HEAD"
- || value == "POST"
- || value == "PUT"
- || value == "DELETE"
- || value == "CONNECT"
- || value == "OPTIONS"
- || value == "TRACE";
- }
-
- internal static bool IsPortNumber (this int value)
- {
- return value > 0 && value < 65536;
- }
-
- internal static bool IsReserved (this CloseStatusCode code)
- {
- return ((ushort) code).IsReservedStatusCode ();
- }
-
- internal static bool IsReservedStatusCode (this ushort code)
- {
- return code == 1004
- || code == 1005
- || code == 1006
- || code == 1015;
- }
-
- internal static bool IsSupportedOpcode (this int opcode)
- {
- return Enum.IsDefined (typeof (Opcode), opcode);
- }
-
- internal static bool IsText (this string value)
- {
- var len = value.Length;
-
- for (var i = 0; i < len; i++) {
- var c = value[i];
-
- if (c < 0x20) {
- if ("\r\n\t".IndexOf (c) == -1)
- return false;
-
- if (c == '\n') {
- i++;
-
- if (i == len)
- break;
-
- c = value[i];
-
- if (" \t".IndexOf (c) == -1)
- return false;
- }
-
- continue;
- }
-
- if (c == 0x7f)
- return false;
- }
-
- return true;
- }
-
- internal static bool IsToken (this string value)
- {
- foreach (var c in value) {
- if (c < 0x20)
- return false;
-
- if (c > 0x7e)
- return false;
-
- if (_tspecials.IndexOf (c) > -1)
- return false;
- }
-
- return true;
- }
-
- internal static bool KeepsAlive (
- this NameValueCollection headers,
- Version version
- )
- {
- var compType = StringComparison.OrdinalIgnoreCase;
-
- return version > HttpVersion.Version10
- ? !headers.Contains ("Connection", "close", compType)
- : headers.Contains ("Connection", "keep-alive", compType);
- }
-
- internal static bool MaybeUri (this string value)
- {
- var idx = value.IndexOf (':');
-
- if (idx < 2 || idx > 9)
- return false;
-
- var schm = value.Substring (0, idx);
-
- return schm.isPredefinedScheme ();
- }
-
- internal static string Quote (this string value)
- {
- var fmt = "\"{0}\"";
- var val = value.Replace ("\"", "\\\"");
-
- return String.Format (fmt, val);
- }
-
- internal static byte[] ReadBytes (this Stream stream, int length)
- {
- var ret = new byte[length];
-
- var offset = 0;
- var retry = 0;
-
- while (length > 0) {
- var nread = stream.Read (ret, offset, length);
-
- if (nread <= 0) {
- if (retry < _maxRetry) {
- retry++;
-
- continue;
- }
-
- return ret.SubArray (0, offset);
- }
-
- retry = 0;
-
- offset += nread;
- length -= nread;
- }
-
- return ret;
- }
-
- internal static byte[] ReadBytes (
- this Stream stream,
- long length,
- int bufferLength
- )
- {
- using (var dest = new MemoryStream ()) {
- var buff = new byte[bufferLength];
- var retry = 0;
-
- while (length > 0) {
- if (length < bufferLength)
- bufferLength = (int) length;
-
- var nread = stream.Read (buff, 0, bufferLength);
-
- if (nread <= 0) {
- if (retry < _maxRetry) {
- retry++;
-
- continue;
- }
-
- break;
- }
-
- retry = 0;
-
- dest.Write (buff, 0, nread);
-
- length -= nread;
- }
-
- dest.Close ();
-
- return dest.ToArray ();
- }
- }
-
- internal static void ReadBytesAsync (
- this Stream stream,
- int length,
- Action completed,
- Action error
- )
- {
- var ret = new byte[length];
-
- var offset = 0;
- var retry = 0;
-
- AsyncCallback callback = null;
- callback =
- ar => {
- try {
- var nread = stream.EndRead (ar);
-
- if (nread <= 0) {
- if (retry < _maxRetry) {
- retry++;
-
- stream.BeginRead (ret, offset, length, callback, null);
-
- return;
- }
-
- if (completed != null)
- completed (ret.SubArray (0, offset));
-
- return;
- }
-
- if (nread == length) {
- if (completed != null)
- completed (ret);
-
- return;
- }
-
- retry = 0;
-
- offset += nread;
- length -= nread;
-
- stream.BeginRead (ret, offset, length, callback, null);
- }
- catch (Exception ex) {
- if (error != null)
- error (ex);
- }
- };
-
- try {
- stream.BeginRead (ret, offset, length, callback, null);
- }
- catch (Exception ex) {
- if (error != null)
- error (ex);
- }
- }
-
- internal static void ReadBytesAsync (
- this Stream stream,
- long length,
- int bufferLength,
- Action completed,
- Action error
- )
- {
- var dest = new MemoryStream ();
-
- var buff = new byte[bufferLength];
- var retry = 0;
-
- Action read = null;
- read =
- len => {
- if (len < bufferLength)
- bufferLength = (int) len;
-
- stream.BeginRead (
- buff,
- 0,
- bufferLength,
- ar => {
- try {
- var nread = stream.EndRead (ar);
-
- if (nread <= 0) {
- if (retry < _maxRetry) {
- retry++;
-
- read (len);
-
- return;
- }
-
- if (completed != null) {
- dest.Close ();
-
- var ret = dest.ToArray ();
-
- completed (ret);
- }
-
- dest.Dispose ();
-
- return;
- }
-
- dest.Write (buff, 0, nread);
-
- if (nread == len) {
- if (completed != null) {
- dest.Close ();
-
- var ret = dest.ToArray ();
-
- completed (ret);
- }
-
- dest.Dispose ();
-
- return;
- }
-
- retry = 0;
-
- read (len - nread);
- }
- catch (Exception ex) {
- dest.Dispose ();
-
- if (error != null)
- error (ex);
- }
- },
- null
- );
- };
-
- try {
- read (length);
- }
- catch (Exception ex) {
- dest.Dispose ();
-
- if (error != null)
- error (ex);
- }
- }
-
- internal static T[] Reverse (this T[] array)
- {
- var len = array.LongLength;
- var ret = new T[len];
-
- var end = len - 1;
-
- for (long i = 0; i <= end; i++)
- ret[i] = array[end - i];
-
- return ret;
- }
-
- internal static IEnumerable SplitHeaderValue (
- this string value,
- params char[] separators
- )
- {
- var len = value.Length;
- var end = len - 1;
-
- var buff = new StringBuilder (32);
- var escaped = false;
- var quoted = false;
-
- for (var i = 0; i <= end; i++) {
- var c = value[i];
-
- buff.Append (c);
-
- if (c == '"') {
- if (escaped) {
- escaped = false;
-
- continue;
- }
-
- quoted = !quoted;
-
- continue;
- }
-
- if (c == '\\') {
- if (i == end)
- break;
-
- if (value[i + 1] == '"')
- escaped = true;
-
- continue;
- }
-
- if (Array.IndexOf (separators, c) > -1) {
- if (quoted)
- continue;
-
- buff.Length -= 1;
-
- yield return buff.ToString ();
-
- buff.Length = 0;
-
- continue;
- }
- }
-
- yield return buff.ToString ();
- }
-
- internal static byte[] ToByteArray (this Stream stream)
- {
- stream.Position = 0;
-
- using (var buff = new MemoryStream ()) {
- stream.CopyTo (buff, 1024);
- buff.Close ();
-
- return buff.ToArray ();
- }
- }
-
- internal static byte[] ToByteArray (this ushort value, ByteOrder order)
- {
- var ret = BitConverter.GetBytes (value);
-
- if (!order.IsHostOrder ())
- Array.Reverse (ret);
-
- return ret;
- }
-
- internal static byte[] ToByteArray (this ulong value, ByteOrder order)
- {
- var ret = BitConverter.GetBytes (value);
-
- if (!order.IsHostOrder ())
- Array.Reverse (ret);
-
- return ret;
- }
-
- internal static CompressionMethod ToCompressionMethod (this string value)
- {
- var methods = Enum.GetValues (typeof (CompressionMethod));
-
- foreach (CompressionMethod method in methods) {
- if (method.ToExtensionString () == value)
- return method;
- }
-
- return CompressionMethod.None;
- }
-
- internal static string ToExtensionString (
- this CompressionMethod method,
- params string[] parameters
- )
- {
- if (method == CompressionMethod.None)
- return String.Empty;
-
- var name = method.ToString ().ToLower ();
- var ename = String.Format ("permessage-{0}", name);
-
- if (parameters == null || parameters.Length == 0)
- return ename;
-
- var eparams = parameters.ToString ("; ");
-
- return String.Format ("{0}; {1}", ename, eparams);
- }
-
- internal static int ToInt32 (this string numericString)
- {
- return Int32.Parse (numericString);
- }
-
- internal static System.Net.IPAddress ToIPAddress (this string value)
- {
- if (value == null || value.Length == 0)
- return null;
-
- System.Net.IPAddress addr;
-
- if (System.Net.IPAddress.TryParse (value, out addr))
- return addr;
-
- try {
- var addrs = System.Net.Dns.GetHostAddresses (value);
-
- return addrs[0];
- }
- catch {
- return null;
- }
- }
-
- internal static List ToList (
- this IEnumerable source
- )
- {
- return new List (source);
- }
-
- internal static string ToString (
- this System.Net.IPAddress address,
- bool bracketIPv6
- )
- {
- return bracketIPv6
- && address.AddressFamily == AddressFamily.InterNetworkV6
- ? String.Format ("[{0}]", address)
- : address.ToString ();
- }
-
- internal static ushort ToUInt16 (this byte[] source, ByteOrder sourceOrder)
- {
- var val = source.ToHostOrder (sourceOrder);
-
- return BitConverter.ToUInt16 (val, 0);
- }
-
- internal static ulong ToUInt64 (this byte[] source, ByteOrder sourceOrder)
- {
- var val = source.ToHostOrder (sourceOrder);
-
- return BitConverter.ToUInt64 (val, 0);
- }
-
- internal static Version ToVersion (this string versionString)
- {
- return new Version (versionString);
- }
-
- internal static IEnumerable TrimEach (
- this IEnumerable source
- )
- {
- foreach (var elm in source)
- yield return elm.Trim ();
- }
-
- internal static string TrimSlashFromEnd (this string value)
- {
- var ret = value.TrimEnd ('/');
-
- return ret.Length > 0 ? ret : "/";
- }
-
- internal static string TrimSlashOrBackslashFromEnd (this string value)
- {
- var ret = value.TrimEnd ('/', '\\');
-
- return ret.Length > 0 ? ret : value[0].ToString ();
- }
-
- internal static bool TryCreateVersion (
- this string versionString,
- out Version result
- )
- {
- result = null;
-
- try {
- result = new Version (versionString);
- }
- catch {
- return false;
- }
-
- return true;
- }
-
- internal static bool TryCreateWebSocketUri (
- this string uriString,
- out Uri result,
- out string message
- )
- {
- result = null;
- message = null;
-
- var uri = uriString.ToUri ();
-
- if (uri == null) {
- message = "An invalid URI string.";
-
- return false;
- }
-
- if (!uri.IsAbsoluteUri) {
- message = "A relative URI.";
-
- return false;
- }
-
- var schm = uri.Scheme;
- var valid = schm == "ws" || schm == "wss";
-
- if (!valid) {
- message = "The scheme part is not \"ws\" or \"wss\".";
-
- return false;
- }
-
- var port = uri.Port;
-
- if (port == 0) {
- message = "The port part is zero.";
-
- return false;
- }
-
- if (uri.Fragment.Length > 0) {
- message = "It includes the fragment component.";
-
- return false;
- }
-
- if (port == -1) {
- port = schm == "ws" ? 80 : 443;
- uriString = String.Format (
- "{0}://{1}:{2}{3}",
- schm,
- uri.Host,
- port,
- uri.PathAndQuery
- );
-
- result = new Uri (uriString);
- }
- else {
- result = uri;
- }
-
- return true;
- }
-
- internal static bool TryGetUTF8DecodedString (
- this byte[] bytes,
- out string s
- )
- {
- s = null;
-
- try {
- s = Encoding.UTF8.GetString (bytes);
- }
- catch {
- return false;
- }
-
- return true;
- }
-
- internal static bool TryGetUTF8EncodedBytes (
- this string s,
- out byte[] bytes
- )
- {
- bytes = null;
-
- try {
- bytes = Encoding.UTF8.GetBytes (s);
- }
- catch {
- return false;
- }
-
- return true;
- }
-
- internal static bool TryOpenRead (
- this FileInfo fileInfo,
- out FileStream fileStream
- )
- {
- fileStream = null;
-
- try {
- fileStream = fileInfo.OpenRead ();
- }
- catch {
- return false;
- }
-
- return true;
- }
-
- internal static string Unquote (this string value)
- {
- var first = value.IndexOf ('"');
-
- if (first == -1)
- return value;
-
- var last = value.LastIndexOf ('"');
-
- if (last == first)
- return value;
-
- var len = last - first - 1;
-
- return len > 0
- ? value.Substring (first + 1, len).Replace ("\\\"", "\"")
- : String.Empty;
- }
-
- internal static bool Upgrades (
- this NameValueCollection headers,
- string protocol
- )
- {
- var compType = StringComparison.OrdinalIgnoreCase;
-
- return headers.Contains ("Upgrade", protocol, compType)
- && headers.Contains ("Connection", "Upgrade", compType);
- }
-
- internal static string UrlDecode (this string value, Encoding encoding)
- {
- return value.IndexOfAny (new[] { '%', '+' }) > -1
- ? HttpUtility.UrlDecode (value, encoding)
- : value;
- }
-
- internal static string UrlEncode (this string value, Encoding encoding)
- {
- return HttpUtility.UrlEncode (value, encoding);
- }
-
- internal static void WriteBytes (
- this Stream stream,
- byte[] bytes,
- int bufferLength
- )
- {
- using (var src = new MemoryStream (bytes))
- src.CopyTo (stream, bufferLength);
- }
-
- internal static void WriteBytesAsync (
- this Stream stream,
- byte[] bytes,
- int bufferLength,
- Action completed,
- Action error
- )
- {
- var src = new MemoryStream (bytes);
-
- src.CopyToAsync (
- stream,
- bufferLength,
- () => {
- if (completed != null)
- completed ();
-
- src.Dispose ();
- },
- ex => {
- src.Dispose ();
-
- if (error != null)
- error (ex);
- }
- );
- }
-
- #endregion
-
- #region Public Methods
-
- ///
- /// Gets the description of the specified HTTP status code.
- ///
- ///
- /// A that represents the description of
- /// the HTTP status code.
- ///
- ///
- ///
- /// One of the enum values.
- ///
- ///
- /// It specifies the HTTP status code.
- ///
- ///
- public static string GetDescription (this HttpStatusCode code)
- {
- return ((int) code).GetStatusDescription ();
- }
-
- ///
- /// Gets the description of the specified HTTP status code.
- ///
- ///
- ///
- /// A that represents the description of
- /// the HTTP status code.
- ///
- ///
- /// An empty string if the description is not present.
- ///
- ///
- ///
- /// An that specifies the HTTP status code.
- ///
- 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;
- }
-
- ///
- /// Determines whether the specified ushort is in the range of
- /// the status code for the WebSocket connection close.
- ///
- ///
- ///
- /// The ranges are the following:
- ///
- ///
- /// -
- ///
- /// 1000-2999: These numbers are reserved for definition by
- /// the WebSocket protocol.
- ///
- ///
- /// -
- ///
- /// 3000-3999: These numbers are reserved for use by libraries,
- /// frameworks, and applications.
- ///
- ///
- /// -
- ///
- /// 4000-4999: These numbers are reserved for private use.
- ///
- ///
- ///
- ///
- ///
- /// true if is in the range of
- /// the status code for the close; otherwise, false.
- ///
- ///
- /// A to test.
- ///
- public static bool IsCloseStatusCode (this ushort value)
- {
- return value > 999 && value < 5000;
- }
-
- ///
- /// Determines whether the specified string is enclosed in
- /// the specified character.
- ///
- ///
- /// true if is enclosed in
- /// ; otherwise, false.
- ///
- ///
- /// A to test.
- ///
- ///
- /// A to find.
- ///
- public static bool IsEnclosedIn (this string value, char c)
- {
- if (value == null)
- return false;
-
- var len = value.Length;
-
- return len > 1 ? value[0] == c && value[len - 1] == c : false;
- }
-
- ///
- /// Determines whether the specified byte order is host (this computer
- /// architecture) byte order.
- ///
- ///
- /// true if is host byte order; otherwise,
- /// false.
- ///
- ///
- /// One of the enum values to test.
- ///
- 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));
- }
-
- ///
- /// Determines whether the specified IP address is a local IP address.
- ///
- ///
- /// This local means NOT REMOTE for the current host.
- ///
- ///
- /// true if is a local IP address;
- /// otherwise, false.
- ///
- ///
- /// A to test.
- ///
- ///
- /// is .
- ///
- public static bool IsLocal (this System.Net.IPAddress address)
- {
- if (address == null)
- throw new ArgumentNullException ("address");
-
- if (address.Equals (System.Net.IPAddress.Any))
- return true;
-
- if (address.Equals (System.Net.IPAddress.Loopback))
- return true;
-
- if (Socket.OSSupportsIPv6) {
- if (address.Equals (System.Net.IPAddress.IPv6Any))
- return true;
-
- if (address.Equals (System.Net.IPAddress.IPv6Loopback))
- return true;
- }
-
- var name = System.Net.Dns.GetHostName ();
- var addrs = System.Net.Dns.GetHostAddresses (name);
-
- foreach (var addr in addrs) {
- if (address.Equals (addr))
- return true;
- }
-
- return false;
- }
-
- ///
- /// Determines whether the specified string is or
- /// an empty string.
- ///
- ///
- /// true if is or
- /// an empty string; otherwise, false.
- ///
- ///
- /// A to test.
- ///
- public static bool IsNullOrEmpty (this string value)
- {
- return value == null || value.Length == 0;
- }
-
- ///
- /// Retrieves a sub-array from the specified array. A sub-array starts at
- /// the specified index in the array.
- ///
- ///
- /// An array of T that receives a sub-array.
- ///
- ///
- /// An array of T from which to retrieve a sub-array.
- ///
- ///
- /// An that specifies the zero-based index in the array
- /// at which retrieving starts.
- ///
- ///
- /// An that specifies the number of elements to retrieve.
- ///
- ///
- /// The type of elements in the array.
- ///
- ///
- /// is .
- ///
- ///
- ///
- /// is less than zero.
- ///
- ///
- /// -or-
- ///
- ///
- /// is greater than the end of the array.
- ///
- ///
- /// -or-
- ///
- ///
- /// is less than zero.
- ///
- ///
- /// -or-
- ///
- ///
- /// is greater than the number of elements from
- /// to the end of the array.
- ///
- ///
- public static T[] SubArray (this T[] array, int startIndex, int length)
- {
- if (array == null)
- throw new ArgumentNullException ("array");
-
- var len = array.Length;
-
- if (len == 0) {
- if (startIndex != 0)
- throw new ArgumentOutOfRangeException ("startIndex");
-
- if (length != 0)
- throw new ArgumentOutOfRangeException ("length");
-
- return array;
- }
-
- if (startIndex < 0 || startIndex >= len)
- throw new ArgumentOutOfRangeException ("startIndex");
-
- if (length < 0 || length > len - startIndex)
- throw new ArgumentOutOfRangeException ("length");
-
- if (length == 0)
- return new T[0];
-
- if (length == len)
- return array;
-
- var ret = new T[length];
-
- Array.Copy (array, startIndex, ret, 0, length);
-
- return ret;
- }
-
- ///
- /// Retrieves a sub-array from the specified array. A sub-array starts at
- /// the specified index in the array.
- ///
- ///
- /// An array of T that receives a sub-array.
- ///
- ///
- /// An array of T from which to retrieve a sub-array.
- ///
- ///
- /// A that specifies the zero-based index in the array
- /// at which retrieving starts.
- ///
- ///
- /// A that specifies the number of elements to retrieve.
- ///
- ///
- /// The type of elements in the array.
- ///
- ///
- /// is .
- ///
- ///
- ///
- /// is less than zero.
- ///
- ///
- /// -or-
- ///
- ///
- /// is greater than the end of the array.
- ///
- ///
- /// -or-
- ///
- ///
- /// is less than zero.
- ///
- ///
- /// -or-
- ///
- ///
- /// is greater than the number of elements from
- /// to the end of the array.
- ///
- ///
- public static T[] SubArray (this T[] array, long startIndex, long length)
- {
- if (array == null)
- throw new ArgumentNullException ("array");
-
- var len = array.LongLength;
-
- if (len == 0) {
- if (startIndex != 0)
- throw new ArgumentOutOfRangeException ("startIndex");
-
- if (length != 0)
- throw new ArgumentOutOfRangeException ("length");
-
- return array;
- }
-
- if (startIndex < 0 || startIndex >= len)
- throw new ArgumentOutOfRangeException ("startIndex");
-
- if (length < 0 || length > len - startIndex)
- throw new ArgumentOutOfRangeException ("length");
-
- if (length == 0)
- return new T[0];
-
- if (length == len)
- return array;
-
- var ret = new T[length];
-
- Array.Copy (array, startIndex, ret, 0, length);
-
- return ret;
- }
-
- ///
- /// Executes the specified delegate times.
- ///
- ///
- /// An that specifies the number of times to execute.
- ///
- ///
- ///
- /// An Action<int> delegate to execute.
- ///
- ///
- /// The parameter is the zero-based count of iteration.
- ///
- ///
- public static void Times (this int n, Action action)
- {
- if (n <= 0)
- return;
-
- if (action == null)
- return;
-
- for (int i = 0; i < n; i++)
- action (i);
- }
-
- ///
- /// Executes the specified delegate times.
- ///
- ///
- /// A that specifies the number of times to execute.
- ///
- ///
- ///
- /// An Action<long> delegate to execute.
- ///
- ///
- /// The parameter is the zero-based count of iteration.
- ///
- ///
- public static void Times (this long n, Action action)
- {
- if (n <= 0)
- return;
-
- if (action == null)
- return;
-
- for (long i = 0; i < n; i++)
- action (i);
- }
-
- ///
- /// Converts the order of elements in the specified byte array to
- /// host (this computer architecture) byte order.
- ///
- ///
- ///
- /// An array of converted from
- /// .
- ///
- ///
- /// if the number of elements in
- /// it is less than 2 or is
- /// same as host byte order.
- ///
- ///
- ///
- /// An array of to convert.
- ///
- ///
- ///
- /// One of the enum values.
- ///
- ///
- /// It specifies the order of elements in .
- ///
- ///
- ///
- /// is .
- ///
- public static byte[] ToHostOrder (this byte[] source, ByteOrder sourceOrder)
- {
- if (source == null)
- throw new ArgumentNullException ("source");
-
- if (source.Length < 2)
- return source;
-
- if (sourceOrder.IsHostOrder ())
- return source;
-
- return source.Reverse ();
- }
-
- ///
- /// Converts the specified array to a string.
- ///
- ///
- ///
- /// A converted by concatenating each element of
- /// across .
- ///
- ///
- /// An empty string if is an empty array.
- ///
- ///
- ///
- /// An array of T to convert.
- ///
- ///
- /// A used to separate each element of
- /// .
- ///
- ///
- /// The type of elements in .
- ///
- ///
- /// is .
- ///
- public static string ToString (this T[] array, string separator)
- {
- if (array == null)
- throw new ArgumentNullException ("array");
-
- var len = array.Length;
-
- if (len == 0)
- return String.Empty;
-
- var buff = new StringBuilder (64);
- var end = len - 1;
-
- for (var i = 0; i < end; i++)
- buff.AppendFormat ("{0}{1}", array[i], separator);
-
- buff.AppendFormat ("{0}", array[end]);
-
- return buff.ToString ();
- }
-
- ///
- /// Converts the specified string to a .
- ///
- ///
- ///
- /// A converted from .
- ///
- ///
- /// if the conversion has failed.
- ///
- ///
- ///
- /// A to convert.
- ///
- public static Uri ToUri (this string value)
- {
- if (value == null || value.Length == 0)
- return null;
-
- var kind = value.MaybeUri () ? UriKind.Absolute : UriKind.Relative;
- Uri ret;
-
- Uri.TryCreate (value, kind, out ret);
-
- return ret;
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Fin.cs b/websocket-sharp/Fin.cs
deleted file mode 100644
index 36622d7e5..000000000
--- a/websocket-sharp/Fin.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-#region License
-/*
- * Fin.cs
- *
- * The MIT License
- *
- * Copyright (c) 2012-2025 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-using System;
-
-namespace WebSocketSharp
-{
- ///
- /// Indicates whether a WebSocket frame is the final frame of a message.
- ///
- ///
- /// The values of this enumeration are defined in
- ///
- /// Section 5.2 of RFC 6455.
- ///
- internal enum Fin
- {
- ///
- /// Equivalent to numeric value 0. Indicates more frames of a message follow.
- ///
- More = 0x0,
- ///
- /// Equivalent to numeric value 1. Indicates the final frame of a message.
- ///
- Final = 0x1
- }
-}
diff --git a/websocket-sharp/HttpBase.cs b/websocket-sharp/HttpBase.cs
deleted file mode 100644
index c4a244f45..000000000
--- a/websocket-sharp/HttpBase.cs
+++ /dev/null
@@ -1,317 +0,0 @@
-#region License
-/*
- * HttpBase.cs
- *
- * The MIT License
- *
- * Copyright (c) 2012-2024 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Collections.Specialized;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading;
-using WebSocketSharp.Net;
-
-namespace WebSocketSharp
-{
- internal abstract class HttpBase
- {
- #region Private Fields
-
- private NameValueCollection _headers;
- private static readonly int _maxMessageHeaderLength;
- private string _messageBody;
- private byte[] _messageBodyData;
- private Version _version;
-
- #endregion
-
- #region Protected Fields
-
- protected static readonly string CrLf;
- protected static readonly string CrLfHt;
- protected static readonly string CrLfSp;
-
- #endregion
-
- #region Static Constructor
-
- static HttpBase ()
- {
- _maxMessageHeaderLength = 8192;
-
- CrLf = "\r\n";
- CrLfHt = "\r\n\t";
- CrLfSp = "\r\n ";
- }
-
- #endregion
-
- #region Protected Constructors
-
- protected HttpBase (Version version, NameValueCollection headers)
- {
- _version = version;
- _headers = headers;
- }
-
- #endregion
-
- #region Internal Properties
-
- internal byte[] MessageBodyData {
- get {
- return _messageBodyData;
- }
- }
-
- #endregion
-
- #region Protected Properties
-
- protected string HeaderSection {
- get {
- var buff = new StringBuilder (64);
-
- var fmt = "{0}: {1}{2}";
-
- foreach (var key in _headers.AllKeys)
- buff.AppendFormat (fmt, key, _headers[key], CrLf);
-
- buff.Append (CrLf);
-
- return buff.ToString ();
- }
- }
-
- #endregion
-
- #region Public Properties
-
- public bool HasMessageBody {
- get {
- return _messageBodyData != null;
- }
- }
-
- public NameValueCollection Headers {
- get {
- return _headers;
- }
- }
-
- public string MessageBody {
- get {
- if (_messageBody == null)
- _messageBody = getMessageBody ();
-
- return _messageBody;
- }
- }
-
- public abstract string MessageHeader { get; }
-
- public Version ProtocolVersion {
- get {
- return _version;
- }
- }
-
- #endregion
-
- #region Private Methods
-
- private string getMessageBody ()
- {
- if (_messageBodyData == null || _messageBodyData.LongLength == 0)
- return String.Empty;
-
- var contentType = _headers["Content-Type"];
-
- var enc = contentType != null && contentType.Length > 0
- ? HttpUtility.GetEncoding (contentType)
- : Encoding.UTF8;
-
- return enc.GetString (_messageBodyData);
- }
-
- private static byte[] readMessageBodyFrom (Stream stream, string length)
- {
- long len;
-
- if (!Int64.TryParse (length, out len)) {
- var msg = "It could not be parsed.";
-
- throw new ArgumentException (msg, "length");
- }
-
- if (len < 0) {
- var msg = "Less than zero.";
-
- throw new ArgumentOutOfRangeException ("length", msg);
- }
-
- return len > 1024
- ? stream.ReadBytes (len, 1024)
- : len > 0
- ? stream.ReadBytes ((int) len)
- : null;
- }
-
- private static string[] readMessageHeaderFrom (Stream stream)
- {
- var buff = new List ();
- var cnt = 0;
- Action add =
- i => {
- if (i == -1) {
- var msg = "The header could not be read from the data stream.";
-
- throw new EndOfStreamException (msg);
- }
-
- buff.Add ((byte) i);
-
- cnt++;
- };
-
- var end = false;
-
- do {
- end = stream.ReadByte ().IsEqualTo ('\r', add)
- && stream.ReadByte ().IsEqualTo ('\n', add)
- && stream.ReadByte ().IsEqualTo ('\r', add)
- && stream.ReadByte ().IsEqualTo ('\n', add);
-
- if (cnt > _maxMessageHeaderLength) {
- var msg = "The length of the header is greater than the max length.";
-
- throw new InvalidOperationException (msg);
- }
- }
- while (!end);
-
- var bytes = buff.ToArray ();
-
- return Encoding.UTF8.GetString (bytes)
- .Replace (CrLfSp, " ")
- .Replace (CrLfHt, " ")
- .Split (new[] { CrLf }, StringSplitOptions.RemoveEmptyEntries);
- }
-
- #endregion
-
- #region Internal Methods
-
- internal void WriteTo (Stream stream)
- {
- var bytes = ToByteArray ();
-
- stream.Write (bytes, 0, bytes.Length);
- }
-
- #endregion
-
- #region Protected Methods
-
- protected static T Read (
- Stream stream,
- Func parser,
- int millisecondsTimeout
- )
- where T : HttpBase
- {
- T ret = null;
-
- var timeout = false;
- var timer = new Timer (
- state => {
- timeout = true;
-
- stream.Close ();
- },
- null,
- millisecondsTimeout,
- -1
- );
-
- Exception exception = null;
-
- try {
- var header = readMessageHeaderFrom (stream);
- ret = parser (header);
-
- var contentLen = ret.Headers["Content-Length"];
-
- if (contentLen != null && contentLen.Length > 0)
- ret._messageBodyData = readMessageBodyFrom (stream, contentLen);
- }
- catch (Exception ex) {
- exception = ex;
- }
- finally {
- timer.Change (-1, -1);
- timer.Dispose ();
- }
-
- if (timeout) {
- var msg = "A timeout has occurred.";
-
- throw new WebSocketException (msg);
- }
-
- if (exception != null) {
- var msg = "An exception has occurred.";
-
- throw new WebSocketException (msg, exception);
- }
-
- return ret;
- }
-
- #endregion
-
- #region Public Methods
-
- public byte[] ToByteArray ()
- {
- var headerData = Encoding.UTF8.GetBytes (MessageHeader);
-
- return _messageBodyData != null
- ? headerData.Concat (_messageBodyData).ToArray ()
- : headerData;
- }
-
- public override string ToString ()
- {
- return _messageBodyData != null
- ? MessageHeader + MessageBody
- : MessageHeader;
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/HttpRequest.cs b/websocket-sharp/HttpRequest.cs
deleted file mode 100644
index 946024d6a..000000000
--- a/websocket-sharp/HttpRequest.cs
+++ /dev/null
@@ -1,253 +0,0 @@
-#region License
-/*
- * HttpRequest.cs
- *
- * The MIT License
- *
- * Copyright (c) 2012-2024 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-#region Contributors
-/*
- * Contributors:
- * - David Burhans
- */
-#endregion
-
-using System;
-using System.Collections.Specialized;
-using System.IO;
-using System.Text;
-using WebSocketSharp.Net;
-
-namespace WebSocketSharp
-{
- internal class HttpRequest : HttpBase
- {
- #region Private Fields
-
- private CookieCollection _cookies;
- private string _method;
- private string _target;
-
- #endregion
-
- #region Private Constructors
-
- private HttpRequest (
- string method,
- string target,
- Version version,
- NameValueCollection headers
- )
- : base (version, headers)
- {
- _method = method;
- _target = target;
- }
-
- #endregion
-
- #region Internal Constructors
-
- internal HttpRequest (string method, string target)
- : this (method, target, HttpVersion.Version11, new NameValueCollection ())
- {
- Headers["User-Agent"] = "websocket-sharp/1.0";
- }
-
- #endregion
-
- #region Internal Properties
-
- internal string RequestLine {
- get {
- var fmt = "{0} {1} HTTP/{2}{3}";
-
- return String.Format (fmt, _method, _target, ProtocolVersion, CrLf);
- }
- }
-
- #endregion
-
- #region Public Properties
-
- public AuthenticationResponse AuthenticationResponse {
- get {
- var val = Headers["Authorization"];
-
- return val != null && val.Length > 0
- ? AuthenticationResponse.Parse (val)
- : null;
- }
- }
-
- public CookieCollection Cookies {
- get {
- if (_cookies == null)
- _cookies = Headers.GetCookies (false);
-
- return _cookies;
- }
- }
-
- public string HttpMethod {
- get {
- return _method;
- }
- }
-
- public bool IsWebSocketRequest {
- get {
- return _method == "GET"
- && ProtocolVersion > HttpVersion.Version10
- && Headers.Upgrades ("websocket");
- }
- }
-
- public override string MessageHeader {
- get {
- return RequestLine + HeaderSection;
- }
- }
-
- public string RequestTarget {
- get {
- return _target;
- }
- }
-
- #endregion
-
- #region Internal Methods
-
- internal static HttpRequest CreateConnectRequest (Uri targetUri)
- {
- var fmt = "{0}:{1}";
- var host = targetUri.DnsSafeHost;
- var port = targetUri.Port;
- var authority = String.Format (fmt, host, port);
-
- var ret = new HttpRequest ("CONNECT", authority);
-
- ret.Headers["Host"] = port != 80 ? authority : host;
-
- return ret;
- }
-
- internal static HttpRequest CreateWebSocketHandshakeRequest (Uri targetUri)
- {
- var ret = new HttpRequest ("GET", targetUri.PathAndQuery);
-
- var headers = ret.Headers;
-
- var port = targetUri.Port;
- var schm = targetUri.Scheme;
- var isDefaultPort = (port == 80 && schm == "ws")
- || (port == 443 && schm == "wss");
-
- headers["Host"] = !isDefaultPort
- ? targetUri.Authority
- : targetUri.DnsSafeHost;
-
- headers["Upgrade"] = "websocket";
- headers["Connection"] = "Upgrade";
-
- return ret;
- }
-
- internal HttpResponse GetResponse (Stream stream, int millisecondsTimeout)
- {
- WriteTo (stream);
-
- return HttpResponse.ReadResponse (stream, millisecondsTimeout);
- }
-
- internal static HttpRequest Parse (string[] messageHeader)
- {
- var len = messageHeader.Length;
-
- if (len == 0) {
- var msg = "An empty request header.";
-
- throw new ArgumentException (msg);
- }
-
- var rlParts = messageHeader[0].Split (new[] { ' ' }, 3);
-
- if (rlParts.Length != 3) {
- var msg = "It includes an invalid request line.";
-
- throw new ArgumentException (msg);
- }
-
- var method = rlParts[0];
- var target = rlParts[1];
- var ver = rlParts[2].Substring (5).ToVersion ();
-
- var headers = new WebHeaderCollection ();
-
- for (var i = 1; i < len; i++)
- headers.InternalSet (messageHeader[i], false);
-
- return new HttpRequest (method, target, ver, headers);
- }
-
- internal static HttpRequest ReadRequest (
- Stream stream,
- int millisecondsTimeout
- )
- {
- return Read (stream, Parse, millisecondsTimeout);
- }
-
- #endregion
-
- #region Public Methods
-
- public void SetCookies (CookieCollection cookies)
- {
- if (cookies == null || cookies.Count == 0)
- return;
-
- var buff = new StringBuilder (64);
-
- foreach (var cookie in cookies.SortedList) {
- if (cookie.Expired)
- continue;
-
- buff.AppendFormat ("{0}; ", cookie);
- }
-
- var len = buff.Length;
-
- if (len <= 2)
- return;
-
- buff.Length = len - 2;
-
- Headers["Cookie"] = buff.ToString ();
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/HttpResponse.cs b/websocket-sharp/HttpResponse.cs
deleted file mode 100644
index d511c94fe..000000000
--- a/websocket-sharp/HttpResponse.cs
+++ /dev/null
@@ -1,274 +0,0 @@
-#region License
-/*
- * HttpResponse.cs
- *
- * The MIT License
- *
- * Copyright (c) 2012-2024 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-using System;
-using System.Collections.Specialized;
-using System.IO;
-using System.Text;
-using WebSocketSharp.Net;
-
-namespace WebSocketSharp
-{
- internal class HttpResponse : HttpBase
- {
- #region Private Fields
-
- private int _code;
- private string _reason;
-
- #endregion
-
- #region Private Constructors
-
- private HttpResponse (
- int code,
- string reason,
- Version version,
- NameValueCollection headers
- )
- : base (version, headers)
- {
- _code = code;
- _reason = reason;
- }
-
- #endregion
-
- #region Internal Constructors
-
- internal HttpResponse (int code)
- : this (code, code.GetStatusDescription ())
- {
- }
-
- internal HttpResponse (HttpStatusCode code)
- : this ((int) code)
- {
- }
-
- internal HttpResponse (int code, string reason)
- : this (
- code,
- reason,
- HttpVersion.Version11,
- new NameValueCollection ()
- )
- {
- Headers["Server"] = "websocket-sharp/1.0";
- }
-
- internal HttpResponse (HttpStatusCode code, string reason)
- : this ((int) code, reason)
- {
- }
-
- #endregion
-
- #region Internal Properties
-
- internal string StatusLine {
- get {
- return _reason != null
- ? String.Format (
- "HTTP/{0} {1} {2}{3}",
- ProtocolVersion,
- _code,
- _reason,
- CrLf
- )
- : String.Format (
- "HTTP/{0} {1}{2}",
- ProtocolVersion,
- _code,
- CrLf
- );
- }
- }
-
- #endregion
-
- #region Public Properties
-
- public bool CloseConnection {
- get {
- var compType = StringComparison.OrdinalIgnoreCase;
-
- return Headers.Contains ("Connection", "close", compType);
- }
- }
-
- public CookieCollection Cookies {
- get {
- return Headers.GetCookies (true);
- }
- }
-
- public bool IsProxyAuthenticationRequired {
- get {
- return _code == 407;
- }
- }
-
- public bool IsRedirect {
- get {
- return _code == 301 || _code == 302;
- }
- }
-
- public bool IsSuccess {
- get {
- return _code >= 200 && _code <= 299;
- }
- }
-
- public bool IsUnauthorized {
- get {
- return _code == 401;
- }
- }
-
- public bool IsWebSocketResponse {
- get {
- return ProtocolVersion > HttpVersion.Version10
- && _code == 101
- && Headers.Upgrades ("websocket");
- }
- }
-
- public override string MessageHeader {
- get {
- return StatusLine + HeaderSection;
- }
- }
-
- public string Reason {
- get {
- return _reason;
- }
- }
-
- public int StatusCode {
- get {
- return _code;
- }
- }
-
- #endregion
-
- #region Internal Methods
-
- internal static HttpResponse CreateCloseResponse (HttpStatusCode code)
- {
- var ret = new HttpResponse (code);
-
- ret.Headers["Connection"] = "close";
-
- return ret;
- }
-
- internal static HttpResponse CreateUnauthorizedResponse (string challenge)
- {
- var ret = new HttpResponse (HttpStatusCode.Unauthorized);
-
- ret.Headers["WWW-Authenticate"] = challenge;
-
- return ret;
- }
-
- internal static HttpResponse CreateWebSocketHandshakeResponse ()
- {
- var ret = new HttpResponse (HttpStatusCode.SwitchingProtocols);
-
- var headers = ret.Headers;
-
- headers["Upgrade"] = "websocket";
- headers["Connection"] = "Upgrade";
-
- return ret;
- }
-
- internal static HttpResponse Parse (string[] messageHeader)
- {
- var len = messageHeader.Length;
-
- if (len == 0) {
- var msg = "An empty response header.";
-
- throw new ArgumentException (msg);
- }
-
- var slParts = messageHeader[0].Split (new[] { ' ' }, 3);
- var plen = slParts.Length;
-
- if (plen < 2) {
- var msg = "It includes an invalid status line.";
-
- throw new ArgumentException (msg);
- }
-
- var code = slParts[1].ToInt32 ();
- var reason = plen == 3 ? slParts[2] : null;
- var ver = slParts[0].Substring (5).ToVersion ();
-
- var headers = new WebHeaderCollection ();
-
- for (var i = 1; i < len; i++)
- headers.InternalSet (messageHeader[i], true);
-
- return new HttpResponse (code, reason, ver, headers);
- }
-
- internal static HttpResponse ReadResponse (
- Stream stream,
- int millisecondsTimeout
- )
- {
- return Read (stream, Parse, millisecondsTimeout);
- }
-
- #endregion
-
- #region Public Methods
-
- public void SetCookies (CookieCollection cookies)
- {
- if (cookies == null || cookies.Count == 0)
- return;
-
- var headers = Headers;
-
- foreach (var cookie in cookies.SortedList) {
- var val = cookie.ToResponseString ();
-
- headers.Add ("Set-Cookie", val);
- }
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/LogData.cs b/websocket-sharp/LogData.cs
deleted file mode 100644
index bb3492a9b..000000000
--- a/websocket-sharp/LogData.cs
+++ /dev/null
@@ -1,159 +0,0 @@
-#region License
-/*
- * LogData.cs
- *
- * The MIT License
- *
- * Copyright (c) 2013-2024 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-using System;
-using System.Diagnostics;
-using System.Text;
-
-namespace WebSocketSharp
-{
- ///
- /// Represents a log data used by the class.
- ///
- public class LogData
- {
- #region Private Fields
-
- private StackFrame _caller;
- private DateTime _date;
- private LogLevel _level;
- private string _message;
-
- #endregion
-
- #region Internal Constructors
-
- internal LogData (LogLevel level, StackFrame caller, string message)
- {
- _level = level;
- _caller = caller;
- _message = message ?? String.Empty;
-
- _date = DateTime.Now;
- }
-
- #endregion
-
- #region Public Properties
-
- ///
- /// Gets the information of the logging method caller.
- ///
- ///
- /// A that provides the information of
- /// the logging method caller.
- ///
- public StackFrame Caller {
- get {
- return _caller;
- }
- }
-
- ///
- /// Gets the date and time when the log data was created.
- ///
- ///
- /// A that represents the date and time when
- /// the log data was created.
- ///
- public DateTime Date {
- get {
- return _date;
- }
- }
-
- ///
- /// Gets the logging level of the log data.
- ///
- ///
- ///
- /// One of the enum values.
- ///
- ///
- /// It represents the logging level of the log data.
- ///
- ///
- public LogLevel Level {
- get {
- return _level;
- }
- }
-
- ///
- /// Gets the message of the log data.
- ///
- ///
- /// A that represents the message of the log data.
- ///
- public string Message {
- get {
- return _message;
- }
- }
-
- #endregion
-
- #region Public Methods
-
- ///
- /// Returns a string that represents the current instance.
- ///
- ///
- /// A that represents the current instance.
- ///
- public override string ToString ()
- {
- var date = String.Format ("[{0}]", _date);
- var level = String.Format ("{0,-5}", _level.ToString ().ToUpper ());
-
- var method = _caller.GetMethod ();
- var type = method.DeclaringType;
-#if DEBUG
- var num = _caller.GetFileLineNumber ();
- var caller = String.Format ("{0}.{1}:{2}", type.Name, method.Name, num);
-#else
- var caller = String.Format ("{0}.{1}", type.Name, method.Name);
-#endif
- var msgs = _message.Replace ("\r\n", "\n").TrimEnd ('\n').Split ('\n');
-
- if (msgs.Length <= 1)
- return String.Format ("{0} {1} {2} {3}", date, level, caller, _message);
-
- var buff = new StringBuilder (64);
-
- buff.AppendFormat ("{0} {1} {2}\n\n", date, level, caller);
-
- foreach (var msg in msgs)
- buff.AppendFormat (" {0}\n", msg);
-
- return buff.ToString ();
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/LogLevel.cs b/websocket-sharp/LogLevel.cs
deleted file mode 100644
index 5ff1d8fed..000000000
--- a/websocket-sharp/LogLevel.cs
+++ /dev/null
@@ -1,67 +0,0 @@
-#region License
-/*
- * LogLevel.cs
- *
- * The MIT License
- *
- * Copyright (c) 2013-2022 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-using System;
-
-namespace WebSocketSharp
-{
- ///
- /// Specifies the logging level.
- ///
- public enum LogLevel
- {
- ///
- /// Specifies the bottom logging level.
- ///
- Trace,
- ///
- /// Specifies the 2nd logging level from the bottom.
- ///
- Debug,
- ///
- /// Specifies the 3rd logging level from the bottom.
- ///
- Info,
- ///
- /// Specifies the 3rd logging level from the top.
- ///
- Warn,
- ///
- /// Specifies the 2nd logging level from the top.
- ///
- Error,
- ///
- /// Specifies the top logging level.
- ///
- Fatal,
- ///
- /// Specifies not to output logs.
- ///
- None
- }
-}
diff --git a/websocket-sharp/Logger.cs b/websocket-sharp/Logger.cs
deleted file mode 100644
index a280ce43f..000000000
--- a/websocket-sharp/Logger.cs
+++ /dev/null
@@ -1,345 +0,0 @@
-#region License
-/*
- * Logger.cs
- *
- * The MIT License
- *
- * Copyright (c) 2013-2024 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-using System;
-using System.Diagnostics;
-using System.IO;
-
-namespace WebSocketSharp
-{
- ///
- /// Provides a set of methods and properties for logging.
- ///
- ///
- ///
- /// If you output a log with lower than the current logging level,
- /// it cannot be outputted.
- ///
- ///
- /// The default output method writes a log to the standard output
- /// stream and the text file if it has a valid path.
- ///
- ///
- /// If you would like to use the custom output method, you should
- /// specify it with the constructor or the
- /// property.
- ///
- ///
- public class Logger
- {
- #region Private Fields
-
- private volatile string _file;
- private volatile LogLevel _level;
- private Action _output;
- private object _sync;
-
- #endregion
-
- #region Public Constructors
-
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- /// This constructor initializes the logging level with the Error level.
- ///
- public Logger ()
- : this (LogLevel.Error, null, null)
- {
- }
-
- ///
- /// Initializes a new instance of the class with
- /// the specified logging level.
- ///
- ///
- /// One of the enum values that specifies
- /// the logging level.
- ///
- public Logger (LogLevel level)
- : this (level, null, null)
- {
- }
-
- ///
- /// Initializes a new instance of the class with
- /// the specified logging level, path to the log file, and delegate
- /// used to output a log.
- ///
- ///
- /// One of the enum values that specifies
- /// the logging level.
- ///
- ///
- /// A that specifies the path to the log file.
- ///
- ///
- /// An that specifies
- /// the delegate used to output a log.
- ///
- public Logger (LogLevel level, string file, Action output)
- {
- _level = level;
- _file = file;
- _output = output ?? defaultOutput;
-
- _sync = new object ();
- }
-
- #endregion
-
- #region Public Properties
-
- ///
- /// Gets or sets the path to the log file.
- ///
- ///
- /// A that represents the path to the log file if any.
- ///
- public string File {
- get {
- return _file;
- }
-
- set {
- lock (_sync)
- _file = value;
- }
- }
-
- ///
- /// Gets or sets the current logging level.
- ///
- ///
- /// A log with lower than the value of this property cannot be outputted.
- ///
- ///
- ///
- /// One of the enum values.
- ///
- ///
- /// It represents the current logging level.
- ///
- ///
- public LogLevel Level {
- get {
- return _level;
- }
-
- set {
- lock (_sync)
- _level = value;
- }
- }
-
- ///
- /// Gets or sets the delegate used to output a log.
- ///
- ///
- ///
- /// An delegate.
- ///
- ///
- /// It represents the delegate called when the logger outputs a log.
- ///
- ///
- /// The string parameter passed to the delegate is the value of
- /// the property.
- ///
- ///
- /// If the value to set is , the default
- /// output method is set.
- ///
- ///
- public Action Output {
- get {
- return _output;
- }
-
- set {
- lock (_sync)
- _output = value ?? defaultOutput;
- }
- }
-
- #endregion
-
- #region Private Methods
-
- private static void defaultOutput (LogData data, string path)
- {
- var val = data.ToString ();
-
- Console.WriteLine (val);
-
- if (path != null && path.Length > 0)
- writeToFile (val, path);
- }
-
- private void output (string message, LogLevel level)
- {
- lock (_sync) {
- if (_level > level)
- return;
-
- try {
- var data = new LogData (level, new StackFrame (2, true), message);
-
- _output (data, _file);
- }
- catch (Exception ex) {
- var data = new LogData (
- LogLevel.Fatal,
- new StackFrame (0, true),
- ex.Message
- );
-
- Console.WriteLine (data.ToString ());
- }
- }
- }
-
- private static void writeToFile (string value, string path)
- {
- using (var writer = new StreamWriter (path, true))
- using (var syncWriter = TextWriter.Synchronized (writer))
- syncWriter.WriteLine (value);
- }
-
- #endregion
-
- #region Public Methods
-
- ///
- /// Outputs the specified message as a log with the Debug level.
- ///
- ///
- /// If the current logging level is higher than the Debug level,
- /// this method does not output the message as a log.
- ///
- ///
- /// A that specifies the message to output.
- ///
- public void Debug (string message)
- {
- if (_level > LogLevel.Debug)
- return;
-
- output (message, LogLevel.Debug);
- }
-
- ///
- /// Outputs the specified message as a log with the Error level.
- ///
- ///
- /// If the current logging level is higher than the Error level,
- /// this method does not output the message as a log.
- ///
- ///
- /// A that specifies the message to output.
- ///
- public void Error (string message)
- {
- if (_level > LogLevel.Error)
- return;
-
- output (message, LogLevel.Error);
- }
-
- ///
- /// Outputs the specified message as a log with the Fatal level.
- ///
- ///
- /// A that specifies the message to output.
- ///
- public void Fatal (string message)
- {
- if (_level > LogLevel.Fatal)
- return;
-
- output (message, LogLevel.Fatal);
- }
-
- ///
- /// Outputs the specified message as a log with the Info level.
- ///
- ///
- /// If the current logging level is higher than the Info level,
- /// this method does not output the message as a log.
- ///
- ///
- /// A that specifies the message to output.
- ///
- public void Info (string message)
- {
- if (_level > LogLevel.Info)
- return;
-
- output (message, LogLevel.Info);
- }
-
- ///
- /// Outputs the specified message as a log with the Trace level.
- ///
- ///
- /// If the current logging level is higher than the Trace level,
- /// this method does not output the message as a log.
- ///
- ///
- /// A that specifies the message to output.
- ///
- public void Trace (string message)
- {
- if (_level > LogLevel.Trace)
- return;
-
- output (message, LogLevel.Trace);
- }
-
- ///
- /// Outputs the specified message as a log with the Warn level.
- ///
- ///
- /// If the current logging level is higher than the Warn level,
- /// this method does not output the message as a log.
- ///
- ///
- /// A that specifies the message to output.
- ///
- public void Warn (string message)
- {
- if (_level > LogLevel.Warn)
- return;
-
- output (message, LogLevel.Warn);
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Mask.cs b/websocket-sharp/Mask.cs
deleted file mode 100644
index 2958f5a83..000000000
--- a/websocket-sharp/Mask.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-#region License
-/*
- * Mask.cs
- *
- * The MIT License
- *
- * Copyright (c) 2012-2025 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-using System;
-
-namespace WebSocketSharp
-{
- ///
- /// Indicates whether the payload data of a WebSocket frame is masked.
- ///
- ///
- /// The values of this enumeration are defined in
- ///
- /// Section 5.2 of RFC 6455.
- ///
- internal enum Mask
- {
- ///
- /// Equivalent to numeric value 0. Indicates not masked.
- ///
- Off = 0x0,
- ///
- /// Equivalent to numeric value 1. Indicates masked.
- ///
- On = 0x1
- }
-}
diff --git a/websocket-sharp/MessageEventArgs.cs b/websocket-sharp/MessageEventArgs.cs
deleted file mode 100644
index 63add90f7..000000000
--- a/websocket-sharp/MessageEventArgs.cs
+++ /dev/null
@@ -1,192 +0,0 @@
-#region License
-/*
- * MessageEventArgs.cs
- *
- * The MIT License
- *
- * Copyright (c) 2012-2022 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-using System;
-
-namespace WebSocketSharp
-{
- ///
- /// Represents the event data for the event.
- ///
- ///
- ///
- /// The message event occurs when the interface
- /// receives a message or a ping if the
- /// property is set to true.
- ///
- ///
- /// If you would like to get the message data, you should access
- /// the or property.
- ///
- ///
- public class MessageEventArgs : EventArgs
- {
- #region Private Fields
-
- private string _data;
- private bool _dataSet;
- private Opcode _opcode;
- private byte[] _rawData;
-
- #endregion
-
- #region Internal Constructors
-
- internal MessageEventArgs (WebSocketFrame frame)
- {
- _opcode = frame.Opcode;
- _rawData = frame.PayloadData.ApplicationData;
- }
-
- internal MessageEventArgs (Opcode opcode, byte[] rawData)
- {
- if ((ulong) rawData.LongLength > PayloadData.MaxLength)
- throw new WebSocketException (CloseStatusCode.TooBig);
-
- _opcode = opcode;
- _rawData = rawData;
- }
-
- #endregion
-
- #region Internal Properties
-
- ///
- /// Gets the opcode for the message.
- ///
- ///
- /// , ,
- /// or .
- ///
- internal Opcode Opcode {
- get {
- return _opcode;
- }
- }
-
- #endregion
-
- #region Public Properties
-
- ///
- /// Gets the message data as a .
- ///
- ///
- ///
- /// A that represents the message data
- /// if the message type is text or ping.
- ///
- ///
- /// if the message type is binary or
- /// the message data could not be UTF-8-decoded.
- ///
- ///
- public string Data {
- get {
- setData ();
-
- return _data;
- }
- }
-
- ///
- /// Gets a value indicating whether the message type is binary.
- ///
- ///
- /// true if the message type is binary; otherwise, false.
- ///
- public bool IsBinary {
- get {
- return _opcode == Opcode.Binary;
- }
- }
-
- ///
- /// Gets a value indicating whether the message type is ping.
- ///
- ///
- /// true if the message type is ping; otherwise, false.
- ///
- public bool IsPing {
- get {
- return _opcode == Opcode.Ping;
- }
- }
-
- ///
- /// Gets a value indicating whether the message type is text.
- ///
- ///
- /// true if the message type is text; otherwise, false.
- ///
- public bool IsText {
- get {
- return _opcode == Opcode.Text;
- }
- }
-
- ///
- /// Gets the message data as an array of .
- ///
- ///
- /// An array of that represents the message data.
- ///
- public byte[] RawData {
- get {
- setData ();
-
- return _rawData;
- }
- }
-
- #endregion
-
- #region Private Methods
-
- private void setData ()
- {
- if (_dataSet)
- return;
-
- if (_opcode == Opcode.Binary) {
- _dataSet = true;
-
- return;
- }
-
- string data;
-
- if (_rawData.TryGetUTF8DecodedString (out data))
- _data = data;
-
- _dataSet = true;
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Net/AuthenticationChallenge.cs b/websocket-sharp/Net/AuthenticationChallenge.cs
deleted file mode 100644
index 726740801..000000000
--- a/websocket-sharp/Net/AuthenticationChallenge.cs
+++ /dev/null
@@ -1,280 +0,0 @@
-#region License
-/*
- * AuthenticationChallenge.cs
- *
- * The MIT License
- *
- * Copyright (c) 2013-2024 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-using System;
-using System.Collections.Specialized;
-using System.Text;
-
-namespace WebSocketSharp.Net
-{
- internal class AuthenticationChallenge
- {
- #region Private Fields
-
- private NameValueCollection _parameters;
- private AuthenticationSchemes _scheme;
-
- #endregion
-
- #region Private Constructors
-
- private AuthenticationChallenge (
- AuthenticationSchemes scheme,
- NameValueCollection parameters
- )
- {
- _scheme = scheme;
- _parameters = parameters;
- }
-
- #endregion
-
- #region Internal Constructors
-
- internal AuthenticationChallenge (
- AuthenticationSchemes scheme,
- string realm
- )
- : this (scheme, new NameValueCollection ())
- {
- _parameters["realm"] = realm;
-
- if (scheme == AuthenticationSchemes.Digest) {
- _parameters["nonce"] = CreateNonceValue ();
- _parameters["algorithm"] = "MD5";
- _parameters["qop"] = "auth";
- }
- }
-
- #endregion
-
- #region Internal Properties
-
- internal NameValueCollection Parameters {
- get {
- return _parameters;
- }
- }
-
- #endregion
-
- #region Public Properties
-
- public string Algorithm {
- get {
- return _parameters["algorithm"];
- }
- }
-
- public string Domain {
- get {
- return _parameters["domain"];
- }
- }
-
- public string Nonce {
- get {
- return _parameters["nonce"];
- }
- }
-
- public string Opaque {
- get {
- return _parameters["opaque"];
- }
- }
-
- public string Qop {
- get {
- return _parameters["qop"];
- }
- }
-
- public string Realm {
- get {
- return _parameters["realm"];
- }
- }
-
- public AuthenticationSchemes Scheme {
- get {
- return _scheme;
- }
- }
-
- public string Stale {
- get {
- return _parameters["stale"];
- }
- }
-
- #endregion
-
- #region Internal Methods
-
- internal static AuthenticationChallenge CreateBasicChallenge (string realm)
- {
- return new AuthenticationChallenge (AuthenticationSchemes.Basic, realm);
- }
-
- internal static AuthenticationChallenge CreateDigestChallenge (string realm)
- {
- return new AuthenticationChallenge (AuthenticationSchemes.Digest, realm);
- }
-
- internal static string CreateNonceValue ()
- {
- var rand = new Random ();
- var bytes = new byte[16];
-
- rand.NextBytes (bytes);
-
- var buff = new StringBuilder (32);
-
- foreach (var b in bytes)
- buff.Append (b.ToString ("x2"));
-
- return buff.ToString ();
- }
-
- internal static AuthenticationChallenge Parse (string value)
- {
- var chal = value.Split (new[] { ' ' }, 2);
-
- if (chal.Length != 2)
- return null;
-
- var schm = chal[0].ToLower ();
-
- if (schm == "basic") {
- var parameters = ParseParameters (chal[1]);
-
- return new AuthenticationChallenge (
- AuthenticationSchemes.Basic,
- parameters
- );
- }
-
- if (schm == "digest") {
- var parameters = ParseParameters (chal[1]);
-
- return new AuthenticationChallenge (
- AuthenticationSchemes.Digest,
- parameters
- );
- }
-
- return null;
- }
-
- internal static NameValueCollection ParseParameters (string value)
- {
- var ret = new NameValueCollection ();
-
- foreach (var param in value.SplitHeaderValue (',')) {
- var i = param.IndexOf ('=');
-
- var name = i > 0 ? param.Substring (0, i).Trim () : null;
- var val = i < 0
- ? param.Trim ().Trim ('"')
- : i < param.Length - 1
- ? param.Substring (i + 1).Trim ().Trim ('"')
- : String.Empty;
-
- ret.Add (name, val);
- }
-
- return ret;
- }
-
- internal string ToBasicString ()
- {
- return String.Format ("Basic realm=\"{0}\"", _parameters["realm"]);
- }
-
- internal string ToDigestString ()
- {
- var buff = new StringBuilder (128);
-
- var domain = _parameters["domain"];
- var realm = _parameters["realm"];
- var nonce = _parameters["nonce"];
-
- if (domain != null) {
- buff.AppendFormat (
- "Digest realm=\"{0}\", domain=\"{1}\", nonce=\"{2}\"",
- realm,
- domain,
- nonce
- );
- }
- else {
- buff.AppendFormat ("Digest realm=\"{0}\", nonce=\"{1}\"", realm, nonce);
- }
-
- var opaque = _parameters["opaque"];
-
- if (opaque != null)
- buff.AppendFormat (", opaque=\"{0}\"", opaque);
-
- var stale = _parameters["stale"];
-
- if (stale != null)
- buff.AppendFormat (", stale={0}", stale);
-
- var algo = _parameters["algorithm"];
-
- if (algo != null)
- buff.AppendFormat (", algorithm={0}", algo);
-
- var qop = _parameters["qop"];
-
- if (qop != null)
- buff.AppendFormat (", qop=\"{0}\"", qop);
-
- return buff.ToString ();
- }
-
- #endregion
-
- #region Public Methods
-
- public override string ToString ()
- {
- if (_scheme == AuthenticationSchemes.Basic)
- return ToBasicString ();
-
- if (_scheme == AuthenticationSchemes.Digest)
- return ToDigestString ();
-
- return String.Empty;
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Net/AuthenticationResponse.cs b/websocket-sharp/Net/AuthenticationResponse.cs
deleted file mode 100644
index 28fbd2236..000000000
--- a/websocket-sharp/Net/AuthenticationResponse.cs
+++ /dev/null
@@ -1,464 +0,0 @@
-#region License
-/*
- * AuthenticationResponse.cs
- *
- * The ParseBasicCredentials method is derived from HttpListenerContext.cs
- * (System.Net) of Mono (http://www.mono-project.com).
- *
- * The MIT License
- *
- * Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
- * Copyright (c) 2013-2024 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-using System;
-using System.Collections.Specialized;
-using System.Security.Cryptography;
-using System.Security.Principal;
-using System.Text;
-
-namespace WebSocketSharp.Net
-{
- internal class AuthenticationResponse
- {
- #region Private Fields
-
- private uint _nonceCount;
- private NameValueCollection _parameters;
- private AuthenticationSchemes _scheme;
-
- #endregion
-
- #region Private Constructors
-
- private AuthenticationResponse (
- AuthenticationSchemes scheme,
- NameValueCollection parameters
- )
- {
- _scheme = scheme;
- _parameters = parameters;
- }
-
- #endregion
-
- #region Internal Constructors
-
- internal AuthenticationResponse (NetworkCredential credentials)
- : this (
- AuthenticationSchemes.Basic,
- new NameValueCollection (),
- credentials,
- 0
- )
- {
- }
-
- internal AuthenticationResponse (
- AuthenticationChallenge challenge,
- NetworkCredential credentials,
- uint nonceCount
- )
- : this (challenge.Scheme, challenge.Parameters, credentials, nonceCount)
- {
- }
-
- internal AuthenticationResponse (
- AuthenticationSchemes scheme,
- NameValueCollection parameters,
- NetworkCredential credentials,
- uint nonceCount
- )
- : this (scheme, parameters)
- {
- _parameters["username"] = credentials.Username;
- _parameters["password"] = credentials.Password;
- _parameters["uri"] = credentials.Domain;
- _nonceCount = nonceCount;
-
- if (scheme == AuthenticationSchemes.Digest)
- initAsDigest ();
- }
-
- #endregion
-
- #region Internal Properties
-
- internal uint NonceCount {
- get {
- return _nonceCount < UInt32.MaxValue ? _nonceCount : 0;
- }
- }
-
- internal NameValueCollection Parameters {
- get {
- return _parameters;
- }
- }
-
- #endregion
-
- #region Public Properties
-
- public string Algorithm {
- get {
- return _parameters["algorithm"];
- }
- }
-
- public string Cnonce {
- get {
- return _parameters["cnonce"];
- }
- }
-
- public string Nc {
- get {
- return _parameters["nc"];
- }
- }
-
- public string Nonce {
- get {
- return _parameters["nonce"];
- }
- }
-
- public string Opaque {
- get {
- return _parameters["opaque"];
- }
- }
-
- public string Password {
- get {
- return _parameters["password"];
- }
- }
-
- public string Qop {
- get {
- return _parameters["qop"];
- }
- }
-
- public string Realm {
- get {
- return _parameters["realm"];
- }
- }
-
- public string Response {
- get {
- return _parameters["response"];
- }
- }
-
- public AuthenticationSchemes Scheme {
- get {
- return _scheme;
- }
- }
-
- public string Uri {
- get {
- return _parameters["uri"];
- }
- }
-
- public string UserName {
- get {
- return _parameters["username"];
- }
- }
-
- #endregion
-
- #region Private Methods
-
- private static string createA1 (
- string username,
- string password,
- string realm
- )
- {
- return String.Format ("{0}:{1}:{2}", username, realm, password);
- }
-
- private static string createA1 (
- string username,
- string password,
- string realm,
- string nonce,
- string cnonce
- )
- {
- var a1 = createA1 (username, password, realm);
-
- return String.Format ("{0}:{1}:{2}", hash (a1), nonce, cnonce);
- }
-
- private static string createA2 (string method, string uri)
- {
- return String.Format ("{0}:{1}", method, uri);
- }
-
- private static string createA2 (string method, string uri, string entity)
- {
- return String.Format ("{0}:{1}:{2}", method, uri, hash (entity));
- }
-
- private static string hash (string value)
- {
- var buff = new StringBuilder (64);
-
- var md5 = MD5.Create ();
- var bytes = Encoding.UTF8.GetBytes (value);
- var res = md5.ComputeHash (bytes);
-
- foreach (var b in res)
- buff.Append (b.ToString ("x2"));
-
- return buff.ToString ();
- }
-
- private void initAsDigest ()
- {
- var qops = _parameters["qop"];
-
- if (qops != null) {
- var hasAuth = qops.Split (',').Contains (
- qop => qop.Trim ().ToLower () == "auth"
- );
-
- if (hasAuth) {
- _parameters["qop"] = "auth";
- _parameters["cnonce"] = AuthenticationChallenge.CreateNonceValue ();
- _parameters["nc"] = String.Format ("{0:x8}", ++_nonceCount);
- }
- else {
- _parameters["qop"] = null;
- }
- }
-
- _parameters["method"] = "GET";
- _parameters["response"] = CreateRequestDigest (_parameters);
- }
-
- #endregion
-
- #region Internal Methods
-
- internal static string CreateRequestDigest (NameValueCollection parameters)
- {
- var uname = parameters["username"];
- var passwd = parameters["password"];
- var realm = parameters["realm"];
- var nonce = parameters["nonce"];
- var uri = parameters["uri"];
- var algo = parameters["algorithm"];
- var qop = parameters["qop"];
- var cnonce = parameters["cnonce"];
- var nc = parameters["nc"];
- var method = parameters["method"];
-
- var a1 = algo != null && algo.ToLower () == "md5-sess"
- ? createA1 (uname, passwd, realm, nonce, cnonce)
- : createA1 (uname, passwd, realm);
-
- var a2 = qop != null && qop.ToLower () == "auth-int"
- ? createA2 (method, uri, parameters["entity"])
- : createA2 (method, uri);
-
- var secret = hash (a1);
- var data = qop != null
- ? String.Format (
- "{0}:{1}:{2}:{3}:{4}",
- nonce,
- nc,
- cnonce,
- qop,
- hash (a2)
- )
- : String.Format ("{0}:{1}", nonce, hash (a2));
-
- var keyed = String.Format ("{0}:{1}", secret, data);
-
- return hash (keyed);
- }
-
- internal static AuthenticationResponse Parse (string value)
- {
- try {
- var cred = value.Split (new[] { ' ' }, 2);
-
- if (cred.Length != 2)
- return null;
-
- var schm = cred[0].ToLower ();
-
- if (schm == "basic") {
- var parameters = ParseBasicCredentials (cred[1]);
-
- return new AuthenticationResponse (
- AuthenticationSchemes.Basic,
- parameters
- );
- }
-
- if (schm == "digest") {
- var parameters = AuthenticationChallenge.ParseParameters (cred[1]);
-
- return new AuthenticationResponse (
- AuthenticationSchemes.Digest,
- parameters
- );
- }
-
- return null;
- }
- catch {
- return null;
- }
- }
-
- internal static NameValueCollection ParseBasicCredentials (string value)
- {
- var ret = new NameValueCollection ();
-
- // Decode the basic-credentials (a Base64 encoded string).
-
- var bytes = Convert.FromBase64String (value);
- var userPass = Encoding.UTF8.GetString (bytes);
-
- // The format is [\]:.
-
- var idx = userPass.IndexOf (':');
- var uname = userPass.Substring (0, idx);
- var passwd = idx < userPass.Length - 1
- ? userPass.Substring (idx + 1)
- : String.Empty;
-
- // Check if exists.
-
- idx = uname.IndexOf ('\\');
-
- if (idx > -1)
- uname = uname.Substring (idx + 1);
-
- ret["username"] = uname;
- ret["password"] = passwd;
-
- return ret;
- }
-
- internal string ToBasicString ()
- {
- var uname = _parameters["username"];
- var passwd = _parameters["password"];
- var userPass = String.Format ("{0}:{1}", uname, passwd);
-
- var bytes = Encoding.UTF8.GetBytes (userPass);
- var cred = Convert.ToBase64String (bytes);
-
- return "Basic " + cred;
- }
-
- internal string ToDigestString ()
- {
- var buff = new StringBuilder (256);
-
- var uname = _parameters["username"];
- var realm = _parameters["realm"];
- var nonce = _parameters["nonce"];
- var uri = _parameters["uri"];
- var res = _parameters["response"];
-
- buff.AppendFormat (
- "Digest username=\"{0}\", realm=\"{1}\", nonce=\"{2}\", uri=\"{3}\", response=\"{4}\"",
- uname,
- realm,
- nonce,
- uri,
- res
- );
-
- var opaque = _parameters["opaque"];
-
- if (opaque != null)
- buff.AppendFormat (", opaque=\"{0}\"", opaque);
-
- var algo = _parameters["algorithm"];
-
- if (algo != null)
- buff.AppendFormat (", algorithm={0}", algo);
-
- var qop = _parameters["qop"];
-
- if (qop != null) {
- var cnonce = _parameters["cnonce"];
- var nc = _parameters["nc"];
-
- buff.AppendFormat (
- ", qop={0}, cnonce=\"{1}\", nc={2}",
- qop,
- cnonce,
- nc
- );
- }
-
- return buff.ToString ();
- }
-
- #endregion
-
- #region Public Methods
-
- public IIdentity ToIdentity ()
- {
- if (_scheme == AuthenticationSchemes.Basic) {
- var uname = _parameters["username"];
- var passwd = _parameters["password"];
-
- return new HttpBasicIdentity (uname, passwd);
- }
-
- if (_scheme == AuthenticationSchemes.Digest)
- return new HttpDigestIdentity (_parameters);
-
- return null;
- }
-
- public override string ToString ()
- {
- if (_scheme == AuthenticationSchemes.Basic)
- return ToBasicString ();
-
- if (_scheme == AuthenticationSchemes.Digest)
- return ToDigestString ();
-
- return String.Empty;
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Net/AuthenticationSchemes.cs b/websocket-sharp/Net/AuthenticationSchemes.cs
deleted file mode 100644
index ab7721a15..000000000
--- a/websocket-sharp/Net/AuthenticationSchemes.cs
+++ /dev/null
@@ -1,66 +0,0 @@
-#region License
-/*
- * AuthenticationSchemes.cs
- *
- * This code is derived from AuthenticationSchemes.cs (System.Net) of Mono
- * (http://www.mono-project.com).
- *
- * The MIT License
- *
- * Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
- * Copyright (c) 2012-2016 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-#region Authors
-/*
- * Authors:
- * - Atsushi Enomoto
- */
-#endregion
-
-using System;
-
-namespace WebSocketSharp.Net
-{
- ///
- /// Specifies the scheme for authentication.
- ///
- public enum AuthenticationSchemes
- {
- ///
- /// No authentication is allowed.
- ///
- None,
- ///
- /// Specifies digest authentication.
- ///
- Digest = 1,
- ///
- /// Specifies basic authentication.
- ///
- Basic = 8,
- ///
- /// Specifies anonymous authentication.
- ///
- Anonymous = 0x8000
- }
-}
diff --git a/websocket-sharp/Net/Chunk.cs b/websocket-sharp/Net/Chunk.cs
deleted file mode 100644
index 9ed28f864..000000000
--- a/websocket-sharp/Net/Chunk.cs
+++ /dev/null
@@ -1,93 +0,0 @@
-#region License
-/*
- * Chunk.cs
- *
- * This code is derived from ChunkStream.cs (System.Net) of Mono
- * (http://www.mono-project.com).
- *
- * The MIT License
- *
- * Copyright (c) 2003 Ximian, Inc (http://www.ximian.com)
- * Copyright (c) 2014-2021 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-#region Authors
-/*
- * Authors:
- * - Gonzalo Paniagua Javier
- */
-#endregion
-
-using System;
-
-namespace WebSocketSharp.Net
-{
- internal class Chunk
- {
- #region Private Fields
-
- private byte[] _data;
- private int _offset;
-
- #endregion
-
- #region Public Constructors
-
- public Chunk (byte[] data)
- {
- _data = data;
- }
-
- #endregion
-
- #region Public Properties
-
- public int ReadLeft {
- get {
- return _data.Length - _offset;
- }
- }
-
- #endregion
-
- #region Public Methods
-
- public int Read (byte[] buffer, int offset, int count)
- {
- var left = _data.Length - _offset;
-
- if (left == 0)
- return 0;
-
- if (count > left)
- count = left;
-
- Buffer.BlockCopy (_data, _offset, buffer, offset, count);
-
- _offset += count;
-
- return count;
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Net/ChunkStream.cs b/websocket-sharp/Net/ChunkStream.cs
deleted file mode 100644
index 3de4374db..000000000
--- a/websocket-sharp/Net/ChunkStream.cs
+++ /dev/null
@@ -1,429 +0,0 @@
-#region License
-/*
- * ChunkStream.cs
- *
- * This code is derived from ChunkStream.cs (System.Net) of Mono
- * (http://www.mono-project.com).
- *
- * The MIT License
- *
- * Copyright (c) 2003 Ximian, Inc (http://www.ximian.com)
- * Copyright (c) 2012-2023 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-#region Authors
-/*
- * Authors:
- * - Gonzalo Paniagua Javier
- */
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
-using System.Net;
-using System.Text;
-
-namespace WebSocketSharp.Net
-{
- internal class ChunkStream
- {
- #region Private Fields
-
- private int _chunkRead;
- private int _chunkSize;
- private List _chunks;
- private int _count;
- private byte[] _endBuffer;
- private bool _gotIt;
- private WebHeaderCollection _headers;
- private int _offset;
- private StringBuilder _saved;
- private bool _sawCr;
- private InputChunkState _state;
- private int _trailerState;
-
- #endregion
-
- #region Public Constructors
-
- public ChunkStream (WebHeaderCollection headers)
- {
- _headers = headers;
-
- _chunkSize = -1;
- _chunks = new List ();
- _saved = new StringBuilder ();
- }
-
- #endregion
-
- #region Internal Properties
-
- internal int Count {
- get {
- return _count;
- }
- }
-
- internal byte[] EndBuffer {
- get {
- return _endBuffer;
- }
- }
-
- internal int Offset {
- get {
- return _offset;
- }
- }
-
- #endregion
-
- #region Public Properties
-
- public WebHeaderCollection Headers {
- get {
- return _headers;
- }
- }
-
- public bool WantsMore {
- get {
- return _state < InputChunkState.End;
- }
- }
-
- #endregion
-
- #region Private Methods
-
- private int read (byte[] buffer, int offset, int count)
- {
- var nread = 0;
- var cnt = _chunks.Count;
-
- for (var i = 0; i < cnt; i++) {
- var chunk = _chunks[i];
-
- if (chunk == null)
- continue;
-
- if (chunk.ReadLeft == 0) {
- _chunks[i] = null;
-
- continue;
- }
-
- nread += chunk.Read (buffer, offset + nread, count - nread);
-
- if (nread == count)
- break;
- }
-
- return nread;
- }
-
- private InputChunkState seekCrLf (byte[] buffer, ref int offset, int length)
- {
- if (!_sawCr) {
- if (buffer[offset++] != 13)
- throwProtocolViolation ("CR is expected.");
-
- _sawCr = true;
-
- if (offset == length)
- return InputChunkState.DataEnded;
- }
-
- if (buffer[offset++] != 10)
- throwProtocolViolation ("LF is expected.");
-
- return InputChunkState.None;
- }
-
- private InputChunkState setChunkSize (
- byte[] buffer,
- ref int offset,
- int length
- )
- {
- byte b = 0;
-
- while (offset < length) {
- b = buffer[offset++];
-
- if (_sawCr) {
- if (b != 10)
- throwProtocolViolation ("LF is expected.");
-
- break;
- }
-
- if (b == 13) {
- _sawCr = true;
-
- continue;
- }
-
- if (b == 10)
- throwProtocolViolation ("LF is unexpected.");
-
- if (_gotIt)
- continue;
-
- if (b == 32 || b == 59) { // SP or ';'
- _gotIt = true;
-
- continue;
- }
-
- _saved.Append ((char) b);
- }
-
- if (_saved.Length > 20)
- throwProtocolViolation ("The chunk size is too big.");
-
- if (b != 10)
- return InputChunkState.None;
-
- var s = _saved.ToString ();
-
- try {
- _chunkSize = Int32.Parse (s, NumberStyles.HexNumber);
- }
- catch {
- throwProtocolViolation ("The chunk size cannot be parsed.");
- }
-
- _chunkRead = 0;
-
- if (_chunkSize == 0) {
- _trailerState = 2;
-
- return InputChunkState.Trailer;
- }
-
- return InputChunkState.Data;
- }
-
- private InputChunkState setTrailer (
- byte[] buffer,
- ref int offset,
- int length
- )
- {
- while (offset < length) {
- if (_trailerState == 4) // CR LF CR LF
- break;
-
- var b = buffer[offset++];
-
- _saved.Append ((char) b);
-
- if (_trailerState == 1 || _trailerState == 3) { // CR or CR LF CR
- if (b != 10)
- throwProtocolViolation ("LF is expected.");
-
- _trailerState++;
-
- continue;
- }
-
- if (b == 13) {
- _trailerState++;
-
- continue;
- }
-
- if (b == 10)
- throwProtocolViolation ("LF is unexpected.");
-
- _trailerState = 0;
- }
-
- var len = _saved.Length;
-
- if (len > 4196)
- throwProtocolViolation ("The trailer is too long.");
-
- if (_trailerState < 4)
- return InputChunkState.Trailer;
-
- if (len == 2)
- return InputChunkState.End;
-
- _saved.Length = len - 2;
-
- var val = _saved.ToString ();
- var reader = new StringReader (val);
-
- while (true) {
- var line = reader.ReadLine ();
-
- if (line == null || line.Length == 0)
- break;
-
- _headers.Add (line);
- }
-
- return InputChunkState.End;
- }
-
- private static void throwProtocolViolation (string message)
- {
- throw new WebException (
- message,
- null,
- WebExceptionStatus.ServerProtocolViolation,
- null
- );
- }
-
- private void write (byte[] buffer, int offset, int length)
- {
- if (_state == InputChunkState.End)
- throwProtocolViolation ("The chunks were ended.");
-
- if (_state == InputChunkState.None) {
- _state = setChunkSize (buffer, ref offset, length);
-
- if (_state == InputChunkState.None)
- return;
-
- _saved.Length = 0;
- _sawCr = false;
- _gotIt = false;
- }
-
- if (_state == InputChunkState.Data) {
- if (offset >= length)
- return;
-
- _state = writeData (buffer, ref offset, length);
-
- if (_state == InputChunkState.Data)
- return;
- }
-
- if (_state == InputChunkState.DataEnded) {
- if (offset >= length)
- return;
-
- _state = seekCrLf (buffer, ref offset, length);
-
- if (_state == InputChunkState.DataEnded)
- return;
-
- _sawCr = false;
- }
-
- if (_state == InputChunkState.Trailer) {
- if (offset >= length)
- return;
-
- _state = setTrailer (buffer, ref offset, length);
-
- if (_state == InputChunkState.Trailer)
- return;
-
- _saved.Length = 0;
- }
-
- if (_state == InputChunkState.End) {
- _endBuffer = buffer;
- _offset = offset;
- _count = length - offset;
-
- return;
- }
-
- if (offset >= length)
- return;
-
- write (buffer, offset, length);
- }
-
- private InputChunkState writeData (
- byte[] buffer,
- ref int offset,
- int length
- )
- {
- var cnt = length - offset;
- var left = _chunkSize - _chunkRead;
-
- if (cnt > left)
- cnt = left;
-
- var data = new byte[cnt];
-
- Buffer.BlockCopy (buffer, offset, data, 0, cnt);
-
- var chunk = new Chunk (data);
-
- _chunks.Add (chunk);
-
- offset += cnt;
- _chunkRead += cnt;
-
- return _chunkRead == _chunkSize
- ? InputChunkState.DataEnded
- : InputChunkState.Data;
- }
-
- #endregion
-
- #region Internal Methods
-
- internal void ResetChunkStore ()
- {
- _chunkRead = 0;
- _chunkSize = -1;
-
- _chunks.Clear ();
- }
-
- #endregion
-
- #region Public Methods
-
- public int Read (byte[] buffer, int offset, int count)
- {
- if (count <= 0)
- return 0;
-
- return read (buffer, offset, count);
- }
-
- public void Write (byte[] buffer, int offset, int count)
- {
- if (count <= 0)
- return;
-
- write (buffer, offset, offset + count);
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Net/ChunkedRequestStream.cs b/websocket-sharp/Net/ChunkedRequestStream.cs
deleted file mode 100644
index f4a583925..000000000
--- a/websocket-sharp/Net/ChunkedRequestStream.cs
+++ /dev/null
@@ -1,283 +0,0 @@
-#region License
-/*
- * ChunkedRequestStream.cs
- *
- * This code is derived from ChunkedInputStream.cs (System.Net) of Mono
- * (http://www.mono-project.com).
- *
- * The MIT License
- *
- * Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
- * Copyright (c) 2012-2023 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-#region Authors
-/*
- * Authors:
- * - Gonzalo Paniagua Javier
- */
-#endregion
-
-using System;
-using System.IO;
-
-namespace WebSocketSharp.Net
-{
- internal class ChunkedRequestStream : RequestStream
- {
- #region Private Fields
-
- private static readonly int _bufferLength;
- private HttpListenerContext _context;
- private ChunkStream _decoder;
- private bool _disposed;
- private bool _noMoreData;
-
- #endregion
-
- #region Static Constructor
-
- static ChunkedRequestStream ()
- {
- _bufferLength = 8192;
- }
-
- #endregion
-
- #region Internal Constructors
-
- internal ChunkedRequestStream (
- Stream innerStream,
- byte[] initialBuffer,
- int offset,
- int count,
- HttpListenerContext context
- )
- : base (innerStream, initialBuffer, offset, count, -1)
- {
- _context = context;
-
- _decoder = new ChunkStream (
- (WebHeaderCollection) context.Request.Headers
- );
- }
-
- #endregion
-
- #region Internal Properties
-
- internal bool HasRemainingBuffer {
- get {
- return _decoder.Count + Count > 0;
- }
- }
-
- internal byte[] RemainingBuffer {
- get {
- using (var buff = new MemoryStream ()) {
- var cnt = _decoder.Count;
-
- if (cnt > 0)
- buff.Write (_decoder.EndBuffer, _decoder.Offset, cnt);
-
- cnt = Count;
-
- if (cnt > 0)
- buff.Write (InitialBuffer, Offset, cnt);
-
- buff.Close ();
-
- return buff.ToArray ();
- }
- }
- }
-
- #endregion
-
- #region Private Methods
-
- private void onRead (IAsyncResult asyncResult)
- {
- var rstate = (ReadBufferState) asyncResult.AsyncState;
- var ares = rstate.AsyncResult;
-
- try {
- var nread = base.EndRead (asyncResult);
-
- _decoder.Write (ares.Buffer, ares.Offset, nread);
-
- nread = _decoder.Read (rstate.Buffer, rstate.Offset, rstate.Count);
-
- rstate.Offset += nread;
- rstate.Count -= nread;
-
- if (rstate.Count == 0 || !_decoder.WantsMore || nread == 0) {
- _noMoreData = !_decoder.WantsMore && nread == 0;
-
- ares.Count = rstate.InitialCount - rstate.Count;
-
- ares.Complete ();
-
- return;
- }
-
- base.BeginRead (ares.Buffer, ares.Offset, ares.Count, onRead, rstate);
- }
- catch (Exception ex) {
- _context.ErrorMessage = "I/O operation aborted";
-
- _context.SendError ();
-
- ares.Complete (ex);
- }
- }
-
- #endregion
-
- #region Public Methods
-
- public override IAsyncResult BeginRead (
- byte[] buffer,
- int offset,
- int count,
- AsyncCallback callback,
- object state
- )
- {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- if (buffer == null)
- throw new ArgumentNullException ("buffer");
-
- if (offset < 0) {
- var msg = "A negative value.";
-
- throw new ArgumentOutOfRangeException ("offset", msg);
- }
-
- if (count < 0) {
- var msg = "A negative value.";
-
- throw new ArgumentOutOfRangeException ("count", msg);
- }
-
- var len = buffer.Length;
-
- if (offset + count > len) {
- var msg = "The sum of offset and count is greater than the length of buffer.";
-
- throw new ArgumentException (msg);
- }
-
- var ares = new HttpStreamAsyncResult (callback, state);
-
- if (_noMoreData) {
- ares.Complete ();
-
- return ares;
- }
-
- var nread = _decoder.Read (buffer, offset, count);
-
- offset += nread;
- count -= nread;
-
- if (count == 0) {
- ares.Count = nread;
-
- ares.Complete ();
-
- return ares;
- }
-
- if (!_decoder.WantsMore) {
- _noMoreData = nread == 0;
-
- ares.Count = nread;
-
- ares.Complete ();
-
- return ares;
- }
-
- ares.Buffer = new byte[_bufferLength];
- ares.Offset = 0;
- ares.Count = _bufferLength;
-
- var rstate = new ReadBufferState (buffer, offset, count, ares);
-
- rstate.InitialCount += nread;
-
- base.BeginRead (ares.Buffer, ares.Offset, ares.Count, onRead, rstate);
-
- return ares;
- }
-
- public override void Close ()
- {
- if (_disposed)
- return;
-
- base.Close ();
-
- _disposed = true;
- }
-
- public override int EndRead (IAsyncResult asyncResult)
- {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- if (asyncResult == null)
- throw new ArgumentNullException ("asyncResult");
-
- var ares = asyncResult as HttpStreamAsyncResult;
-
- if (ares == null) {
- var msg = "A wrong IAsyncResult instance.";
-
- throw new ArgumentException (msg, "asyncResult");
- }
-
- if (!ares.IsCompleted)
- ares.AsyncWaitHandle.WaitOne ();
-
- if (ares.HasException) {
- var msg = "The I/O operation has been aborted.";
-
- throw new HttpListenerException (995, msg);
- }
-
- return ares.Count;
- }
-
- public override int Read (byte[] buffer, int offset, int count)
- {
- var ares = BeginRead (buffer, offset, count, null, null);
-
- return EndRead (ares);
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Net/ClientSslConfiguration.cs b/websocket-sharp/Net/ClientSslConfiguration.cs
deleted file mode 100644
index 33438a93c..000000000
--- a/websocket-sharp/Net/ClientSslConfiguration.cs
+++ /dev/null
@@ -1,311 +0,0 @@
-#region License
-/*
- * ClientSslConfiguration.cs
- *
- * The MIT License
- *
- * Copyright (c) 2014 liryna
- * Copyright (c) 2014-2024 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-#region Authors
-/*
- * Authors:
- * - Liryna
- */
-#endregion
-
-using System;
-using System.Net.Security;
-using System.Security.Authentication;
-using System.Security.Cryptography.X509Certificates;
-
-namespace WebSocketSharp.Net
-{
- ///
- /// Stores the parameters for an instance used by
- /// a client.
- ///
- public class ClientSslConfiguration
- {
- #region Private Fields
-
- private bool _checkCertRevocation;
- private LocalCertificateSelectionCallback _clientCertSelectionCallback;
- private X509CertificateCollection _clientCerts;
- private SslProtocols _enabledSslProtocols;
- private RemoteCertificateValidationCallback _serverCertValidationCallback;
- private string _targetHost;
-
- #endregion
-
- #region Public Constructors
-
- ///
- /// Initializes a new instance of the
- /// class with the specified target host name.
- ///
- ///
- /// A that specifies the name of the server that
- /// will share a secure connection with the client.
- ///
- ///
- /// is an empty string.
- ///
- ///
- /// is .
- ///
- public ClientSslConfiguration (string targetHost)
- {
- if (targetHost == null)
- throw new ArgumentNullException ("targetHost");
-
- if (targetHost.Length == 0)
- throw new ArgumentException ("An empty string.", "targetHost");
-
- _targetHost = targetHost;
-
- _enabledSslProtocols = SslProtocols.None;
- }
-
- ///
- /// Initializes a new instance of the
- /// class copying from the specified configuration.
- ///
- ///
- /// A from which to copy.
- ///
- ///
- /// is .
- ///
- public ClientSslConfiguration (ClientSslConfiguration configuration)
- {
- if (configuration == null)
- throw new ArgumentNullException ("configuration");
-
- _checkCertRevocation = configuration._checkCertRevocation;
- _clientCertSelectionCallback = configuration._clientCertSelectionCallback;
- _clientCerts = configuration._clientCerts;
- _enabledSslProtocols = configuration._enabledSslProtocols;
- _serverCertValidationCallback = configuration._serverCertValidationCallback;
- _targetHost = configuration._targetHost;
- }
-
- #endregion
-
- #region Public Properties
-
- ///
- /// Gets or sets a value indicating whether the certificate revocation
- /// list is checked during authentication.
- ///
- ///
- ///
- /// true if the certificate revocation list is checked during
- /// authentication; otherwise, false.
- ///
- ///
- /// The default value is false.
- ///
- ///
- public bool CheckCertificateRevocation {
- get {
- return _checkCertRevocation;
- }
-
- set {
- _checkCertRevocation = value;
- }
- }
-
- ///
- /// Gets or sets the collection of the certificates from which to select
- /// one to supply to the server.
- ///
- ///
- ///
- /// A that contains
- /// the certificates from which to select.
- ///
- ///
- /// if not present.
- ///
- ///
- /// The default value is .
- ///
- ///
- public X509CertificateCollection ClientCertificates {
- get {
- return _clientCerts;
- }
-
- set {
- _clientCerts = value;
- }
- }
-
- ///
- /// Gets or sets the callback used to select the certificate to supply to
- /// the server.
- ///
- ///
- /// No certificate is supplied if the callback returns .
- ///
- ///
- ///
- /// A delegate.
- ///
- ///
- /// It represents the delegate called when the client selects
- /// the certificate.
- ///
- ///
- /// The default value invokes a method that only returns
- /// .
- ///
- ///
- public LocalCertificateSelectionCallback ClientCertificateSelectionCallback {
- get {
- if (_clientCertSelectionCallback == null)
- _clientCertSelectionCallback = defaultSelectClientCertificate;
-
- return _clientCertSelectionCallback;
- }
-
- set {
- _clientCertSelectionCallback = value;
- }
- }
-
- ///
- /// Gets or sets the enabled versions of the SSL/TLS protocols.
- ///
- ///
- ///
- /// Any of the enum values.
- ///
- ///
- /// It represents the enabled versions of the SSL/TLS protocols.
- ///
- ///
- /// The default value is .
- ///
- ///
- public SslProtocols EnabledSslProtocols {
- get {
- return _enabledSslProtocols;
- }
-
- set {
- _enabledSslProtocols = value;
- }
- }
-
- ///
- /// Gets or sets the callback used to validate the certificate supplied by
- /// the server.
- ///
- ///
- /// The certificate is valid if the callback returns true.
- ///
- ///
- ///
- /// A delegate.
- ///
- ///
- /// It represents the delegate called when the client validates
- /// the certificate.
- ///
- ///
- /// The default value invokes a method that only returns true.
- ///
- ///
- public RemoteCertificateValidationCallback ServerCertificateValidationCallback {
- get {
- if (_serverCertValidationCallback == null)
- _serverCertValidationCallback = defaultValidateServerCertificate;
-
- return _serverCertValidationCallback;
- }
-
- set {
- _serverCertValidationCallback = value;
- }
- }
-
- ///
- /// Gets or sets the target host name.
- ///
- ///
- /// A that represents the name of the server that
- /// will share a secure connection with the client.
- ///
- ///
- /// The value specified for a set operation is an empty string.
- ///
- ///
- /// The value specified for a set operation is .
- ///
- public string TargetHost {
- get {
- return _targetHost;
- }
-
- set {
- if (value == null)
- throw new ArgumentNullException ("value");
-
- if (value.Length == 0)
- throw new ArgumentException ("An empty string.", "value");
-
- _targetHost = value;
- }
- }
-
- #endregion
-
- #region Private Methods
-
- private static X509Certificate defaultSelectClientCertificate (
- object sender,
- string targetHost,
- X509CertificateCollection clientCertificates,
- X509Certificate serverCertificate,
- string[] acceptableIssuers
- )
- {
- return null;
- }
-
- private static bool defaultValidateServerCertificate (
- object sender,
- X509Certificate certificate,
- X509Chain chain,
- SslPolicyErrors sslPolicyErrors
- )
- {
- return true;
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Net/Cookie.cs b/websocket-sharp/Net/Cookie.cs
deleted file mode 100644
index 149b5041e..000000000
--- a/websocket-sharp/Net/Cookie.cs
+++ /dev/null
@@ -1,1032 +0,0 @@
-#region License
-/*
- * Cookie.cs
- *
- * This code is derived from Cookie.cs (System.Net) of Mono
- * (http://www.mono-project.com).
- *
- * The MIT License
- *
- * Copyright (c) 2004,2009 Novell, Inc. (http://www.novell.com)
- * Copyright (c) 2012-2024 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-#region Authors
-/*
- * Authors:
- * - Lawrence Pit
- * - Gonzalo Paniagua Javier
- * - Daniel Nauck
- * - Sebastien Pouliot
- */
-#endregion
-
-using System;
-using System.Globalization;
-using System.Text;
-
-namespace WebSocketSharp.Net
-{
- ///
- /// Provides a set of methods and properties used to manage an HTTP cookie.
- ///
- ///
- ///
- /// This class refers to the following specifications:
- ///
- ///
- /// -
- ///
- ///
- /// Netscape specification
- ///
- ///
- /// -
- ///
- /// RFC 2109
- ///
- ///
- /// -
- ///
- /// RFC 2965
- ///
- ///
- /// -
- ///
- /// RFC 6265
- ///
- ///
- ///
- ///
- /// This class cannot be inherited.
- ///
- ///
- [Serializable]
- public sealed class Cookie
- {
- #region Private Fields
-
- private string _comment;
- private Uri _commentUri;
- private bool _discard;
- private string _domain;
- private static readonly int[] _emptyPorts;
- private DateTime _expires;
- private bool _httpOnly;
- private string _name;
- private string _path;
- private string _port;
- private int[] _ports;
- private static readonly char[] _reservedCharsForValue;
- private string _sameSite;
- private bool _secure;
- private DateTime _timeStamp;
- private string _value;
- private int _version;
-
- #endregion
-
- #region Static Constructor
-
- static Cookie ()
- {
- _emptyPorts = new int[0];
- _reservedCharsForValue = new[] { ';', ',' };
- }
-
- #endregion
-
- #region Internal Constructors
-
- internal Cookie ()
- {
- init (String.Empty, String.Empty, String.Empty, String.Empty);
- }
-
- #endregion
-
- #region Public Constructors
-
- ///
- /// Initializes a new instance of the class with
- /// the specified name and value.
- ///
- ///
- ///
- /// A that specifies the name of the cookie.
- ///
- ///
- /// The name must be a token defined in
- ///
- /// RFC 2616.
- ///
- ///
- ///
- /// A that specifies the value of the cookie.
- ///
- ///
- ///
- /// is an empty string.
- ///
- ///
- /// -or-
- ///
- ///
- /// starts with a dollar sign.
- ///
- ///
- /// -or-
- ///
- ///
- /// contains an invalid character.
- ///
- ///
- /// -or-
- ///
- ///
- /// is a string not enclosed in double quotes
- /// although it contains a reserved character.
- ///
- ///
- ///
- /// is .
- ///
- public Cookie (string name, string value)
- : this (name, value, String.Empty, String.Empty)
- {
- }
-
- ///
- /// Initializes a new instance of the class with
- /// the specified name, value, and path.
- ///
- ///
- ///
- /// A that specifies the name of the cookie.
- ///
- ///
- /// The name must be a token defined in
- ///
- /// RFC 2616.
- ///
- ///
- ///
- /// A that specifies the value of the cookie.
- ///
- ///
- /// A that specifies the value of the Path
- /// attribute of the cookie.
- ///
- ///
- ///
- /// is an empty string.
- ///
- ///
- /// -or-
- ///
- ///
- /// starts with a dollar sign.
- ///
- ///
- /// -or-
- ///
- ///
- /// contains an invalid character.
- ///
- ///
- /// -or-
- ///
- ///
- /// is a string not enclosed in double quotes
- /// although it contains a reserved character.
- ///
- ///
- ///
- /// is .
- ///
- public Cookie (string name, string value, string path)
- : this (name, value, path, String.Empty)
- {
- }
-
- ///
- /// Initializes a new instance of the class with
- /// the specified name, value, path, and domain.
- ///
- ///
- ///
- /// A that specifies the name of the cookie.
- ///
- ///
- /// The name must be a token defined in
- ///
- /// RFC 2616.
- ///
- ///
- ///
- /// A that specifies the value of the cookie.
- ///
- ///
- /// A that specifies the value of the Path
- /// attribute of the cookie.
- ///
- ///
- /// A that specifies the value of the Domain
- /// attribute of the cookie.
- ///
- ///
- ///
- /// is an empty string.
- ///
- ///
- /// -or-
- ///
- ///
- /// starts with a dollar sign.
- ///
- ///
- /// -or-
- ///
- ///
- /// contains an invalid character.
- ///
- ///
- /// -or-
- ///
- ///
- /// is a string not enclosed in double quotes
- /// although it contains a reserved character.
- ///
- ///
- ///
- /// is .
- ///
- public Cookie (string name, string value, string path, string domain)
- {
- if (name == null)
- throw new ArgumentNullException ("name");
-
- if (name.Length == 0)
- throw new ArgumentException ("An empty string.", "name");
-
- if (name[0] == '$') {
- var msg = "It starts with a dollar sign.";
-
- throw new ArgumentException (msg, "name");
- }
-
- if (!name.IsToken ()) {
- var msg = "It contains an invalid character.";
-
- throw new ArgumentException (msg, "name");
- }
-
- if (value == null)
- value = String.Empty;
-
- if (value.Contains (_reservedCharsForValue)) {
- if (!value.IsEnclosedIn ('"')) {
- var msg = "A string not enclosed in double quotes.";
-
- throw new ArgumentException (msg, "value");
- }
- }
-
- init (name, value, path ?? String.Empty, domain ?? String.Empty);
- }
-
- #endregion
-
- #region Internal Properties
-
- internal bool ExactDomain {
- get {
- return _domain.Length == 0 || _domain[0] != '.';
- }
- }
-
- internal int MaxAge {
- get {
- if (_expires == DateTime.MinValue)
- return 0;
-
- var expires = _expires.Kind != DateTimeKind.Local
- ? _expires.ToLocalTime ()
- : _expires;
-
- var span = expires - DateTime.Now;
-
- return span > TimeSpan.Zero
- ? (int) span.TotalSeconds
- : 0;
- }
-
- set {
- _expires = value > 0
- ? DateTime.Now.AddSeconds ((double) value)
- : DateTime.Now;
- }
- }
-
- internal int[] Ports {
- get {
- return _ports ?? _emptyPorts;
- }
- }
-
- internal string SameSite {
- get {
- return _sameSite;
- }
-
- set {
- _sameSite = value;
- }
- }
-
- #endregion
-
- #region Public Properties
-
- ///
- /// Gets the value of the Comment attribute of the cookie.
- ///
- ///
- ///
- /// A that represents the comment to document
- /// intended use of the cookie.
- ///
- ///
- /// if not present.
- ///
- ///
- /// The default value is .
- ///
- ///
- public string Comment {
- get {
- return _comment;
- }
-
- internal set {
- _comment = value;
- }
- }
-
- ///
- /// Gets the value of the CommentURL attribute of the cookie.
- ///
- ///
- ///
- /// A that represents the URI that provides
- /// the comment to document intended use of the cookie.
- ///
- ///
- /// if not present.
- ///
- ///
- /// The default value is .
- ///
- ///
- public Uri CommentUri {
- get {
- return _commentUri;
- }
-
- internal set {
- _commentUri = value;
- }
- }
-
- ///
- /// Gets a value indicating whether the client discards the cookie
- /// unconditionally when the client terminates.
- ///
- ///
- ///
- /// true if the client discards the cookie unconditionally
- /// when the client terminates; otherwise, false.
- ///
- ///
- /// The default value is false.
- ///
- ///
- public bool Discard {
- get {
- return _discard;
- }
-
- internal set {
- _discard = value;
- }
- }
-
- ///
- /// Gets or sets the value of the Domain attribute of the cookie.
- ///
- ///
- ///
- /// A that represents the domain name that
- /// the cookie is valid for.
- ///
- ///
- /// An empty string if not necessary.
- ///
- ///
- public string Domain {
- get {
- return _domain;
- }
-
- set {
- _domain = value ?? String.Empty;
- }
- }
-
- ///
- /// Gets or sets a value indicating whether the cookie has expired.
- ///
- ///
- ///
- /// true if the cookie has expired; otherwise, false.
- ///
- ///
- /// The default value is false.
- ///
- ///
- public bool Expired {
- get {
- return _expires != DateTime.MinValue && _expires <= DateTime.Now;
- }
-
- set {
- _expires = value ? DateTime.Now : DateTime.MinValue;
- }
- }
-
- ///
- /// Gets or sets the value of the Expires attribute of the cookie.
- ///
- ///
- ///
- /// A that represents the date and time that
- /// the cookie expires on.
- ///
- ///
- /// if not necessary.
- ///
- ///
- /// The default value is .
- ///
- ///
- public DateTime Expires {
- get {
- return _expires;
- }
-
- set {
- _expires = value;
- }
- }
-
- ///
- /// Gets or sets a value indicating whether non-HTTP APIs can access
- /// the cookie.
- ///
- ///
- ///
- /// true if non-HTTP APIs cannot access the cookie; otherwise,
- /// false.
- ///
- ///
- /// The default value is false.
- ///
- ///
- public bool HttpOnly {
- get {
- return _httpOnly;
- }
-
- set {
- _httpOnly = value;
- }
- }
-
- ///
- /// Gets or sets the name of the cookie.
- ///
- ///
- ///
- /// A that represents the name of the cookie.
- ///
- ///
- /// The name must be a token defined in
- ///
- /// RFC 2616.
- ///
- ///
- ///
- ///
- /// The value specified for a set operation is an empty string.
- ///
- ///
- /// -or-
- ///
- ///
- /// The value specified for a set operation starts with a dollar sign.
- ///
- ///
- /// -or-
- ///
- ///
- /// The value specified for a set operation contains an invalid character.
- ///
- ///
- ///
- /// The value specified for a set operation is .
- ///
- public string Name {
- get {
- return _name;
- }
-
- set {
- if (value == null)
- throw new ArgumentNullException ("value");
-
- if (value.Length == 0)
- throw new ArgumentException ("An empty string.", "value");
-
- if (value[0] == '$') {
- var msg = "It starts with a dollar sign.";
-
- throw new ArgumentException (msg, "value");
- }
-
- if (!value.IsToken ()) {
- var msg = "It contains an invalid character.";
-
- throw new ArgumentException (msg, "value");
- }
-
- _name = value;
- }
- }
-
- ///
- /// Gets or sets the value of the Path attribute of the cookie.
- ///
- ///
- /// A that represents the subset of URI on
- /// the origin server that the cookie applies to.
- ///
- public string Path {
- get {
- return _path;
- }
-
- set {
- _path = value ?? String.Empty;
- }
- }
-
- ///
- /// Gets the value of the Port attribute of the cookie.
- ///
- ///
- ///
- /// A that represents the list of TCP ports
- /// that the cookie applies to.
- ///
- ///
- /// if not present.
- ///
- ///
- /// The default value is .
- ///
- ///
- public string Port {
- get {
- return _port;
- }
-
- internal set {
- int[] ports;
-
- if (!tryCreatePorts (value, out ports))
- return;
-
- _ports = ports;
- _port = value;
- }
- }
-
- ///
- /// Gets or sets a value indicating whether the security level of
- /// the cookie is secure.
- ///
- ///
- /// When this property is true, the cookie may be included in
- /// the request only if the request is transmitted over HTTPS.
- ///
- ///
- ///
- /// true if the security level of the cookie is secure;
- /// otherwise, false.
- ///
- ///
- /// The default value is false.
- ///
- ///
- public bool Secure {
- get {
- return _secure;
- }
-
- set {
- _secure = value;
- }
- }
-
- ///
- /// Gets the time when the cookie was issued.
- ///
- ///
- /// A that represents the time when
- /// the cookie was issued.
- ///
- public DateTime TimeStamp {
- get {
- return _timeStamp;
- }
- }
-
- ///
- /// Gets or sets the value of the cookie.
- ///
- ///
- /// A that represents the value of the cookie.
- ///
- ///
- /// The value specified for a set operation is a string not enclosed in
- /// double quotes although it contains a reserved character.
- ///
- public string Value {
- get {
- return _value;
- }
-
- set {
- if (value == null)
- value = String.Empty;
-
- if (value.Contains (_reservedCharsForValue)) {
- if (!value.IsEnclosedIn ('"')) {
- var msg = "A string not enclosed in double quotes.";
-
- throw new ArgumentException (msg, "value");
- }
- }
-
- _value = value;
- }
- }
-
- ///
- /// Gets the value of the Version attribute of the cookie.
- ///
- ///
- ///
- /// An that represents the version of HTTP state
- /// management that the cookie conforms to.
- ///
- ///
- /// 0 or 1.
- ///
- ///
- /// 0 if not present.
- ///
- ///
- /// The default value is 0.
- ///
- ///
- public int Version {
- get {
- return _version;
- }
-
- internal set {
- if (value < 0 || value > 1)
- return;
-
- _version = value;
- }
- }
-
- #endregion
-
- #region Private Methods
-
- private static int hash (int i, int j, int k, int l, int m)
- {
- return i
- ^ (j << 13 | j >> 19)
- ^ (k << 26 | k >> 6)
- ^ (l << 7 | l >> 25)
- ^ (m << 20 | m >> 12);
- }
-
- private void init (string name, string value, string path, string domain)
- {
- _name = name;
- _value = value;
- _path = path;
- _domain = domain;
-
- _expires = DateTime.MinValue;
- _timeStamp = DateTime.Now;
- }
-
- private string toResponseStringVersion0 ()
- {
- var buff = new StringBuilder (64);
-
- buff.AppendFormat ("{0}={1}", _name, _value);
-
- if (_expires != DateTime.MinValue) {
- var expires = _expires
- .ToUniversalTime ()
- .ToString (
- "ddd, dd'-'MMM'-'yyyy HH':'mm':'ss 'GMT'",
- CultureInfo.CreateSpecificCulture ("en-US")
- );
-
- buff.AppendFormat ("; Expires={0}", expires);
- }
-
- if (!_path.IsNullOrEmpty ())
- buff.AppendFormat ("; Path={0}", _path);
-
- if (!_domain.IsNullOrEmpty ())
- buff.AppendFormat ("; Domain={0}", _domain);
-
- if (!_sameSite.IsNullOrEmpty ())
- buff.AppendFormat ("; SameSite={0}", _sameSite);
-
- if (_secure)
- buff.Append ("; Secure");
-
- if (_httpOnly)
- buff.Append ("; HttpOnly");
-
- return buff.ToString ();
- }
-
- private string toResponseStringVersion1 ()
- {
- var buff = new StringBuilder (64);
-
- buff.AppendFormat ("{0}={1}; Version={2}", _name, _value, _version);
-
- if (_expires != DateTime.MinValue)
- buff.AppendFormat ("; Max-Age={0}", MaxAge);
-
- if (!_path.IsNullOrEmpty ())
- buff.AppendFormat ("; Path={0}", _path);
-
- if (!_domain.IsNullOrEmpty ())
- buff.AppendFormat ("; Domain={0}", _domain);
-
- if (_port != null) {
- if (_port != "\"\"")
- buff.AppendFormat ("; Port={0}", _port);
- else
- buff.Append ("; Port");
- }
-
- if (_comment != null) {
- var comment = HttpUtility.UrlEncode (_comment);
-
- buff.AppendFormat ("; Comment={0}", comment);
- }
-
- if (_commentUri != null) {
- var url = _commentUri.OriginalString;
-
- buff.AppendFormat (
- "; CommentURL={0}",
- !url.IsToken () ? url.Quote () : url
- );
- }
-
- if (_discard)
- buff.Append ("; Discard");
-
- if (_secure)
- buff.Append ("; Secure");
-
- return buff.ToString ();
- }
-
- private static bool tryCreatePorts (string value, out int[] result)
- {
- result = null;
-
- var arr = value.Trim ('"').Split (',');
- var len = arr.Length;
- var res = new int[len];
-
- for (var i = 0; i < len; i++) {
- var s = arr[i].Trim ();
-
- if (s.Length == 0) {
- res[i] = Int32.MinValue;
-
- continue;
- }
-
- if (!Int32.TryParse (s, out res[i]))
- return false;
- }
-
- result = res;
-
- return true;
- }
-
- #endregion
-
- #region Internal Methods
-
- internal bool EqualsWithoutValue (Cookie cookie)
- {
- var caseSensitive = StringComparison.InvariantCulture;
- var caseInsensitive = StringComparison.InvariantCultureIgnoreCase;
-
- return _name.Equals (cookie._name, caseInsensitive)
- && _path.Equals (cookie._path, caseSensitive)
- && _domain.Equals (cookie._domain, caseInsensitive)
- && _version == cookie._version;
- }
-
- internal bool EqualsWithoutValueAndVersion (Cookie cookie)
- {
- var caseSensitive = StringComparison.InvariantCulture;
- var caseInsensitive = StringComparison.InvariantCultureIgnoreCase;
-
- return _name.Equals (cookie._name, caseInsensitive)
- && _path.Equals (cookie._path, caseSensitive)
- && _domain.Equals (cookie._domain, caseInsensitive);
- }
-
- internal string ToRequestString (Uri uri)
- {
- if (_name.Length == 0)
- return String.Empty;
-
- if (_version == 0)
- return String.Format ("{0}={1}", _name, _value);
-
- var buff = new StringBuilder (64);
-
- buff.AppendFormat ("$Version={0}; {1}={2}", _version, _name, _value);
-
- if (!_path.IsNullOrEmpty ())
- buff.AppendFormat ("; $Path={0}", _path);
- else if (uri != null)
- buff.AppendFormat ("; $Path={0}", uri.GetAbsolutePath ());
- else
- buff.Append ("; $Path=/");
-
- if (!_domain.IsNullOrEmpty ()) {
- if (uri == null || uri.Host != _domain)
- buff.AppendFormat ("; $Domain={0}", _domain);
- }
-
- if (_port != null) {
- if (_port != "\"\"")
- buff.AppendFormat ("; $Port={0}", _port);
- else
- buff.Append ("; $Port");
- }
-
- return buff.ToString ();
- }
-
- internal string ToResponseString ()
- {
- if (_name.Length == 0)
- return String.Empty;
-
- if (_version == 0)
- return toResponseStringVersion0 ();
-
- return toResponseStringVersion1 ();
- }
-
- internal static bool TryCreate (
- string name,
- string value,
- out Cookie result
- )
- {
- result = null;
-
- try {
- result = new Cookie (name, value);
- }
- catch {
- return false;
- }
-
- return true;
- }
-
- #endregion
-
- #region Public Methods
-
- ///
- /// Determines whether the current cookie instance is equal to
- /// the specified instance.
- ///
- ///
- ///
- /// An instance to compare with
- /// the current cookie instance.
- ///
- ///
- /// An reference to a instance.
- ///
- ///
- ///
- /// true if the current cookie instance is equal to
- /// ; otherwise, false.
- ///
- public override bool Equals (object comparand)
- {
- var cookie = comparand as Cookie;
-
- if (cookie == null)
- return false;
-
- var caseSensitive = StringComparison.InvariantCulture;
- var caseInsensitive = StringComparison.InvariantCultureIgnoreCase;
-
- return _name.Equals (cookie._name, caseInsensitive)
- && _value.Equals (cookie._value, caseSensitive)
- && _path.Equals (cookie._path, caseSensitive)
- && _domain.Equals (cookie._domain, caseInsensitive)
- && _version == cookie._version;
- }
-
- ///
- /// Gets a hash code for the current cookie instance.
- ///
- ///
- /// An that represents the hash code.
- ///
- public override int GetHashCode ()
- {
- var i = StringComparer.InvariantCultureIgnoreCase.GetHashCode (_name);
- var j = _value.GetHashCode ();
- var k = _path.GetHashCode ();
- var l = StringComparer.InvariantCultureIgnoreCase.GetHashCode (_domain);
- var m = _version;
-
- return hash (i, j, k, l, m);
- }
-
- ///
- /// Returns a string that represents the current cookie instance.
- ///
- ///
- /// A that is suitable for the Cookie request header.
- ///
- public override string ToString ()
- {
- return ToRequestString (null);
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Net/CookieCollection.cs b/websocket-sharp/Net/CookieCollection.cs
deleted file mode 100644
index 02e065580..000000000
--- a/websocket-sharp/Net/CookieCollection.cs
+++ /dev/null
@@ -1,883 +0,0 @@
-#region License
-/*
- * CookieCollection.cs
- *
- * This code is derived from CookieCollection.cs (System.Net) of Mono
- * (http://www.mono-project.com).
- *
- * The MIT License
- *
- * Copyright (c) 2004,2009 Novell, Inc. (http://www.novell.com)
- * Copyright (c) 2012-2025 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-#region Authors
-/*
- * Authors:
- * - Lawrence Pit
- * - Gonzalo Paniagua Javier
- * - Sebastien Pouliot
- */
-#endregion
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Text;
-
-namespace WebSocketSharp.Net
-{
- ///
- /// Provides a collection of instances of the class.
- ///
- [Serializable]
- public class CookieCollection : ICollection
- {
- #region Private Fields
-
- private List _list;
- private bool _readOnly;
- private object _syncRoot;
-
- #endregion
-
- #region Public Constructors
-
- ///
- /// Initializes a new instance of the class.
- ///
- public CookieCollection ()
- {
- _list = new List ();
- _syncRoot = ((ICollection) _list).SyncRoot;
- }
-
- #endregion
-
- #region Internal Properties
-
- internal IList List {
- get {
- return _list;
- }
- }
-
- internal bool ReadOnly {
- get {
- return _readOnly;
- }
-
- set {
- _readOnly = value;
- }
- }
-
- internal ICollection SortedList {
- get {
- var list = new List (_list);
-
- if (list.Count > 1)
- list.Sort (compareForSortedList);
-
- return list;
- }
- }
-
- #endregion
-
- #region Public Properties
-
- ///
- /// Gets the number of cookies in the collection.
- ///
- ///
- /// An that represents the number of cookies in
- /// the collection.
- ///
- public int Count {
- get {
- return _list.Count;
- }
- }
-
- ///
- /// Gets a value indicating whether the collection is read-only.
- ///
- ///
- ///
- /// true if the collection is read-only; otherwise, false.
- ///
- ///
- /// The default value is false.
- ///
- ///
- public bool IsReadOnly {
- get {
- return _readOnly;
- }
- }
-
- ///
- /// Gets a value indicating whether the access to the collection is
- /// thread safe.
- ///
- ///
- ///
- /// true if the access to the collection is thread safe;
- /// otherwise, false.
- ///
- ///
- /// The default value is false.
- ///
- ///
- public bool IsSynchronized {
- get {
- return false;
- }
- }
-
- ///
- /// Gets the cookie at the specified index from the collection.
- ///
- ///
- /// A at the specified index in the collection.
- ///
- ///
- /// An that specifies the zero-based index of the cookie
- /// to find.
- ///
- ///
- /// is out of allowable range for the collection.
- ///
- public Cookie this[int index] {
- get {
- if (index < 0 || index >= _list.Count)
- throw new ArgumentOutOfRangeException ("index");
-
- return _list[index];
- }
- }
-
- ///
- /// Gets the cookie with the specified name from the collection.
- ///
- ///
- ///
- /// A with the specified name in the collection.
- ///
- ///
- /// if not found.
- ///
- ///
- ///
- /// A that specifies the name of the cookie to find.
- ///
- ///
- /// is .
- ///
- public Cookie this[string name] {
- get {
- if (name == null)
- throw new ArgumentNullException ("name");
-
- var caseInsensitive = StringComparison.InvariantCultureIgnoreCase;
-
- foreach (var cookie in SortedList) {
- if (cookie.Name.Equals (name, caseInsensitive))
- return cookie;
- }
-
- return null;
- }
- }
-
- ///
- /// Gets an object used to synchronize access to the collection.
- ///
- ///
- /// An used to synchronize access to the collection.
- ///
- public object SyncRoot {
- get {
- return _syncRoot;
- }
- }
-
- #endregion
-
- #region Private Methods
-
- private void add (Cookie cookie)
- {
- var idx = search (cookie);
-
- if (idx == -1) {
- _list.Add (cookie);
-
- return;
- }
-
- _list[idx] = cookie;
- }
-
- private static int compareForSort (Cookie x, Cookie y)
- {
- return (x.Name.Length + x.Value.Length)
- - (y.Name.Length + y.Value.Length);
- }
-
- private static int compareForSortedList (Cookie x, Cookie y)
- {
- var ret = x.Version - y.Version;
-
- if (ret != 0)
- return ret;
-
- ret = x.Name.CompareTo (y.Name);
-
- if (ret != 0)
- return ret;
-
- return y.Path.Length - x.Path.Length;
- }
-
- private static CookieCollection parseRequest (string value)
- {
- var ret = new CookieCollection ();
-
- Cookie cookie = null;
- var ver = 0;
- var caseInsensitive = StringComparison.InvariantCultureIgnoreCase;
-
- var pairs = value.SplitHeaderValue (',', ';').ToList ();
-
- for (var i = 0; i < pairs.Count; i++) {
- var pair = pairs[i].Trim ();
-
- if (pair.Length == 0)
- continue;
-
- var idx = pair.IndexOf ('=');
-
- if (idx == -1) {
- if (cookie == null)
- continue;
-
- if (pair.Equals ("$port", caseInsensitive)) {
- cookie.Port = "\"\"";
-
- continue;
- }
-
- continue;
- }
-
- if (idx == 0) {
- if (cookie != null) {
- ret.add (cookie);
-
- cookie = null;
- }
-
- continue;
- }
-
- var name = pair.Substring (0, idx).TrimEnd (' ');
- var val = idx < pair.Length - 1
- ? pair.Substring (idx + 1).TrimStart (' ')
- : String.Empty;
-
- if (name.Equals ("$version", caseInsensitive)) {
- if (val.Length == 0)
- continue;
-
- var s = val.Unquote ();
-
- int num;
-
- if (!Int32.TryParse (s, out num))
- continue;
-
- ver = num;
-
- continue;
- }
-
- if (name.Equals ("$path", caseInsensitive)) {
- if (cookie == null)
- continue;
-
- if (val.Length == 0)
- continue;
-
- cookie.Path = val;
-
- continue;
- }
-
- if (name.Equals ("$domain", caseInsensitive)) {
- if (cookie == null)
- continue;
-
- if (val.Length == 0)
- continue;
-
- cookie.Domain = val;
-
- continue;
- }
-
- if (name.Equals ("$port", caseInsensitive)) {
- if (cookie == null)
- continue;
-
- if (val.Length == 0)
- continue;
-
- cookie.Port = val;
-
- continue;
- }
-
- if (cookie != null)
- ret.add (cookie);
-
- if (!Cookie.TryCreate (name, val, out cookie))
- continue;
-
- if (ver != 0)
- cookie.Version = ver;
- }
-
- if (cookie != null)
- ret.add (cookie);
-
- return ret;
- }
-
- private static CookieCollection parseResponse (string value)
- {
- var ret = new CookieCollection ();
-
- Cookie cookie = null;
- var caseInsensitive = StringComparison.InvariantCultureIgnoreCase;
-
- var pairs = value.SplitHeaderValue (',', ';').ToList ();
-
- for (var i = 0; i < pairs.Count; i++) {
- var pair = pairs[i].Trim ();
-
- if (pair.Length == 0)
- continue;
-
- var idx = pair.IndexOf ('=');
-
- if (idx == -1) {
- if (cookie == null)
- continue;
-
- if (pair.Equals ("port", caseInsensitive)) {
- cookie.Port = "\"\"";
-
- continue;
- }
-
- if (pair.Equals ("discard", caseInsensitive)) {
- cookie.Discard = true;
-
- continue;
- }
-
- if (pair.Equals ("secure", caseInsensitive)) {
- cookie.Secure = true;
-
- continue;
- }
-
- if (pair.Equals ("httponly", caseInsensitive)) {
- cookie.HttpOnly = true;
-
- continue;
- }
-
- continue;
- }
-
- if (idx == 0) {
- if (cookie != null) {
- ret.add (cookie);
-
- cookie = null;
- }
-
- continue;
- }
-
- var name = pair.Substring (0, idx).TrimEnd (' ');
- var val = idx < pair.Length - 1
- ? pair.Substring (idx + 1).TrimStart (' ')
- : String.Empty;
-
- if (name.Equals ("version", caseInsensitive)) {
- if (cookie == null)
- continue;
-
- if (val.Length == 0)
- continue;
-
- var s = val.Unquote ();
-
- int num;
-
- if (!Int32.TryParse (s, out num))
- continue;
-
- cookie.Version = num;
-
- continue;
- }
-
- if (name.Equals ("expires", caseInsensitive)) {
- if (val.Length == 0)
- continue;
-
- if (i == pairs.Count - 1)
- break;
-
- i++;
-
- if (cookie == null)
- continue;
-
- if (cookie.Expires != DateTime.MinValue)
- continue;
-
- var buff = new StringBuilder (val, 32);
-
- buff.AppendFormat (", {0}", pairs[i].Trim ());
-
- var s = buff.ToString ();
- var fmts = new[] { "ddd, dd'-'MMM'-'yyyy HH':'mm':'ss 'GMT'", "r" };
- var provider = CultureInfo.CreateSpecificCulture ("en-US");
- var style = DateTimeStyles.AdjustToUniversal
- | DateTimeStyles.AssumeUniversal;
-
- DateTime expires;
-
- var done = DateTime.TryParseExact (
- s,
- fmts,
- provider,
- style,
- out expires
- );
-
- if (!done)
- continue;
-
- cookie.Expires = expires.ToLocalTime ();
-
- continue;
- }
-
- if (name.Equals ("max-age", caseInsensitive)) {
- if (cookie == null)
- continue;
-
- if (val.Length == 0)
- continue;
-
- var s = val.Unquote ();
-
- int maxAge;
-
- if (!Int32.TryParse (s, out maxAge))
- continue;
-
- cookie.MaxAge = maxAge;
-
- continue;
- }
-
- if (name.Equals ("path", caseInsensitive)) {
- if (cookie == null)
- continue;
-
- if (val.Length == 0)
- continue;
-
- cookie.Path = val;
-
- continue;
- }
-
- if (name.Equals ("domain", caseInsensitive)) {
- if (cookie == null)
- continue;
-
- if (val.Length == 0)
- continue;
-
- cookie.Domain = val;
-
- continue;
- }
-
- if (name.Equals ("port", caseInsensitive)) {
- if (cookie == null)
- continue;
-
- if (val.Length == 0)
- continue;
-
- cookie.Port = val;
-
- continue;
- }
-
- if (name.Equals ("comment", caseInsensitive)) {
- if (cookie == null)
- continue;
-
- if (val.Length == 0)
- continue;
-
- cookie.Comment = urlDecode (val, Encoding.UTF8);
-
- continue;
- }
-
- if (name.Equals ("commenturl", caseInsensitive)) {
- if (cookie == null)
- continue;
-
- if (val.Length == 0)
- continue;
-
- cookie.CommentUri = val.Unquote ().ToUri ();
-
- continue;
- }
-
- if (name.Equals ("samesite", caseInsensitive)) {
- if (cookie == null)
- continue;
-
- if (val.Length == 0)
- continue;
-
- cookie.SameSite = val.Unquote ();
-
- continue;
- }
-
- if (cookie != null)
- ret.add (cookie);
-
- Cookie.TryCreate (name, val, out cookie);
- }
-
- if (cookie != null)
- ret.add (cookie);
-
- return ret;
- }
-
- private int search (Cookie cookie)
- {
- for (var i = _list.Count - 1; i >= 0; i--) {
- if (_list[i].EqualsWithoutValue (cookie))
- return i;
- }
-
- return -1;
- }
-
- private static string urlDecode (string s, Encoding encoding)
- {
- if (s.IndexOfAny (new[] { '%', '+' }) == -1)
- return s;
-
- try {
- return HttpUtility.UrlDecode (s, encoding);
- }
- catch {
- return null;
- }
- }
-
- #endregion
-
- #region Internal Methods
-
- internal static CookieCollection Parse (string value, bool response)
- {
- try {
- return response ? parseResponse (value) : parseRequest (value);
- }
- catch (Exception ex) {
- throw new CookieException ("It could not be parsed.", ex);
- }
- }
-
- internal void SetOrRemove (Cookie cookie)
- {
- var idx = search (cookie);
-
- if (idx == -1) {
- if (cookie.Expired)
- return;
-
- _list.Add (cookie);
-
- return;
- }
-
- if (cookie.Expired) {
- _list.RemoveAt (idx);
-
- return;
- }
-
- _list[idx] = cookie;
- }
-
- internal void SetOrRemove (CookieCollection cookies)
- {
- foreach (var cookie in cookies._list)
- SetOrRemove (cookie);
- }
-
- internal void Sort ()
- {
- if (_list.Count < 2)
- return;
-
- _list.Sort (compareForSort);
- }
-
- #endregion
-
- #region Public Methods
-
- ///
- /// Adds the specified cookie to the collection.
- ///
- ///
- /// A to add.
- ///
- ///
- /// is .
- ///
- ///
- /// This method is not available if the collection is read-only.
- ///
- public void Add (Cookie cookie)
- {
- if (_readOnly) {
- var msg = "The collection is read-only.";
-
- throw new InvalidOperationException (msg);
- }
-
- if (cookie == null)
- throw new ArgumentNullException ("cookie");
-
- add (cookie);
- }
-
- ///
- /// Adds the specified cookies to the collection.
- ///
- ///
- /// A that contains the cookies to add.
- ///
- ///
- /// is .
- ///
- ///
- /// This method is not available if the collection is read-only.
- ///
- public void Add (CookieCollection cookies)
- {
- if (_readOnly) {
- var msg = "The collection is read-only.";
-
- throw new InvalidOperationException (msg);
- }
-
- if (cookies == null)
- throw new ArgumentNullException ("cookies");
-
- foreach (var cookie in cookies._list)
- add (cookie);
- }
-
- ///
- /// Removes all cookies from the collection.
- ///
- ///
- /// This method is not available if the collection is read-only.
- ///
- public void Clear ()
- {
- if (_readOnly) {
- var msg = "The collection is read-only.";
-
- throw new InvalidOperationException (msg);
- }
-
- _list.Clear ();
- }
-
- ///
- /// Determines whether the collection contains the specified cookie.
- ///
- ///
- /// true if the cookie is found in the collection; otherwise,
- /// false.
- ///
- ///
- /// A to find.
- ///
- ///
- /// is .
- ///
- public bool Contains (Cookie cookie)
- {
- if (cookie == null)
- throw new ArgumentNullException ("cookie");
-
- return search (cookie) > -1;
- }
-
- ///
- /// Copies the elements of the collection to the specified array,
- /// starting at the specified index.
- ///
- ///
- /// An array of that specifies the destination of
- /// the elements copied from the collection.
- ///
- ///
- /// An that specifies the zero-based index in
- /// the array at which copying starts.
- ///
- ///
- /// The space from to the end of
- /// is not enough to copy to.
- ///
- ///
- /// is .
- ///
- ///
- /// is less than zero.
- ///
- public void CopyTo (Cookie[] array, int index)
- {
- if (array == null)
- throw new ArgumentNullException ("array");
-
- if (index < 0) {
- var msg = "Less than zero.";
-
- throw new ArgumentOutOfRangeException ("index", msg);
- }
-
- if (array.Length - index < _list.Count) {
- var msg = "The available space of the array is not enough to copy to.";
-
- throw new ArgumentException (msg);
- }
-
- _list.CopyTo (array, index);
- }
-
- ///
- /// Gets the enumerator that iterates through the collection.
- ///
- ///
- /// An
- /// instance that can be used to iterate through the collection.
- ///
- public IEnumerator GetEnumerator ()
- {
- return _list.GetEnumerator ();
- }
-
- ///
- /// Removes the specified cookie from the collection.
- ///
- ///
- /// true if the cookie is successfully found and removed;
- /// otherwise, false.
- ///
- ///
- /// A to remove.
- ///
- ///
- /// is .
- ///
- ///
- /// This method is not available if the collection is read-only.
- ///
- public bool Remove (Cookie cookie)
- {
- if (_readOnly) {
- var msg = "The collection is read-only.";
-
- throw new InvalidOperationException (msg);
- }
-
- if (cookie == null)
- throw new ArgumentNullException ("cookie");
-
- var idx = search (cookie);
-
- if (idx == -1)
- return false;
-
- _list.RemoveAt (idx);
-
- return true;
- }
-
- #endregion
-
- #region Explicit Interface Implementations
-
- ///
- /// Gets the enumerator that iterates through the collection.
- ///
- ///
- /// An instance that can be used to iterate
- /// through the collection.
- ///
- IEnumerator IEnumerable.GetEnumerator ()
- {
- return _list.GetEnumerator ();
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Net/CookieException.cs b/websocket-sharp/Net/CookieException.cs
deleted file mode 100644
index 3c9ab3f9e..000000000
--- a/websocket-sharp/Net/CookieException.cs
+++ /dev/null
@@ -1,169 +0,0 @@
-#region License
-/*
- * CookieException.cs
- *
- * This code is derived from CookieException.cs (System.Net) of Mono
- * (http://www.mono-project.com).
- *
- * The MIT License
- *
- * Copyright (c) 2012-2024 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-#region Authors
-/*
- * Authors:
- * - Lawrence Pit
- */
-#endregion
-
-using System;
-using System.Runtime.Serialization;
-using System.Security.Permissions;
-
-namespace WebSocketSharp.Net
-{
- ///
- /// The exception that is thrown when a gets an error.
- ///
- [Serializable]
- public class CookieException : FormatException, ISerializable
- {
- #region Internal Constructors
-
- internal CookieException (string message)
- : base (message)
- {
- }
-
- internal CookieException (string message, Exception innerException)
- : base (message, innerException)
- {
- }
-
- #endregion
-
- #region Protected Constructors
-
- ///
- /// Initializes a new instance of the class
- /// with the specified serialized data.
- ///
- ///
- /// A that contains the serialized
- /// object data.
- ///
- ///
- /// A that specifies the source for
- /// the deserialization.
- ///
- ///
- /// is .
- ///
- protected CookieException (
- SerializationInfo serializationInfo,
- StreamingContext streamingContext
- )
- : base (serializationInfo, streamingContext)
- {
- }
-
- #endregion
-
- #region Public Constructors
-
- ///
- /// Initializes a new instance of the class.
- ///
- public CookieException ()
- : base ()
- {
- }
-
- #endregion
-
- #region Public Methods
-
- ///
- /// Populates the specified instance with
- /// the data needed to serialize the current instance.
- ///
- ///
- /// A that holds the serialized object data.
- ///
- ///
- /// A that specifies the destination for
- /// the serialization.
- ///
- ///
- /// is .
- ///
- [
- SecurityPermission (
- SecurityAction.LinkDemand,
- Flags = SecurityPermissionFlag.SerializationFormatter
- )
- ]
- public override void GetObjectData (
- SerializationInfo serializationInfo,
- StreamingContext streamingContext
- )
- {
- base.GetObjectData (serializationInfo, streamingContext);
- }
-
- #endregion
-
- #region Explicit Interface Implementation
-
- ///
- /// Populates the specified instance with
- /// the data needed to serialize the current instance.
- ///
- ///
- /// A that holds the serialized object data.
- ///
- ///
- /// A that specifies the destination for
- /// the serialization.
- ///
- ///
- /// is .
- ///
- [
- SecurityPermission (
- SecurityAction.LinkDemand,
- Flags = SecurityPermissionFlag.SerializationFormatter,
- SerializationFormatter = true
- )
- ]
- void ISerializable.GetObjectData (
- SerializationInfo serializationInfo,
- StreamingContext streamingContext
- )
- {
- base.GetObjectData (serializationInfo, streamingContext);
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Net/EndPointListener.cs b/websocket-sharp/Net/EndPointListener.cs
deleted file mode 100644
index 3c8b3653a..000000000
--- a/websocket-sharp/Net/EndPointListener.cs
+++ /dev/null
@@ -1,604 +0,0 @@
-#region License
-/*
- * EndPointListener.cs
- *
- * This code is derived from EndPointListener.cs (System.Net) of Mono
- * (http://www.mono-project.com).
- *
- * The MIT License
- *
- * Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
- * Copyright (c) 2012-2023 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-#region Authors
-/*
- * Authors:
- * - Gonzalo Paniagua Javier
- */
-#endregion
-
-#region Contributors
-/*
- * Contributors:
- * - Liryna
- * - Nicholas Devenish
- */
-#endregion
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.IO;
-using System.Net;
-using System.Net.Sockets;
-using System.Security.Cryptography;
-using System.Security.Cryptography.X509Certificates;
-using System.Threading;
-
-namespace WebSocketSharp.Net
-{
- internal sealed class EndPointListener
- {
- #region Private Fields
-
- private List _all; // host == '+'
- private Dictionary _connections;
- private object _connectionsSync;
- private static readonly string _defaultCertFolderPath;
- private IPEndPoint _endpoint;
- private List _prefixes;
- private bool _secure;
- private Socket _socket;
- private ServerSslConfiguration _sslConfig;
- private List _unhandled; // host == '*'
-
- #endregion
-
- #region Static Constructor
-
- static EndPointListener ()
- {
- _defaultCertFolderPath = Environment.GetFolderPath (
- Environment.SpecialFolder.ApplicationData
- );
- }
-
- #endregion
-
- #region Internal Constructors
-
- internal EndPointListener (
- IPEndPoint endpoint,
- bool secure,
- string certificateFolderPath,
- ServerSslConfiguration sslConfig,
- bool reuseAddress
- )
- {
- _endpoint = endpoint;
-
- if (secure) {
- var cert = getCertificate (
- endpoint.Port,
- certificateFolderPath,
- sslConfig.ServerCertificate
- );
-
- if (cert == null) {
- var msg = "No server certificate could be found.";
-
- throw new ArgumentException (msg);
- }
-
- _secure = true;
- _sslConfig = new ServerSslConfiguration (sslConfig);
- _sslConfig.ServerCertificate = cert;
- }
-
- _prefixes = new List ();
- _connections = new Dictionary ();
- _connectionsSync = ((ICollection) _connections).SyncRoot;
-
- _socket = new Socket (
- endpoint.Address.AddressFamily,
- SocketType.Stream,
- ProtocolType.Tcp
- );
-
- if (reuseAddress) {
- _socket.SetSocketOption (
- SocketOptionLevel.Socket,
- SocketOptionName.ReuseAddress,
- true
- );
- }
-
- _socket.Bind (endpoint);
- _socket.Listen (500);
- _socket.BeginAccept (onAccept, this);
- }
-
- #endregion
-
- #region Public Properties
-
- public IPAddress Address {
- get {
- return _endpoint.Address;
- }
- }
-
- public bool IsSecure {
- get {
- return _secure;
- }
- }
-
- public int Port {
- get {
- return _endpoint.Port;
- }
- }
-
- public ServerSslConfiguration SslConfiguration {
- get {
- return _sslConfig;
- }
- }
-
- #endregion
-
- #region Private Methods
-
- private static void addSpecial (
- List prefixes,
- HttpListenerPrefix prefix
- )
- {
- var path = prefix.Path;
-
- foreach (var pref in prefixes) {
- if (pref.Path == path) {
- var msg = "The prefix is already in use.";
-
- throw new HttpListenerException (87, msg);
- }
- }
-
- prefixes.Add (prefix);
- }
-
- private void clearConnections ()
- {
- HttpConnection[] conns = null;
-
- lock (_connectionsSync) {
- var cnt = _connections.Count;
-
- if (cnt == 0)
- return;
-
- conns = new HttpConnection[cnt];
-
- _connections.Values.CopyTo (conns, 0);
- _connections.Clear ();
- }
-
- foreach (var conn in conns)
- conn.Close (true);
- }
-
- private static RSACryptoServiceProvider createRSAFromFile (string path)
- {
- var rsa = new RSACryptoServiceProvider ();
-
- var key = File.ReadAllBytes (path);
-
- rsa.ImportCspBlob (key);
-
- return rsa;
- }
-
- private static X509Certificate2 getCertificate (
- int port,
- string folderPath,
- X509Certificate2 defaultCertificate
- )
- {
- if (folderPath == null || folderPath.Length == 0)
- folderPath = _defaultCertFolderPath;
-
- try {
- var cer = Path.Combine (folderPath, String.Format ("{0}.cer", port));
- var key = Path.Combine (folderPath, String.Format ("{0}.key", port));
-
- var exists = File.Exists (cer) && File.Exists (key);
-
- if (!exists)
- return defaultCertificate;
-
- var cert = new X509Certificate2 (cer);
-
- cert.PrivateKey = createRSAFromFile (key);
-
- return cert;
- }
- catch {
- return defaultCertificate;
- }
- }
-
- private void leaveIfNoPrefix ()
- {
- if (_prefixes.Count > 0)
- return;
-
- var prefs = _unhandled;
-
- if (prefs != null && prefs.Count > 0)
- return;
-
- prefs = _all;
-
- if (prefs != null && prefs.Count > 0)
- return;
-
- Close ();
- }
-
- private static void onAccept (IAsyncResult asyncResult)
- {
- var lsnr = (EndPointListener) asyncResult.AsyncState;
-
- Socket sock = null;
-
- try {
- sock = lsnr._socket.EndAccept (asyncResult);
- }
- catch (ObjectDisposedException) {
- return;
- }
- catch (Exception) {
- // TODO: Logging.
- }
-
- try {
- lsnr._socket.BeginAccept (onAccept, lsnr);
- }
- catch (Exception) {
- // TODO: Logging.
-
- if (sock != null)
- sock.Close ();
-
- return;
- }
-
- if (sock == null)
- return;
-
- processAccepted (sock, lsnr);
- }
-
- private static void processAccepted (
- Socket socket,
- EndPointListener listener
- )
- {
- HttpConnection conn = null;
-
- try {
- conn = new HttpConnection (socket, listener);
- }
- catch (Exception) {
- // TODO: Logging.
-
- socket.Close ();
-
- return;
- }
-
- lock (listener._connectionsSync)
- listener._connections.Add (conn, conn);
-
- conn.BeginReadRequest ();
- }
-
- private static bool removeSpecial (
- List prefixes,
- HttpListenerPrefix prefix
- )
- {
- var path = prefix.Path;
- var cnt = prefixes.Count;
-
- for (var i = 0; i < cnt; i++) {
- if (prefixes[i].Path == path) {
- prefixes.RemoveAt (i);
-
- return true;
- }
- }
-
- return false;
- }
-
- private static HttpListener searchHttpListenerFromSpecial (
- string path,
- List prefixes
- )
- {
- if (prefixes == null)
- return null;
-
- HttpListener ret = null;
-
- var bestLen = -1;
-
- foreach (var pref in prefixes) {
- var prefPath = pref.Path;
- var len = prefPath.Length;
-
- if (len < bestLen)
- continue;
-
- var match = path.StartsWith (prefPath, StringComparison.Ordinal);
-
- if (!match)
- continue;
-
- bestLen = len;
- ret = pref.Listener;
- }
-
- return ret;
- }
-
- #endregion
-
- #region Internal Methods
-
- internal static bool CertificateExists (int port, string folderPath)
- {
- if (folderPath == null || folderPath.Length == 0)
- folderPath = _defaultCertFolderPath;
-
- var cer = Path.Combine (folderPath, String.Format ("{0}.cer", port));
- var key = Path.Combine (folderPath, String.Format ("{0}.key", port));
-
- return File.Exists (cer) && File.Exists (key);
- }
-
- internal void RemoveConnection (HttpConnection connection)
- {
- lock (_connectionsSync)
- _connections.Remove (connection);
- }
-
- internal bool TrySearchHttpListener (Uri uri, out HttpListener listener)
- {
- listener = null;
-
- if (uri == null)
- return false;
-
- var host = uri.Host;
- var dns = Uri.CheckHostName (host) == UriHostNameType.Dns;
- var port = uri.Port.ToString ();
- var path = HttpUtility.UrlDecode (uri.AbsolutePath);
-
- if (path[path.Length - 1] != '/')
- path += "/";
-
- if (host != null && host.Length > 0) {
- var prefs = _prefixes;
- var bestLen = -1;
-
- foreach (var pref in prefs) {
- if (dns) {
- var prefHost = pref.Host;
- var prefDns = Uri.CheckHostName (prefHost) == UriHostNameType.Dns;
-
- if (prefDns) {
- if (prefHost != host)
- continue;
- }
- }
-
- if (pref.Port != port)
- continue;
-
- var prefPath = pref.Path;
- var len = prefPath.Length;
-
- if (len < bestLen)
- continue;
-
- var match = path.StartsWith (prefPath, StringComparison.Ordinal);
-
- if (!match)
- continue;
-
- bestLen = len;
- listener = pref.Listener;
- }
-
- if (bestLen != -1)
- return true;
- }
-
- listener = searchHttpListenerFromSpecial (path, _unhandled);
-
- if (listener != null)
- return true;
-
- listener = searchHttpListenerFromSpecial (path, _all);
-
- return listener != null;
- }
-
- #endregion
-
- #region Public Methods
-
- public void AddPrefix (HttpListenerPrefix prefix)
- {
- List current, future;
-
- if (prefix.Host == "*") {
- do {
- current = _unhandled;
- future = current != null
- ? new List (current)
- : new List ();
-
- addSpecial (future, prefix);
- }
- while (
- Interlocked.CompareExchange (ref _unhandled, future, current)
- != current
- );
-
- return;
- }
-
- if (prefix.Host == "+") {
- do {
- current = _all;
- future = current != null
- ? new List (current)
- : new List ();
-
- addSpecial (future, prefix);
- }
- while (
- Interlocked.CompareExchange (ref _all, future, current)
- != current
- );
-
- return;
- }
-
- do {
- current = _prefixes;
-
- var idx = current.IndexOf (prefix);
-
- if (idx > -1) {
- if (current[idx].Listener != prefix.Listener) {
- var fmt = "There is another listener for {0}.";
- var msg = String.Format (fmt, prefix);
-
- throw new HttpListenerException (87, msg);
- }
-
- return;
- }
-
- future = new List (current);
-
- future.Add (prefix);
- }
- while (
- Interlocked.CompareExchange (ref _prefixes, future, current)
- != current
- );
- }
-
- public void Close ()
- {
- _socket.Close ();
-
- clearConnections ();
- EndPointManager.RemoveEndPoint (_endpoint);
- }
-
- public void RemovePrefix (HttpListenerPrefix prefix)
- {
- List current, future;
-
- if (prefix.Host == "*") {
- do {
- current = _unhandled;
-
- if (current == null)
- break;
-
- future = new List (current);
-
- if (!removeSpecial (future, prefix))
- break;
- }
- while (
- Interlocked.CompareExchange (ref _unhandled, future, current)
- != current
- );
-
- leaveIfNoPrefix ();
-
- return;
- }
-
- if (prefix.Host == "+") {
- do {
- current = _all;
-
- if (current == null)
- break;
-
- future = new List (current);
-
- if (!removeSpecial (future, prefix))
- break;
- }
- while (
- Interlocked.CompareExchange (ref _all, future, current)
- != current
- );
-
- leaveIfNoPrefix ();
-
- return;
- }
-
- do {
- current = _prefixes;
-
- if (!current.Contains (prefix))
- break;
-
- future = new List (current);
-
- future.Remove (prefix);
- }
- while (
- Interlocked.CompareExchange (ref _prefixes, future, current)
- != current
- );
-
- leaveIfNoPrefix ();
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Net/EndPointManager.cs b/websocket-sharp/Net/EndPointManager.cs
deleted file mode 100644
index ac4582b24..000000000
--- a/websocket-sharp/Net/EndPointManager.cs
+++ /dev/null
@@ -1,261 +0,0 @@
-#region License
-/*
- * EndPointManager.cs
- *
- * This code is derived from EndPointManager.cs (System.Net) of Mono
- * (http://www.mono-project.com).
- *
- * The MIT License
- *
- * Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
- * Copyright (c) 2012-2020 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-#region Authors
-/*
- * Authors:
- * - Gonzalo Paniagua Javier
- */
-#endregion
-
-#region Contributors
-/*
- * Contributors:
- * - Liryna
- */
-#endregion
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Net;
-
-namespace WebSocketSharp.Net
-{
- internal sealed class EndPointManager
- {
- #region Private Fields
-
- private static readonly Dictionary _endpoints;
-
- #endregion
-
- #region Static Constructor
-
- static EndPointManager ()
- {
- _endpoints = new Dictionary ();
- }
-
- #endregion
-
- #region Private Constructors
-
- private EndPointManager ()
- {
- }
-
- #endregion
-
- #region Private Methods
-
- private static void addPrefix (string uriPrefix, HttpListener listener)
- {
- var pref = new HttpListenerPrefix (uriPrefix, listener);
-
- var addr = convertToIPAddress (pref.Host);
-
- if (addr == null) {
- var msg = "The URI prefix includes an invalid host.";
-
- throw new HttpListenerException (87, msg);
- }
-
- if (!addr.IsLocal ()) {
- var msg = "The URI prefix includes an invalid host.";
-
- throw new HttpListenerException (87, msg);
- }
-
- int port;
-
- if (!Int32.TryParse (pref.Port, out port)) {
- var msg = "The URI prefix includes an invalid port.";
-
- throw new HttpListenerException (87, msg);
- }
-
- if (!port.IsPortNumber ()) {
- var msg = "The URI prefix includes an invalid port.";
-
- throw new HttpListenerException (87, msg);
- }
-
- var path = pref.Path;
-
- if (path.IndexOf ('%') != -1) {
- var msg = "The URI prefix includes an invalid path.";
-
- throw new HttpListenerException (87, msg);
- }
-
- if (path.IndexOf ("//", StringComparison.Ordinal) != -1) {
- var msg = "The URI prefix includes an invalid path.";
-
- throw new HttpListenerException (87, msg);
- }
-
- var endpoint = new IPEndPoint (addr, port);
-
- EndPointListener lsnr;
-
- if (_endpoints.TryGetValue (endpoint, out lsnr)) {
- if (lsnr.IsSecure ^ pref.IsSecure) {
- var msg = "The URI prefix includes an invalid scheme.";
-
- throw new HttpListenerException (87, msg);
- }
- }
- else {
- lsnr = new EndPointListener (
- endpoint,
- pref.IsSecure,
- listener.CertificateFolderPath,
- listener.SslConfiguration,
- listener.ReuseAddress
- );
-
- _endpoints.Add (endpoint, lsnr);
- }
-
- lsnr.AddPrefix (pref);
- }
-
- private static IPAddress convertToIPAddress (string hostname)
- {
- if (hostname == "*")
- return IPAddress.Any;
-
- if (hostname == "+")
- return IPAddress.Any;
-
- return hostname.ToIPAddress ();
- }
-
- private static void removePrefix (string uriPrefix, HttpListener listener)
- {
- var pref = new HttpListenerPrefix (uriPrefix, listener);
-
- var addr = convertToIPAddress (pref.Host);
-
- if (addr == null)
- return;
-
- if (!addr.IsLocal ())
- return;
-
- int port;
-
- if (!Int32.TryParse (pref.Port, out port))
- return;
-
- if (!port.IsPortNumber ())
- return;
-
- var path = pref.Path;
-
- if (path.IndexOf ('%') != -1)
- return;
-
- if (path.IndexOf ("//", StringComparison.Ordinal) != -1)
- return;
-
- var endpoint = new IPEndPoint (addr, port);
-
- EndPointListener lsnr;
-
- if (!_endpoints.TryGetValue (endpoint, out lsnr))
- return;
-
- if (lsnr.IsSecure ^ pref.IsSecure)
- return;
-
- lsnr.RemovePrefix (pref);
- }
-
- #endregion
-
- #region Internal Methods
-
- internal static bool RemoveEndPoint (IPEndPoint endpoint)
- {
- lock (((ICollection) _endpoints).SyncRoot)
- return _endpoints.Remove (endpoint);
- }
-
- #endregion
-
- #region Public Methods
-
- public static void AddListener (HttpListener listener)
- {
- var added = new List ();
-
- lock (((ICollection) _endpoints).SyncRoot) {
- try {
- foreach (var pref in listener.Prefixes) {
- addPrefix (pref, listener);
- added.Add (pref);
- }
- }
- catch {
- foreach (var pref in added)
- removePrefix (pref, listener);
-
- throw;
- }
- }
- }
-
- public static void AddPrefix (string uriPrefix, HttpListener listener)
- {
- lock (((ICollection) _endpoints).SyncRoot)
- addPrefix (uriPrefix, listener);
- }
-
- public static void RemoveListener (HttpListener listener)
- {
- lock (((ICollection) _endpoints).SyncRoot) {
- foreach (var pref in listener.Prefixes)
- removePrefix (pref, listener);
- }
- }
-
- public static void RemovePrefix (string uriPrefix, HttpListener listener)
- {
- lock (((ICollection) _endpoints).SyncRoot)
- removePrefix (uriPrefix, listener);
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Net/HttpBasicIdentity.cs b/websocket-sharp/Net/HttpBasicIdentity.cs
deleted file mode 100644
index d26b29f69..000000000
--- a/websocket-sharp/Net/HttpBasicIdentity.cs
+++ /dev/null
@@ -1,82 +0,0 @@
-#region License
-/*
- * HttpBasicIdentity.cs
- *
- * This code is derived from HttpListenerBasicIdentity.cs (System.Net) of
- * Mono (http://www.mono-project.com).
- *
- * The MIT License
- *
- * Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
- * Copyright (c) 2014-2017 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-#region Authors
-/*
- * Authors:
- * - Gonzalo Paniagua Javier
- */
-#endregion
-
-using System;
-using System.Security.Principal;
-
-namespace WebSocketSharp.Net
-{
- ///
- /// Holds the username and password from an HTTP Basic authentication attempt.
- ///
- public class HttpBasicIdentity : GenericIdentity
- {
- #region Private Fields
-
- private string _password;
-
- #endregion
-
- #region Internal Constructors
-
- internal HttpBasicIdentity (string username, string password)
- : base (username, "Basic")
- {
- _password = password;
- }
-
- #endregion
-
- #region Public Properties
-
- ///
- /// Gets the password from a basic authentication attempt.
- ///
- ///
- /// A that represents the password.
- ///
- public virtual string Password {
- get {
- return _password;
- }
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Net/HttpConnection.cs b/websocket-sharp/Net/HttpConnection.cs
deleted file mode 100644
index ec57a22af..000000000
--- a/websocket-sharp/Net/HttpConnection.cs
+++ /dev/null
@@ -1,653 +0,0 @@
-#region License
-/*
- * HttpConnection.cs
- *
- * This code is derived from HttpConnection.cs (System.Net) of Mono
- * (http://www.mono-project.com).
- *
- * The MIT License
- *
- * Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
- * Copyright (c) 2012-2026 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-#region Authors
-/*
- * Authors:
- * - Gonzalo Paniagua Javier
- */
-#endregion
-
-#region Contributors
-/*
- * Contributors:
- * - Liryna
- * - Rohan Singh
- */
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Net;
-using System.Net.Security;
-using System.Net.Sockets;
-using System.Text;
-using System.Threading;
-
-namespace WebSocketSharp.Net
-{
- internal sealed class HttpConnection
- {
- #region Private Fields
-
- private int _attempts;
- private byte[] _buffer;
- private static readonly int _bufferLength;
- private HttpListenerContext _context;
- private StringBuilder _currentLine;
- private EndPointListener _endPointListener;
- private InputState _inputState;
- private RequestStream _inputStream;
- private LineState _lineState;
- private EndPoint _localEndPoint;
- private static readonly int _maxInputLength;
- private ResponseStream _outputStream;
- private int _position;
- private EndPoint _remoteEndPoint;
- private MemoryStream _requestBuffer;
- private int _reuses;
- private bool _secure;
- private Socket _socket;
- private Stream _stream;
- private object _sync;
- private int _timeout;
- private Dictionary _timeoutCanceled;
- private Timer _timer;
-
- #endregion
-
- #region Static Constructor
-
- static HttpConnection ()
- {
- _bufferLength = 8192;
- _maxInputLength = 32768;
- }
-
- #endregion
-
- #region Internal Constructors
-
- internal HttpConnection (Socket socket, EndPointListener listener)
- {
- _socket = socket;
- _endPointListener = listener;
-
- var netStream = new NetworkStream (socket, false);
-
- if (listener.IsSecure) {
- var sslConf = listener.SslConfiguration;
- var sslStream = new SslStream (
- netStream,
- false,
- sslConf.ClientCertificateValidationCallback
- );
-
- sslStream.AuthenticateAsServer (
- sslConf.ServerCertificate,
- sslConf.ClientCertificateRequired,
- sslConf.EnabledSslProtocols,
- sslConf.CheckCertificateRevocation
- );
-
- _secure = true;
- _stream = sslStream;
- }
- else {
- _stream = netStream;
- }
-
- _buffer = new byte[_bufferLength];
- _localEndPoint = socket.LocalEndPoint;
- _remoteEndPoint = socket.RemoteEndPoint;
- _sync = new object ();
- _timeoutCanceled = new Dictionary ();
- _timer = new Timer (onTimeout, this, Timeout.Infinite, Timeout.Infinite);
-
- // 90k ms for first request, 15k ms from then on.
- init (new MemoryStream (), 90000);
- }
-
- #endregion
-
- #region Public Properties
-
- public bool IsClosed {
- get {
- return _socket == null;
- }
- }
-
- public bool IsLocal {
- get {
- return ((IPEndPoint) _remoteEndPoint).Address.IsLocal ();
- }
- }
-
- public bool IsSecure {
- get {
- return _secure;
- }
- }
-
- public IPEndPoint LocalEndPoint {
- get {
- return (IPEndPoint) _localEndPoint;
- }
- }
-
- public IPEndPoint RemoteEndPoint {
- get {
- return (IPEndPoint) _remoteEndPoint;
- }
- }
-
- public int Reuses {
- get {
- return _reuses;
- }
- }
-
- public Socket Socket {
- get {
- return _socket;
- }
- }
-
- public Stream Stream {
- get {
- return _stream;
- }
- }
-
- #endregion
-
- #region Private Methods
-
- private void close ()
- {
- lock (_sync) {
- if (_socket == null)
- return;
-
- disposeTimer ();
- disposeRequestBuffer ();
- disposeStream ();
- closeSocket ();
- }
-
- _context.Unregister ();
- _endPointListener.RemoveConnection (this);
- }
-
- private void closeSocket ()
- {
- try {
- _socket.Shutdown (SocketShutdown.Both);
- }
- catch {
- }
-
- _socket.Close ();
-
- _socket = null;
- }
-
- private static MemoryStream createRequestBuffer (
- RequestStream inputStream
- )
- {
- var ret = new MemoryStream ();
-
- if (inputStream is ChunkedRequestStream) {
- var crs = (ChunkedRequestStream) inputStream;
-
- if (crs.HasRemainingBuffer) {
- var buff = crs.RemainingBuffer;
-
- ret.Write (buff, 0, buff.Length);
- }
-
- return ret;
- }
-
- var cnt = inputStream.Count;
-
- if (cnt > 0)
- ret.Write (inputStream.InitialBuffer, inputStream.Offset, cnt);
-
- return ret;
- }
-
- private void disposeRequestBuffer ()
- {
- if (_requestBuffer == null)
- return;
-
- _requestBuffer.Dispose ();
-
- _requestBuffer = null;
- }
-
- private void disposeStream ()
- {
- if (_stream == null)
- return;
-
- _stream.Dispose ();
-
- _stream = null;
- }
-
- private void disposeTimer ()
- {
- if (_timer == null)
- return;
-
- try {
- _timer.Change (Timeout.Infinite, Timeout.Infinite);
- }
- catch {
- }
-
- _timer.Dispose ();
-
- _timer = null;
- }
-
- private void init (MemoryStream requestBuffer, int timeout)
- {
- _requestBuffer = requestBuffer;
- _timeout = timeout;
-
- _context = new HttpListenerContext (this);
- _currentLine = new StringBuilder (64);
- _inputState = InputState.RequestLine;
- _inputStream = null;
- _lineState = LineState.None;
- _outputStream = null;
- _position = 0;
- }
-
- private static void onRead (IAsyncResult asyncResult)
- {
- var conn = (HttpConnection) asyncResult.AsyncState;
- var current = conn._attempts;
-
- if (conn._socket == null)
- return;
-
- lock (conn._sync) {
- if (conn._socket == null)
- return;
-
- conn._timer.Change (Timeout.Infinite, Timeout.Infinite);
- conn._timeoutCanceled[current] = true;
-
- var nread = 0;
-
- try {
- nread = conn._stream.EndRead (asyncResult);
- }
- catch (Exception) {
- // TODO: Logging.
-
- conn.close ();
-
- return;
- }
-
- if (nread <= 0) {
- conn.close ();
-
- return;
- }
-
- conn._requestBuffer.Write (conn._buffer, 0, nread);
-
- if (conn.processRequestBuffer ())
- return;
-
- conn.BeginReadRequest ();
- }
- }
-
- private static void onTimeout (object state)
- {
- var conn = (HttpConnection) state;
- var current = conn._attempts;
-
- if (conn._socket == null)
- return;
-
- lock (conn._sync) {
- if (conn._socket == null)
- return;
-
- if (conn._timeoutCanceled[current])
- return;
-
- conn._context.SendError (408);
- }
- }
-
- private bool processInput (byte[] data, int length)
- {
- // This method returns a bool:
- // - true Done processing
- // - false Need more input
-
- var req = _context.Request;
-
- try {
- while (true) {
- int nread;
- var line = readLineFrom (data, _position, length, out nread);
-
- _position += nread;
-
- if (line == null)
- break;
-
- if (line.Length == 0) {
- if (_inputState == InputState.RequestLine)
- continue;
-
- if (_position > _maxInputLength)
- _context.ErrorMessage = "Headers too long";
-
- return true;
- }
-
- if (_inputState == InputState.RequestLine) {
- req.SetRequestLine (line);
-
- _inputState = InputState.Headers;
- }
- else {
- req.AddHeader (line);
- }
-
- if (_context.HasErrorMessage)
- return true;
- }
- }
- catch (Exception) {
- // TODO: Logging.
-
- _context.ErrorMessage = "Processing failure";
-
- return true;
- }
-
- if (_position >= _maxInputLength) {
- _context.ErrorMessage = "Headers too long";
-
- return true;
- }
-
- return false;
- }
-
- private bool processRequestBuffer ()
- {
- // This method returns a bool:
- // - true Done processing
- // - false Need more write
-
- var data = _requestBuffer.GetBuffer ();
- var len = (int) _requestBuffer.Length;
-
- if (!processInput (data, len))
- return false;
-
- var req = _context.Request;
-
- if (!_context.HasErrorMessage)
- req.FinishInitialization ();
-
- if (_context.HasErrorMessage) {
- _context.SendError ();
-
- return true;
- }
-
- var uri = req.Url;
- HttpListener httplsnr;
-
- if (!_endPointListener.TrySearchHttpListener (uri, out httplsnr)) {
- _context.SendError (404);
-
- return true;
- }
-
- httplsnr.RegisterContext (_context);
-
- return true;
- }
-
- private string readLineFrom (
- byte[] buffer,
- int offset,
- int length,
- out int nread
- )
- {
- nread = 0;
-
- for (var i = offset; i < length; i++) {
- nread++;
-
- var b = buffer[i];
-
- if (b == 13) {
- _lineState = LineState.Cr;
-
- continue;
- }
-
- if (b == 10) {
- _lineState = LineState.Lf;
-
- break;
- }
-
- _currentLine.Append ((char) b);
- }
-
- if (_lineState != LineState.Lf)
- return null;
-
- var ret = _currentLine.ToString ();
-
- _currentLine.Length = 0;
- _lineState = LineState.None;
-
- return ret;
- }
-
- private MemoryStream takeOverRequestBuffer ()
- {
- if (_inputStream != null)
- return createRequestBuffer (_inputStream);
-
- var ret = new MemoryStream ();
-
- var buff = _requestBuffer.GetBuffer ();
- var len = (int) _requestBuffer.Length;
- var cnt = len - _position;
-
- if (cnt > 0)
- ret.Write (buff, _position, cnt);
-
- disposeRequestBuffer ();
-
- return ret;
- }
-
- #endregion
-
- #region Internal Methods
-
- internal void BeginReadRequest ()
- {
- _attempts++;
-
- _timeoutCanceled.Add (_attempts, false);
- _timer.Change (_timeout, Timeout.Infinite);
-
- try {
- _stream.BeginRead (_buffer, 0, _bufferLength, onRead, this);
- }
- catch (Exception) {
- // TODO: Logging.
-
- close ();
- }
- }
-
- internal void Close (bool force)
- {
- if (_socket == null)
- return;
-
- lock (_sync) {
- if (_socket == null)
- return;
-
- if (force) {
- if (_outputStream != null)
- _outputStream.Close (true);
-
- close ();
-
- return;
- }
-
- GetResponseStream ().Close (false);
-
- if (_context.Response.CloseConnection) {
- close ();
-
- return;
- }
-
- if (!_context.Request.FlushInput ()) {
- close ();
-
- return;
- }
-
- _context.Unregister ();
-
- _reuses++;
-
- var buff = takeOverRequestBuffer ();
- var len = buff.Length;
-
- init (buff, 15000);
-
- if (len > 0) {
- if (processRequestBuffer ())
- return;
- }
-
- BeginReadRequest ();
- }
- }
-
- #endregion
-
- #region Public Methods
-
- public void Close ()
- {
- Close (false);
- }
-
- public RequestStream GetRequestStream (long contentLength, bool chunked)
- {
- lock (_sync) {
- if (_socket == null)
- return null;
-
- if (_inputStream != null)
- return _inputStream;
-
- var buff = _requestBuffer.GetBuffer ();
- var len = (int) _requestBuffer.Length;
- var cnt = len - _position;
-
- _inputStream = chunked
- ? new ChunkedRequestStream (
- _stream,
- buff,
- _position,
- cnt,
- _context
- )
- : new RequestStream (
- _stream,
- buff,
- _position,
- cnt,
- contentLength
- );
-
- disposeRequestBuffer ();
-
- return _inputStream;
- }
- }
-
- public ResponseStream GetResponseStream ()
- {
- lock (_sync) {
- if (_socket == null)
- return null;
-
- if (_outputStream != null)
- return _outputStream;
-
- var lsnr = _context.Listener;
- var ignore = lsnr != null ? lsnr.IgnoreWriteExceptions : true;
-
- _outputStream = new ResponseStream (_stream, _context.Response, ignore);
-
- return _outputStream;
- }
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Net/HttpDigestIdentity.cs b/websocket-sharp/Net/HttpDigestIdentity.cs
deleted file mode 100644
index e2863aa9c..000000000
--- a/websocket-sharp/Net/HttpDigestIdentity.cs
+++ /dev/null
@@ -1,192 +0,0 @@
-#region License
-/*
- * HttpDigestIdentity.cs
- *
- * The MIT License
- *
- * Copyright (c) 2014-2024 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-using System;
-using System.Collections.Specialized;
-using System.Security.Principal;
-
-namespace WebSocketSharp.Net
-{
- ///
- /// Holds the username and other parameters from an HTTP Digest
- /// authentication attempt.
- ///
- public class HttpDigestIdentity : GenericIdentity
- {
- #region Private Fields
-
- private NameValueCollection _parameters;
-
- #endregion
-
- #region Internal Constructors
-
- internal HttpDigestIdentity (NameValueCollection parameters)
- : base (parameters["username"], "Digest")
- {
- _parameters = parameters;
- }
-
- #endregion
-
- #region Public Properties
-
- ///
- /// Gets the algorithm parameter from a digest authentication attempt.
- ///
- ///
- /// A that represents the algorithm parameter.
- ///
- public string Algorithm {
- get {
- return _parameters["algorithm"];
- }
- }
-
- ///
- /// Gets the cnonce parameter from a digest authentication attempt.
- ///
- ///
- /// A that represents the cnonce parameter.
- ///
- public string Cnonce {
- get {
- return _parameters["cnonce"];
- }
- }
-
- ///
- /// Gets the nc parameter from a digest authentication attempt.
- ///
- ///
- /// A that represents the nc parameter.
- ///
- public string Nc {
- get {
- return _parameters["nc"];
- }
- }
-
- ///
- /// Gets the nonce parameter from a digest authentication attempt.
- ///
- ///
- /// A that represents the nonce parameter.
- ///
- public string Nonce {
- get {
- return _parameters["nonce"];
- }
- }
-
- ///
- /// Gets the opaque parameter from a digest authentication attempt.
- ///
- ///
- /// A that represents the opaque parameter.
- ///
- public string Opaque {
- get {
- return _parameters["opaque"];
- }
- }
-
- ///
- /// Gets the qop parameter from a digest authentication attempt.
- ///
- ///
- /// A that represents the qop parameter.
- ///
- public string Qop {
- get {
- return _parameters["qop"];
- }
- }
-
- ///
- /// Gets the realm parameter from a digest authentication attempt.
- ///
- ///
- /// A that represents the realm parameter.
- ///
- public string Realm {
- get {
- return _parameters["realm"];
- }
- }
-
- ///
- /// Gets the response parameter from a digest authentication attempt.
- ///
- ///
- /// A that represents the response parameter.
- ///
- public string Response {
- get {
- return _parameters["response"];
- }
- }
-
- ///
- /// Gets the uri parameter from a digest authentication attempt.
- ///
- ///
- /// A that represents the uri parameter.
- ///
- public string Uri {
- get {
- return _parameters["uri"];
- }
- }
-
- #endregion
-
- #region Internal Methods
-
- internal bool IsValid (
- string password,
- string realm,
- string method,
- string entity
- )
- {
- var parameters = new NameValueCollection (_parameters);
-
- parameters["password"] = password;
- parameters["realm"] = realm;
- parameters["method"] = method;
- parameters["entity"] = entity;
-
- var expectedDigest = AuthenticationResponse.CreateRequestDigest (parameters);
-
- return _parameters["response"] == expectedDigest;
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Net/HttpHeaderInfo.cs b/websocket-sharp/Net/HttpHeaderInfo.cs
deleted file mode 100644
index 2b77e3d9d..000000000
--- a/websocket-sharp/Net/HttpHeaderInfo.cs
+++ /dev/null
@@ -1,128 +0,0 @@
-#region License
-/*
- * HttpHeaderInfo.cs
- *
- * The MIT License
- *
- * Copyright (c) 2013-2020 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-using System;
-
-namespace WebSocketSharp.Net
-{
- internal class HttpHeaderInfo
- {
- #region Private Fields
-
- private string _headerName;
- private HttpHeaderType _headerType;
-
- #endregion
-
- #region Internal Constructors
-
- internal HttpHeaderInfo (string headerName, HttpHeaderType headerType)
- {
- _headerName = headerName;
- _headerType = headerType;
- }
-
- #endregion
-
- #region Internal Properties
-
- internal bool IsMultiValueInRequest {
- get {
- var headerType = _headerType & HttpHeaderType.MultiValueInRequest;
-
- return headerType == HttpHeaderType.MultiValueInRequest;
- }
- }
-
- internal bool IsMultiValueInResponse {
- get {
- var headerType = _headerType & HttpHeaderType.MultiValueInResponse;
-
- return headerType == HttpHeaderType.MultiValueInResponse;
- }
- }
-
- #endregion
-
- #region Public Properties
-
- public string HeaderName {
- get {
- return _headerName;
- }
- }
-
- public HttpHeaderType HeaderType {
- get {
- return _headerType;
- }
- }
-
- public bool IsRequest {
- get {
- var headerType = _headerType & HttpHeaderType.Request;
-
- return headerType == HttpHeaderType.Request;
- }
- }
-
- public bool IsResponse {
- get {
- var headerType = _headerType & HttpHeaderType.Response;
-
- return headerType == HttpHeaderType.Response;
- }
- }
-
- #endregion
-
- #region Public Methods
-
- public bool IsMultiValue (bool response)
- {
- var headerType = _headerType & HttpHeaderType.MultiValue;
-
- if (headerType != HttpHeaderType.MultiValue)
- return response ? IsMultiValueInResponse : IsMultiValueInRequest;
-
- return response ? IsResponse : IsRequest;
- }
-
- public bool IsRestricted (bool response)
- {
- var headerType = _headerType & HttpHeaderType.Restricted;
-
- if (headerType != HttpHeaderType.Restricted)
- return false;
-
- return response ? IsResponse : IsRequest;
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Net/HttpHeaderType.cs b/websocket-sharp/Net/HttpHeaderType.cs
deleted file mode 100644
index 113fb63b6..000000000
--- a/websocket-sharp/Net/HttpHeaderType.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-#region License
-/*
- * HttpHeaderType.cs
- *
- * The MIT License
- *
- * Copyright (c) 2013-2014 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-using System;
-
-namespace WebSocketSharp.Net
-{
- [Flags]
- internal enum HttpHeaderType
- {
- Unspecified = 0,
- Request = 1,
- Response = 1 << 1,
- Restricted = 1 << 2,
- MultiValue = 1 << 3,
- MultiValueInRequest = 1 << 4,
- MultiValueInResponse = 1 << 5
- }
-}
diff --git a/websocket-sharp/Net/HttpListener.cs b/websocket-sharp/Net/HttpListener.cs
deleted file mode 100644
index 44b964c0c..000000000
--- a/websocket-sharp/Net/HttpListener.cs
+++ /dev/null
@@ -1,1028 +0,0 @@
-#region License
-/*
- * HttpListener.cs
- *
- * This code is derived from HttpListener.cs (System.Net) of Mono
- * (http://www.mono-project.com).
- *
- * The MIT License
- *
- * Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
- * Copyright (c) 2012-2024 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-#region Authors
-/*
- * Authors:
- * - Gonzalo Paniagua Javier
- */
-#endregion
-
-#region Contributors
-/*
- * Contributors:
- * - Liryna
- */
-#endregion
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Security.Cryptography.X509Certificates;
-using System.Security.Principal;
-using System.Threading;
-
-// TODO: Logging.
-namespace WebSocketSharp.Net
-{
- ///
- /// Provides a simple, programmatically controlled HTTP listener.
- ///
- ///
- ///
- /// The listener supports HTTP/1.1 version request and response.
- ///
- ///
- /// And the listener allows to accept WebSocket handshake requests.
- ///
- ///
- /// This class cannot be inherited.
- ///
- ///
- public sealed class HttpListener : IDisposable
- {
- #region Private Fields
-
- private AuthenticationSchemes _authSchemes;
- private Func _authSchemeSelector;
- private string _certFolderPath;
- private Queue _contextQueue;
- private LinkedList _contextRegistry;
- private object _contextRegistrySync;
- private static readonly string _defaultRealm;
- private bool _disposed;
- private bool _ignoreWriteExceptions;
- private volatile bool _isListening;
- private Logger _log;
- private HttpListenerPrefixCollection _prefixes;
- private string _realm;
- private bool _reuseAddress;
- private ServerSslConfiguration _sslConfig;
- private object _sync;
- private Func _userCredFinder;
- private Queue _waitQueue;
-
- #endregion
-
- #region Static Constructor
-
- static HttpListener ()
- {
- _defaultRealm = "SECRET AREA";
- }
-
- #endregion
-
- #region Public Constructors
-
- ///
- /// Initializes a new instance of the class.
- ///
- public HttpListener ()
- {
- _authSchemes = AuthenticationSchemes.Anonymous;
- _contextQueue = new Queue ();
- _contextRegistry = new LinkedList ();
- _contextRegistrySync = ((ICollection) _contextRegistry).SyncRoot;
- _log = new Logger ();
- _prefixes = new HttpListenerPrefixCollection (this);
- _sync = new object ();
- _waitQueue = new Queue ();
- }
-
- #endregion
-
- #region Internal Properties
-
- internal string ObjectName {
- get {
- return GetType ().ToString ();
- }
- }
-
- internal bool ReuseAddress {
- get {
- return _reuseAddress;
- }
-
- set {
- _reuseAddress = value;
- }
- }
-
- #endregion
-
- #region Public Properties
-
- ///
- /// Gets or sets the scheme used to authenticate the clients.
- ///
- ///
- ///
- /// One of the
- /// enum values.
- ///
- ///
- /// It represents the scheme used to authenticate the clients.
- ///
- ///
- /// The default value is
- /// .
- ///
- ///
- ///
- /// This listener has been closed.
- ///
- public AuthenticationSchemes AuthenticationSchemes {
- get {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- return _authSchemes;
- }
-
- set {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- _authSchemes = value;
- }
- }
-
- ///
- /// Gets or sets the delegate called to determine the scheme used to
- /// authenticate the clients.
- ///
- ///
- ///
- /// If this property is set, the listener uses the authentication
- /// scheme selected by the delegate for each request.
- ///
- ///
- /// Or if this property is not set, the listener uses the value of
- /// the property
- /// as the authentication scheme for all requests.
- ///
- ///
- ///
- ///
- /// A
- /// delegate.
- ///
- ///
- /// It represents the delegate called when the listener selects
- /// an authentication scheme.
- ///
- ///
- /// if not necessary.
- ///
- ///
- /// The default value is .
- ///
- ///
- ///
- /// This listener has been closed.
- ///
- public Func AuthenticationSchemeSelector {
- get {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- return _authSchemeSelector;
- }
-
- set {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- _authSchemeSelector = value;
- }
- }
-
- ///
- /// Gets or sets the path to the folder in which stores the certificate
- /// files used to authenticate the server on the secure connection.
- ///
- ///
- ///
- /// This property represents the path to the folder in which stores
- /// the certificate files associated with each port number of added
- /// URI prefixes.
- ///
- ///
- /// A set of the certificate files is a pair of <port number>.cer
- /// (DER) and <port number>.key (DER, RSA Private Key).
- ///
- ///
- /// If this property is or an empty string,
- /// the result of the
- /// with the method is used as
- /// the default path.
- ///
- ///
- ///
- ///
- /// A that represents the path to the folder
- /// in which stores the certificate files.
- ///
- ///
- /// The default value is .
- ///
- ///
- ///
- /// This listener has been closed.
- ///
- public string CertificateFolderPath {
- get {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- return _certFolderPath;
- }
-
- set {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- _certFolderPath = value;
- }
- }
-
- ///
- /// Gets or sets a value indicating whether the listener returns
- /// exceptions that occur when sending the response to the client.
- ///
- ///
- ///
- /// true if the listener should not return those exceptions;
- /// otherwise, false.
- ///
- ///
- /// The default value is false.
- ///
- ///
- ///
- /// This listener has been closed.
- ///
- public bool IgnoreWriteExceptions {
- get {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- return _ignoreWriteExceptions;
- }
-
- set {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- _ignoreWriteExceptions = value;
- }
- }
-
- ///
- /// Gets a value indicating whether the listener has been started.
- ///
- ///
- /// true if the listener has been started; otherwise, false.
- ///
- public bool IsListening {
- get {
- return _isListening;
- }
- }
-
- ///
- /// Gets a value indicating whether the listener can be used with
- /// the current operating system.
- ///
- ///
- /// true.
- ///
- public static bool IsSupported {
- get {
- return true;
- }
- }
-
- ///
- /// Gets the logging functions.
- ///
- ///
- ///
- /// The default logging level is .
- ///
- ///
- /// If you would like to change it, you should set the Log.Level
- /// property to any of the enum values.
- ///
- ///
- ///
- /// A that provides the logging functions.
- ///
- ///
- /// This listener has been closed.
- ///
- public Logger Log {
- get {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- return _log;
- }
- }
-
- ///
- /// Gets the URI prefixes handled by the listener.
- ///
- ///
- /// A that contains the URI
- /// prefixes.
- ///
- ///
- /// This listener has been closed.
- ///
- public HttpListenerPrefixCollection Prefixes {
- get {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- return _prefixes;
- }
- }
-
- ///
- /// Gets or sets the name of the realm associated with the listener.
- ///
- ///
- /// If this property is or an empty string,
- /// "SECRET AREA" is used as the name of the realm.
- ///
- ///
- ///
- /// A that represents the name of the realm.
- ///
- ///
- /// The default value is .
- ///
- ///
- ///
- /// This listener has been closed.
- ///
- public string Realm {
- get {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- return _realm;
- }
-
- set {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- _realm = value;
- }
- }
-
- ///
- /// Gets the configuration for secure connection.
- ///
- ///
- /// A that represents the
- /// configuration used to provide secure connections.
- ///
- ///
- /// This listener has been closed.
- ///
- public ServerSslConfiguration SslConfiguration {
- get {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- if (_sslConfig == null)
- _sslConfig = new ServerSslConfiguration ();
-
- return _sslConfig;
- }
- }
-
- ///
- /// Gets or sets a value indicating whether, when NTLM authentication is used,
- /// the authentication information of first request is used to authenticate
- /// additional requests on the same connection.
- ///
- ///
- /// This property is not currently supported and always throws
- /// a .
- ///
- ///
- /// true if the authentication information of first request is used;
- /// otherwise, false.
- ///
- ///
- /// Any use of this property.
- ///
- public bool UnsafeConnectionNtlmAuthentication {
- get {
- throw new NotSupportedException ();
- }
-
- set {
- throw new NotSupportedException ();
- }
- }
-
- ///
- /// Gets or sets the delegate called to find the credentials for
- /// an identity used to authenticate a client.
- ///
- ///
- ///
- /// A
- /// delegate.
- ///
- ///
- /// It represents the delegate called when the listener finds
- /// the credentials used to authenticate a client.
- ///
- ///
- /// It must return if the credentials
- /// are not found.
- ///
- ///
- /// if not necessary.
- ///
- ///
- /// The default value is .
- ///
- ///
- ///
- /// This listener has been closed.
- ///
- public Func UserCredentialsFinder {
- get {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- return _userCredFinder;
- }
-
- set {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- _userCredFinder = value;
- }
- }
-
- #endregion
-
- #region Private Methods
-
- private bool authenticateClient (HttpListenerContext context)
- {
- var schm = selectAuthenticationScheme (context.Request);
-
- if (schm == AuthenticationSchemes.Anonymous)
- return true;
-
- if (schm == AuthenticationSchemes.None) {
- var msg = "Authentication not allowed";
-
- context.SendError (403, msg);
-
- return false;
- }
-
- var realm = getRealm ();
-
- if (!context.SetUser (schm, realm, _userCredFinder)) {
- context.SendAuthenticationChallenge (schm, realm);
-
- return false;
- }
-
- return true;
- }
-
- private HttpListenerAsyncResult beginGetContext (
- AsyncCallback callback,
- object state
- )
- {
- lock (_contextRegistrySync) {
- if (!_isListening) {
- var msg = "The method is canceled.";
-
- throw new HttpListenerException (995, msg);
- }
-
- var ares = new HttpListenerAsyncResult (callback, state, _log);
-
- if (_contextQueue.Count == 0) {
- _waitQueue.Enqueue (ares);
-
- return ares;
- }
-
- var ctx = _contextQueue.Dequeue ();
-
- ares.Complete (ctx, true);
-
- return ares;
- }
- }
-
- private void cleanupContextQueue (bool force)
- {
- if (_contextQueue.Count == 0)
- return;
-
- if (force) {
- _contextQueue.Clear ();
-
- return;
- }
-
- var ctxs = _contextQueue.ToArray ();
-
- _contextQueue.Clear ();
-
- foreach (var ctx in ctxs)
- ctx.SendError (503);
- }
-
- private void cleanupContextRegistry ()
- {
- var cnt = _contextRegistry.Count;
-
- if (cnt == 0)
- return;
-
- var ctxs = new HttpListenerContext[cnt];
-
- lock (_contextRegistrySync) {
- _contextRegistry.CopyTo (ctxs, 0);
- _contextRegistry.Clear ();
- }
-
- foreach (var ctx in ctxs)
- ctx.Connection.Close (true);
- }
-
- private void cleanupWaitQueue (string message)
- {
- if (_waitQueue.Count == 0)
- return;
-
- var aress = _waitQueue.ToArray ();
-
- _waitQueue.Clear ();
-
- foreach (var ares in aress) {
- var ex = new HttpListenerException (995, message);
-
- ares.Complete (ex);
- }
- }
-
- private void close (bool force)
- {
- lock (_sync) {
- if (_disposed)
- return;
-
- lock (_contextRegistrySync) {
- if (!_isListening) {
- _disposed = true;
-
- return;
- }
-
- _isListening = false;
- }
-
- cleanupContextQueue (force);
- cleanupContextRegistry ();
-
- var msg = "The listener is closed.";
-
- cleanupWaitQueue (msg);
-
- EndPointManager.RemoveListener (this);
-
- _disposed = true;
- }
- }
-
- private string getRealm ()
- {
- var realm = _realm;
-
- return realm != null && realm.Length > 0 ? realm : _defaultRealm;
- }
-
- private bool registerContext (HttpListenerContext context)
- {
- if (!_isListening)
- return false;
-
- lock (_contextRegistrySync) {
- if (!_isListening)
- return false;
-
- context.Listener = this;
-
- _contextRegistry.AddLast (context);
-
- if (_waitQueue.Count == 0) {
- _contextQueue.Enqueue (context);
-
- return true;
- }
-
- var ares = _waitQueue.Dequeue ();
-
- ares.Complete (context, false);
-
- return true;
- }
- }
-
- private AuthenticationSchemes selectAuthenticationScheme (
- HttpListenerRequest request
- )
- {
- var selector = _authSchemeSelector;
-
- if (selector == null)
- return _authSchemes;
-
- try {
- return selector (request);
- }
- catch {
- return AuthenticationSchemes.None;
- }
- }
-
- #endregion
-
- #region Internal Methods
-
- internal void CheckDisposed ()
- {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
- }
-
- internal bool RegisterContext (HttpListenerContext context)
- {
- if (!authenticateClient (context))
- return false;
-
- if (!registerContext (context)) {
- context.SendError (503);
-
- return false;
- }
-
- return true;
- }
-
- internal void UnregisterContext (HttpListenerContext context)
- {
- lock (_contextRegistrySync)
- _contextRegistry.Remove (context);
- }
-
- #endregion
-
- #region Public Methods
-
- ///
- /// Shuts down the listener immediately.
- ///
- public void Abort ()
- {
- if (_disposed)
- return;
-
- close (true);
- }
-
- ///
- /// Begins getting an incoming request asynchronously.
- ///
- ///
- ///
- /// This asynchronous operation must be ended by calling
- /// the method.
- ///
- ///
- /// Typically, the method is called by
- /// .
- ///
- ///
- ///
- /// An instance that represents the status of
- /// the asynchronous operation.
- ///
- ///
- ///
- /// An delegate.
- ///
- ///
- /// It specifies the delegate called when the asynchronous operation is
- /// complete.
- ///
- ///
- ///
- /// An that specifies a user defined object to pass to
- /// .
- ///
- ///
- /// This method is canceled.
- ///
- ///
- ///
- /// This listener has not been started or is currently stopped.
- ///
- ///
- /// -or-
- ///
- ///
- /// This listener has no URI prefix on which listens.
- ///
- ///
- ///
- /// This listener has been closed.
- ///
- public IAsyncResult BeginGetContext (AsyncCallback callback, object state)
- {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- if (!_isListening) {
- var msg = "The listener has not been started.";
-
- throw new InvalidOperationException (msg);
- }
-
- if (_prefixes.Count == 0) {
- var msg = "The listener has no URI prefix on which listens.";
-
- throw new InvalidOperationException (msg);
- }
-
- return beginGetContext (callback, state);
- }
-
- ///
- /// Shuts down the listener.
- ///
- public void Close ()
- {
- if (_disposed)
- return;
-
- close (false);
- }
-
- ///
- /// Ends an asynchronous operation to get an incoming request.
- ///
- ///
- /// This method ends an asynchronous operation started by calling
- /// the method.
- ///
- ///
- /// A that represents a request.
- ///
- ///
- /// An instance obtained by calling
- /// the method.
- ///
- ///
- /// was not obtained by calling
- /// the method.
- ///
- ///
- /// is .
- ///
- ///
- /// This method is canceled.
- ///
- ///
- ///
- /// This listener has not been started or is currently stopped.
- ///
- ///
- /// -or-
- ///
- ///
- /// This method was already called for .
- ///
- ///
- ///
- /// This listener has been closed.
- ///
- public HttpListenerContext EndGetContext (IAsyncResult asyncResult)
- {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- if (!_isListening) {
- var msg = "The listener has not been started.";
-
- throw new InvalidOperationException (msg);
- }
-
- if (asyncResult == null)
- throw new ArgumentNullException ("asyncResult");
-
- var ares = asyncResult as HttpListenerAsyncResult;
-
- if (ares == null) {
- var msg = "A wrong IAsyncResult instance.";
-
- throw new ArgumentException (msg, "asyncResult");
- }
-
- lock (ares.SyncRoot) {
- if (ares.EndCalled) {
- var msg = "This IAsyncResult instance cannot be reused.";
-
- throw new InvalidOperationException (msg);
- }
-
- ares.EndCalled = true;
- }
-
- if (!ares.IsCompleted)
- ares.AsyncWaitHandle.WaitOne ();
-
- return ares.Context;
- }
-
- ///
- /// Gets an incoming request.
- ///
- ///
- /// This method waits for an incoming request and returns when
- /// a request is received.
- ///
- ///
- /// A that represents a request.
- ///
- ///
- /// This method is canceled.
- ///
- ///
- ///
- /// This listener has not been started or is currently stopped.
- ///
- ///
- /// -or-
- ///
- ///
- /// This listener has no URI prefix on which listens.
- ///
- ///
- ///
- /// This listener has been closed.
- ///
- public HttpListenerContext GetContext ()
- {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- if (!_isListening) {
- var msg = "The listener has not been started.";
-
- throw new InvalidOperationException (msg);
- }
-
- if (_prefixes.Count == 0) {
- var msg = "The listener has no URI prefix on which listens.";
-
- throw new InvalidOperationException (msg);
- }
-
- var ares = beginGetContext (null, null);
-
- ares.EndCalled = true;
-
- if (!ares.IsCompleted)
- ares.AsyncWaitHandle.WaitOne ();
-
- return ares.Context;
- }
-
- ///
- /// Starts receiving incoming requests.
- ///
- ///
- /// This listener has been closed.
- ///
- public void Start ()
- {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- lock (_sync) {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- lock (_contextRegistrySync) {
- if (_isListening)
- return;
-
- EndPointManager.AddListener (this);
-
- _isListening = true;
- }
- }
- }
-
- ///
- /// Stops receiving incoming requests.
- ///
- ///
- /// This listener has been closed.
- ///
- public void Stop ()
- {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- lock (_sync) {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- lock (_contextRegistrySync) {
- if (!_isListening)
- return;
-
- _isListening = false;
- }
-
- cleanupContextQueue (false);
- cleanupContextRegistry ();
-
- var msg = "The listener is stopped.";
-
- cleanupWaitQueue (msg);
-
- EndPointManager.RemoveListener (this);
- }
- }
-
- #endregion
-
- #region Explicit Interface Implementations
-
- ///
- /// Releases all resources used by the listener.
- ///
- void IDisposable.Dispose ()
- {
- if (_disposed)
- return;
-
- close (true);
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Net/HttpListenerAsyncResult.cs b/websocket-sharp/Net/HttpListenerAsyncResult.cs
deleted file mode 100644
index e4742d77b..000000000
--- a/websocket-sharp/Net/HttpListenerAsyncResult.cs
+++ /dev/null
@@ -1,202 +0,0 @@
-#region License
-/*
- * HttpListenerAsyncResult.cs
- *
- * This code is derived from ListenerAsyncResult.cs (System.Net) of Mono
- * (http://www.mono-project.com).
- *
- * The MIT License
- *
- * Copyright (c) 2005 Ximian, Inc. (http://www.ximian.com)
- * Copyright (c) 2012-2024 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-#region Authors
-/*
- * Authors:
- * - Gonzalo Paniagua Javier
- */
-#endregion
-
-#region Contributors
-/*
- * Contributors:
- * - Nicholas Devenish
- */
-#endregion
-
-using System;
-using System.Threading;
-
-namespace WebSocketSharp.Net
-{
- internal class HttpListenerAsyncResult : IAsyncResult
- {
- #region Private Fields
-
- private AsyncCallback _callback;
- private bool _completed;
- private bool _completedSynchronously;
- private HttpListenerContext _context;
- private bool _endCalled;
- private Exception _exception;
- private Logger _log;
- private object _state;
- private object _sync;
- private ManualResetEvent _waitHandle;
-
- #endregion
-
- #region Internal Constructors
-
- internal HttpListenerAsyncResult (
- AsyncCallback callback,
- object state,
- Logger log
- )
- {
- _callback = callback;
- _state = state;
- _log = log;
-
- _sync = new object ();
- }
-
- #endregion
-
- #region Internal Properties
-
- internal HttpListenerContext Context
- {
- get {
- if (_exception != null)
- throw _exception;
-
- return _context;
- }
- }
-
- internal bool EndCalled {
- get {
- return _endCalled;
- }
-
- set {
- _endCalled = value;
- }
- }
-
- internal object SyncRoot {
- get {
- return _sync;
- }
- }
-
- #endregion
-
- #region Public Properties
-
- public object AsyncState {
- get {
- return _state;
- }
- }
-
- public WaitHandle AsyncWaitHandle {
- get {
- lock (_sync) {
- if (_waitHandle == null)
- _waitHandle = new ManualResetEvent (_completed);
-
- return _waitHandle;
- }
- }
- }
-
- public bool CompletedSynchronously {
- get {
- return _completedSynchronously;
- }
- }
-
- public bool IsCompleted {
- get {
- lock (_sync)
- return _completed;
- }
- }
-
- #endregion
-
- #region Private Methods
-
- private void complete ()
- {
- lock (_sync) {
- _completed = true;
-
- if (_waitHandle != null)
- _waitHandle.Set ();
- }
-
- if (_callback == null)
- return;
-
- ThreadPool.QueueUserWorkItem (
- state => {
- try {
- _callback (this);
- }
- catch (Exception ex) {
- _log.Error (ex.Message);
- _log.Debug (ex.ToString ());
- }
- },
- null
- );
- }
-
- #endregion
-
- #region Internal Methods
-
- internal void Complete (Exception exception)
- {
- _exception = exception;
-
- complete ();
- }
-
- internal void Complete (
- HttpListenerContext context,
- bool completedSynchronously
- )
- {
- _context = context;
- _completedSynchronously = completedSynchronously;
-
- complete ();
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Net/HttpListenerContext.cs b/websocket-sharp/Net/HttpListenerContext.cs
deleted file mode 100644
index 82ea0176c..000000000
--- a/websocket-sharp/Net/HttpListenerContext.cs
+++ /dev/null
@@ -1,452 +0,0 @@
-#region License
-/*
- * HttpListenerContext.cs
- *
- * This code is derived from HttpListenerContext.cs (System.Net) of Mono
- * (http://www.mono-project.com).
- *
- * The MIT License
- *
- * Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
- * Copyright (c) 2012-2024 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-#region Authors
-/*
- * Authors:
- * - Gonzalo Paniagua Javier
- */
-#endregion
-
-using System;
-using System.Security.Principal;
-using System.Text;
-using WebSocketSharp.Net.WebSockets;
-
-namespace WebSocketSharp.Net
-{
- ///
- /// Provides the access to the HTTP request and response objects used by
- /// the class.
- ///
- ///
- /// This class cannot be inherited.
- ///
- public sealed class HttpListenerContext
- {
- #region Private Fields
-
- private HttpConnection _connection;
- private string _errorMessage;
- private int _errorStatusCode;
- private HttpListener _listener;
- private HttpListenerRequest _request;
- private HttpListenerResponse _response;
- private IPrincipal _user;
- private HttpListenerWebSocketContext _websocketContext;
-
- #endregion
-
- #region Internal Constructors
-
- internal HttpListenerContext (HttpConnection connection)
- {
- _connection = connection;
-
- _errorStatusCode = 400;
- _request = new HttpListenerRequest (this);
- _response = new HttpListenerResponse (this);
- }
-
- #endregion
-
- #region Internal Properties
-
- internal HttpConnection Connection {
- get {
- return _connection;
- }
- }
-
- internal string ErrorMessage {
- get {
- return _errorMessage;
- }
-
- set {
- _errorMessage = value;
- }
- }
-
- internal int ErrorStatusCode {
- get {
- return _errorStatusCode;
- }
-
- set {
- _errorStatusCode = value;
- }
- }
-
- internal bool HasErrorMessage {
- get {
- return _errorMessage != null;
- }
- }
-
- internal HttpListener Listener {
- get {
- return _listener;
- }
-
- set {
- _listener = value;
- }
- }
-
- #endregion
-
- #region Public Properties
-
- ///
- /// Gets the HTTP request object that represents a client request.
- ///
- ///
- /// A that represents the client request.
- ///
- public HttpListenerRequest Request {
- get {
- return _request;
- }
- }
-
- ///
- /// Gets the HTTP response object used to send a response to the client.
- ///
- ///
- /// A that represents a response to
- /// the client request.
- ///
- public HttpListenerResponse Response {
- get {
- return _response;
- }
- }
-
- ///
- /// Gets the client information.
- ///
- ///
- ///
- /// A instance that represents identity,
- /// authentication, and security roles for the client.
- ///
- ///
- /// if the client is not authenticated.
- ///
- ///
- public IPrincipal User {
- get {
- return _user;
- }
- }
-
- #endregion
-
- #region Private Methods
-
- private static string createErrorContent (
- int statusCode,
- string statusDescription,
- string message
- )
- {
- return message != null && message.Length > 0
- ? String.Format (
- "{0} {1} ({2})
",
- statusCode,
- statusDescription,
- message
- )
- : String.Format (
- "{0} {1}
",
- statusCode,
- statusDescription
- );
- }
-
- #endregion
-
- #region Internal Methods
-
- internal HttpListenerWebSocketContext GetWebSocketContext (string protocol)
- {
- _websocketContext = new HttpListenerWebSocketContext (this, protocol);
-
- return _websocketContext;
- }
-
- internal void SendAuthenticationChallenge (
- AuthenticationSchemes scheme,
- string realm
- )
- {
- _response.StatusCode = 401;
-
- var val = new AuthenticationChallenge (scheme, realm).ToString ();
-
- _response.Headers.InternalSet ("WWW-Authenticate", val, true);
-
- _response.Close ();
- }
-
- internal void SendError ()
- {
- try {
- _response.StatusCode = _errorStatusCode;
- _response.ContentType = "text/html";
-
- var content = createErrorContent (
- _errorStatusCode,
- _response.StatusDescription,
- _errorMessage
- );
-
- var enc = Encoding.UTF8;
- var entity = enc.GetBytes (content);
-
- _response.ContentEncoding = enc;
- _response.ContentLength64 = entity.LongLength;
-
- _response.Close (entity, true);
- }
- catch {
- _connection.Close (true);
- }
- }
-
- internal void SendError (int statusCode)
- {
- _errorStatusCode = statusCode;
-
- SendError ();
- }
-
- internal void SendError (int statusCode, string message)
- {
- _errorStatusCode = statusCode;
- _errorMessage = message;
-
- SendError ();
- }
-
- internal bool SetUser (
- AuthenticationSchemes scheme,
- string realm,
- Func credentialsFinder
- )
- {
- var user = HttpUtility.CreateUser (
- _request.Headers["Authorization"],
- scheme,
- realm,
- _request.HttpMethod,
- credentialsFinder
- );
-
- if (user == null)
- return false;
-
- if (!user.Identity.IsAuthenticated)
- return false;
-
- _user = user;
-
- return true;
- }
-
- internal void Unregister ()
- {
- if (_listener == null)
- return;
-
- _listener.UnregisterContext (this);
- }
-
- #endregion
-
- #region Public Methods
-
- ///
- /// Accepts a WebSocket connection.
- ///
- ///
- /// A that represents
- /// the WebSocket handshake request.
- ///
- ///
- ///
- /// A that specifies the name of the subprotocol
- /// supported on the WebSocket connection.
- ///
- ///
- /// if not necessary.
- ///
- ///
- ///
- ///
- /// is an empty string.
- ///
- ///
- /// -or-
- ///
- ///
- /// contains an invalid character.
- ///
- ///
- ///
- ///
- /// This method has already been done.
- ///
- ///
- /// -or-
- ///
- ///
- /// The client request is not a WebSocket handshake request.
- ///
- ///
- public HttpListenerWebSocketContext AcceptWebSocket (string protocol)
- {
- return AcceptWebSocket (protocol, null);
- }
-
- ///
- /// Accepts a WebSocket connection with initializing the WebSocket
- /// interface.
- ///
- ///
- /// A that represents
- /// the WebSocket handshake request.
- ///
- ///
- ///
- /// A that specifies the name of the subprotocol
- /// supported on the WebSocket connection.
- ///
- ///
- /// if not necessary.
- ///
- ///
- ///
- ///
- /// An delegate.
- ///
- ///
- /// It specifies the delegate called when a new WebSocket instance is
- /// initialized.
- ///
- ///
- ///
- ///
- /// is an empty string.
- ///
- ///
- /// -or-
- ///
- ///
- /// contains an invalid character.
- ///
- ///
- /// -or-
- ///
- ///
- /// caused an exception.
- ///
- ///
- ///
- ///
- /// This method has already been done.
- ///
- ///
- /// -or-
- ///
- ///
- /// The client request is not a WebSocket handshake request.
- ///
- ///
- public HttpListenerWebSocketContext AcceptWebSocket (
- string protocol,
- Action initializer
- )
- {
- if (_websocketContext != null) {
- var msg = "The method has already been done.";
-
- throw new InvalidOperationException (msg);
- }
-
- if (!_request.IsWebSocketRequest) {
- var msg = "The request is not a WebSocket handshake request.";
-
- throw new InvalidOperationException (msg);
- }
-
- if (protocol != null) {
- if (protocol.Length == 0) {
- var msg = "An empty string.";
-
- throw new ArgumentException (msg, "protocol");
- }
-
- if (!protocol.IsToken ()) {
- var msg = "It contains an invalid character.";
-
- throw new ArgumentException (msg, "protocol");
- }
- }
-
- var ret = GetWebSocketContext (protocol);
-
- var ws = ret.WebSocket;
-
- if (initializer != null) {
- try {
- initializer (ws);
- }
- catch (Exception ex) {
- if (ws.ReadyState == WebSocketState.New)
- _websocketContext = null;
-
- var msg = "It caused an exception.";
-
- throw new ArgumentException (msg, "initializer", ex);
- }
- }
-
- ws.Accept ();
-
- return ret;
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Net/HttpListenerException.cs b/websocket-sharp/Net/HttpListenerException.cs
deleted file mode 100644
index dec858d53..000000000
--- a/websocket-sharp/Net/HttpListenerException.cs
+++ /dev/null
@@ -1,140 +0,0 @@
-#region License
-/*
- * HttpListenerException.cs
- *
- * This code is derived from HttpListenerException.cs (System.Net) of Mono
- * (http://www.mono-project.com).
- *
- * The MIT License
- *
- * Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
- * Copyright (c) 2012-2024 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-#region Authors
-/*
- * Authors:
- * - Gonzalo Paniagua Javier
- */
-#endregion
-
-using System;
-using System.ComponentModel;
-using System.Runtime.Serialization;
-
-namespace WebSocketSharp.Net
-{
- ///
- /// The exception that is thrown when an error occurs processing
- /// an HTTP request.
- ///
- [Serializable]
- public class HttpListenerException : Win32Exception
- {
- #region Protected Constructors
-
- ///
- /// Initializes a new instance of the
- /// class with the specified serialized data.
- ///
- ///
- /// A that contains the serialized
- /// object data.
- ///
- ///
- /// A that specifies the source for
- /// the deserialization.
- ///
- ///
- /// is .
- ///
- protected HttpListenerException (
- SerializationInfo serializationInfo,
- StreamingContext streamingContext
- )
- : base (serializationInfo, streamingContext)
- {
- }
-
- #endregion
-
- #region Public Constructors
-
- ///
- /// Initializes a new instance of the
- /// class.
- ///
- public HttpListenerException ()
- {
- }
-
- ///
- /// Initializes a new instance of the
- /// class with the specified error code.
- ///
- ///
- /// An that specifies the error code.
- ///
- public HttpListenerException (int errorCode)
- : base (errorCode)
- {
- }
-
- ///
- /// Initializes a new instance of the
- /// class with the specified error code and message.
- ///
- ///
- /// An that specifies the error code.
- ///
- ///
- /// A that specifies the message.
- ///
- public HttpListenerException (int errorCode, string message)
- : base (errorCode, message)
- {
- }
-
- #endregion
-
- #region Public Properties
-
- ///
- /// Gets the error code that identifies the error that occurred.
- ///
- ///
- ///
- /// An that represents the error code.
- ///
- ///
- /// It is any of the Win32 error codes.
- ///
- ///
- public override int ErrorCode {
- get {
- return NativeErrorCode;
- }
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Net/HttpListenerPrefix.cs b/websocket-sharp/Net/HttpListenerPrefix.cs
deleted file mode 100644
index aba9d1bfd..000000000
--- a/websocket-sharp/Net/HttpListenerPrefix.cs
+++ /dev/null
@@ -1,243 +0,0 @@
-#region License
-/*
- * HttpListenerPrefix.cs
- *
- * This code is derived from ListenerPrefix.cs (System.Net) of Mono
- * (http://www.mono-project.com).
- *
- * The MIT License
- *
- * Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
- * Copyright (c) 2012-2024 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-#region Authors
-/*
- * Authors:
- * - Gonzalo Paniagua Javier
- * - Oleg Mihailik
- */
-#endregion
-
-using System;
-
-namespace WebSocketSharp.Net
-{
- internal sealed class HttpListenerPrefix
- {
- #region Private Fields
-
- private string _host;
- private bool _isSecure;
- private HttpListener _listener;
- private string _original;
- private string _path;
- private string _port;
- private string _prefix;
- private string _scheme;
-
- #endregion
-
- #region Internal Constructors
-
- internal HttpListenerPrefix (string uriPrefix, HttpListener listener)
- {
- _original = uriPrefix;
- _listener = listener;
-
- parse (uriPrefix);
- }
-
- #endregion
-
- #region Public Properties
-
- public string Host {
- get {
- return _host;
- }
- }
-
- public bool IsSecure {
- get {
- return _isSecure;
- }
- }
-
- public HttpListener Listener {
- get {
- return _listener;
- }
- }
-
- public string Original {
- get {
- return _original;
- }
- }
-
- public string Path {
- get {
- return _path;
- }
- }
-
- public string Port {
- get {
- return _port;
- }
- }
-
- public string Scheme {
- get {
- return _scheme;
- }
- }
-
- #endregion
-
- #region Private Methods
-
- private void parse (string uriPrefix)
- {
- var compType = StringComparison.Ordinal;
-
- _isSecure = uriPrefix.StartsWith ("https", compType);
- _scheme = _isSecure ? "https" : "http";
-
- var hostStartIdx = uriPrefix.IndexOf (':') + 3;
-
- var len = uriPrefix.Length;
- var rootIdx = uriPrefix
- .IndexOf ('/', hostStartIdx + 1, len - hostStartIdx - 1);
-
- var colonIdx = uriPrefix
- .LastIndexOf (':', rootIdx - 1, rootIdx - hostStartIdx - 1);
-
- var hasPort = uriPrefix[rootIdx - 1] != ']' && colonIdx > hostStartIdx;
-
- if (hasPort) {
- _host = uriPrefix.Substring (hostStartIdx, colonIdx - hostStartIdx);
- _port = uriPrefix.Substring (colonIdx + 1, rootIdx - colonIdx - 1);
- }
- else {
- _host = uriPrefix.Substring (hostStartIdx, rootIdx - hostStartIdx);
- _port = _isSecure ? "443" : "80";
- }
-
- _path = uriPrefix.Substring (rootIdx);
-
- var fmt = "{0}://{1}:{2}{3}";
-
- _prefix = String.Format (fmt, _scheme, _host, _port, _path);
- }
-
- #endregion
-
- #region Public Methods
-
- public static void CheckPrefix (string uriPrefix)
- {
- if (uriPrefix == null)
- throw new ArgumentNullException ("uriPrefix");
-
- var len = uriPrefix.Length;
-
- if (len == 0) {
- var msg = "An empty string.";
-
- throw new ArgumentException (msg, "uriPrefix");
- }
-
- var compType = StringComparison.Ordinal;
- var isHttpSchm = uriPrefix.StartsWith ("http://", compType)
- || uriPrefix.StartsWith ("https://", compType);
-
- if (!isHttpSchm) {
- var msg = "The scheme is not http or https.";
-
- throw new ArgumentException (msg, "uriPrefix");
- }
-
- var endIdx = len - 1;
-
- if (uriPrefix[endIdx] != '/') {
- var msg = "It ends without a forward slash.";
-
- throw new ArgumentException (msg, "uriPrefix");
- }
-
- var hostStartIdx = uriPrefix.IndexOf (':') + 3;
-
- if (hostStartIdx >= endIdx) {
- var msg = "No host is specified.";
-
- throw new ArgumentException (msg, "uriPrefix");
- }
-
- if (uriPrefix[hostStartIdx] == ':') {
- var msg = "No host is specified.";
-
- throw new ArgumentException (msg, "uriPrefix");
- }
-
- var rootIdx = uriPrefix.IndexOf ('/', hostStartIdx, len - hostStartIdx);
-
- if (rootIdx == hostStartIdx) {
- var msg = "No host is specified.";
-
- throw new ArgumentException (msg, "uriPrefix");
- }
-
- if (uriPrefix[rootIdx - 1] == ':') {
- var msg = "No port is specified.";
-
- throw new ArgumentException (msg, "uriPrefix");
- }
-
- if (rootIdx == endIdx - 1) {
- var msg = "No path is specified.";
-
- throw new ArgumentException (msg, "uriPrefix");
- }
- }
-
- public override bool Equals (object obj)
- {
- var pref = obj as HttpListenerPrefix;
-
- return pref != null && _prefix.Equals (pref._prefix);
- }
-
- public override int GetHashCode ()
- {
- return _prefix.GetHashCode ();
- }
-
- public override string ToString ()
- {
- return _prefix;
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Net/HttpListenerPrefixCollection.cs b/websocket-sharp/Net/HttpListenerPrefixCollection.cs
deleted file mode 100644
index 3f5c44a2c..000000000
--- a/websocket-sharp/Net/HttpListenerPrefixCollection.cs
+++ /dev/null
@@ -1,295 +0,0 @@
-#region License
-/*
- * HttpListenerPrefixCollection.cs
- *
- * This code is derived from HttpListenerPrefixCollection.cs (System.Net) of Mono
- * (http://www.mono-project.com).
- *
- * The MIT License
- *
- * Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
- * Copyright (c) 2012-2024 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-#region Authors
-/*
- * Authors:
- * - Gonzalo Paniagua Javier
- */
-#endregion
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-
-namespace WebSocketSharp.Net
-{
- ///
- /// Provides a collection used to store the URI prefixes for a instance of
- /// the class.
- ///
- ///
- /// The instance responds to the request which
- /// has a requested URI that the prefixes most closely match.
- ///
- public class HttpListenerPrefixCollection : ICollection
- {
- #region Private Fields
-
- private HttpListener _listener;
- private List _prefixes;
-
- #endregion
-
- #region Internal Constructors
-
- internal HttpListenerPrefixCollection (HttpListener listener)
- {
- _listener = listener;
-
- _prefixes = new List ();
- }
-
- #endregion
-
- #region Public Properties
-
- ///
- /// Gets the number of prefixes in the collection.
- ///
- ///
- /// An that represents the number of prefixes.
- ///
- public int Count {
- get {
- return _prefixes.Count;
- }
- }
-
- ///
- /// Gets a value indicating whether the access to the collection is
- /// read-only.
- ///
- ///
- /// Always returns false.
- ///
- public bool IsReadOnly {
- get {
- return false;
- }
- }
-
- ///
- /// Gets a value indicating whether the access to the collection is
- /// synchronized.
- ///
- ///
- /// Always returns false.
- ///
- public bool IsSynchronized {
- get {
- return false;
- }
- }
-
- #endregion
-
- #region Public Methods
-
- ///
- /// Adds the specified URI prefix to the collection.
- ///
- ///
- ///
- /// A that specifies the URI prefix to add.
- ///
- ///
- /// It must be a well-formed URI prefix with http or https scheme,
- /// and must end with a forward slash (/).
- ///
- ///
- ///
- /// is invalid.
- ///
- ///
- /// is .
- ///
- ///
- /// The instance associated with this
- /// collection is closed.
- ///
- public void Add (string uriPrefix)
- {
- _listener.CheckDisposed ();
-
- HttpListenerPrefix.CheckPrefix (uriPrefix);
-
- if (_prefixes.Contains (uriPrefix))
- return;
-
- if (_listener.IsListening)
- EndPointManager.AddPrefix (uriPrefix, _listener);
-
- _prefixes.Add (uriPrefix);
- }
-
- ///
- /// Removes all URI prefixes from the collection.
- ///
- ///
- /// The instance associated with this
- /// collection is closed.
- ///
- public void Clear ()
- {
- _listener.CheckDisposed ();
-
- if (_listener.IsListening)
- EndPointManager.RemoveListener (_listener);
-
- _prefixes.Clear ();
- }
-
- ///
- /// Returns a value indicating whether the collection contains the
- /// specified URI prefix.
- ///
- ///
- /// true if the collection contains the URI prefix; otherwise,
- /// false.
- ///
- ///
- /// A that specifies the URI prefix to test.
- ///
- ///
- /// is .
- ///
- ///
- /// The instance associated with this
- /// collection is closed.
- ///
- public bool Contains (string uriPrefix)
- {
- _listener.CheckDisposed ();
-
- if (uriPrefix == null)
- throw new ArgumentNullException ("uriPrefix");
-
- return _prefixes.Contains (uriPrefix);
- }
-
- ///
- /// Copies the contents of the collection to the specified array of string.
- ///
- ///
- /// An array of that specifies the destination of
- /// the URI prefix strings copied from the collection.
- ///
- ///
- /// An that specifies the zero-based index in
- /// the array at which copying begins.
- ///
- ///
- /// The space from to the end of
- /// is not enough to copy to.
- ///
- ///
- /// is .
- ///
- ///
- /// is less than zero.
- ///
- ///
- /// The instance associated with this
- /// collection is closed.
- ///
- public void CopyTo (string[] array, int offset)
- {
- _listener.CheckDisposed ();
-
- _prefixes.CopyTo (array, offset);
- }
-
- ///
- /// Gets the enumerator that iterates through the collection.
- ///
- ///
- /// An
- /// instance that can be used to iterate through the collection.
- ///
- public IEnumerator GetEnumerator ()
- {
- return _prefixes.GetEnumerator ();
- }
-
- ///
- /// Removes the specified URI prefix from the collection.
- ///
- ///
- /// true if the URI prefix is successfully removed; otherwise,
- /// false.
- ///
- ///
- /// A that specifies the URI prefix to remove.
- ///
- ///
- /// is .
- ///
- ///
- /// The instance associated with this
- /// collection is closed.
- ///
- public bool Remove (string uriPrefix)
- {
- _listener.CheckDisposed ();
-
- if (uriPrefix == null)
- throw new ArgumentNullException ("uriPrefix");
-
- if (!_prefixes.Contains (uriPrefix))
- return false;
-
- if (_listener.IsListening)
- EndPointManager.RemovePrefix (uriPrefix, _listener);
-
- return _prefixes.Remove (uriPrefix);
- }
-
- #endregion
-
- #region Explicit Interface Implementations
-
- ///
- /// Gets the enumerator that iterates through the collection.
- ///
- ///
- /// An instance that can be used to iterate
- /// through the collection.
- ///
- IEnumerator IEnumerable.GetEnumerator ()
- {
- return _prefixes.GetEnumerator ();
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Net/HttpListenerRequest.cs b/websocket-sharp/Net/HttpListenerRequest.cs
deleted file mode 100644
index 9c7b1a16d..000000000
--- a/websocket-sharp/Net/HttpListenerRequest.cs
+++ /dev/null
@@ -1,943 +0,0 @@
-#region License
-/*
- * HttpListenerRequest.cs
- *
- * This code is derived from HttpListenerRequest.cs (System.Net) of Mono
- * (http://www.mono-project.com).
- *
- * The MIT License
- *
- * Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
- * Copyright (c) 2012-2024 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-#region Authors
-/*
- * Authors:
- * - Gonzalo Paniagua Javier
- */
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Collections.Specialized;
-using System.Globalization;
-using System.IO;
-using System.Security.Cryptography.X509Certificates;
-using System.Text;
-
-namespace WebSocketSharp.Net
-{
- ///
- /// Represents an incoming HTTP request to a
- /// instance.
- ///
- ///
- /// This class cannot be inherited.
- ///
- public sealed class HttpListenerRequest
- {
- #region Private Fields
-
- private static readonly byte[] _100continue;
- private string[] _acceptTypes;
- private bool _chunked;
- private HttpConnection _connection;
- private Encoding _contentEncoding;
- private long _contentLength;
- private HttpListenerContext _context;
- private CookieCollection _cookies;
- private static readonly Encoding _defaultEncoding;
- private WebHeaderCollection _headers;
- private string _httpMethod;
- private Stream _inputStream;
- private Version _protocolVersion;
- private NameValueCollection _queryString;
- private string _rawUrl;
- private Guid _requestTraceIdentifier;
- private Uri _url;
- private Uri _urlReferrer;
- private bool _urlSet;
- private string _userHostName;
- private string[] _userLanguages;
-
- #endregion
-
- #region Static Constructor
-
- static HttpListenerRequest ()
- {
- _100continue = Encoding.ASCII.GetBytes ("HTTP/1.1 100 Continue\r\n\r\n");
- _defaultEncoding = Encoding.UTF8;
- }
-
- #endregion
-
- #region Internal Constructors
-
- internal HttpListenerRequest (HttpListenerContext context)
- {
- _context = context;
-
- _connection = context.Connection;
- _contentLength = -1;
- _headers = new WebHeaderCollection ();
- _requestTraceIdentifier = Guid.NewGuid ();
- }
-
- #endregion
-
- #region Public Properties
-
- ///
- /// Gets the media types that are acceptable for the client.
- ///
- ///
- ///
- /// An array of that contains the names of
- /// the media types specified in the value of the Accept header.
- ///
- ///
- /// if the header is not present.
- ///
- ///
- public string[] AcceptTypes {
- get {
- var val = _headers["Accept"];
-
- if (val == null)
- return null;
-
- if (_acceptTypes == null) {
- _acceptTypes = val
- .SplitHeaderValue (',')
- .TrimEach ()
- .ToList ()
- .ToArray ();
- }
-
- return _acceptTypes;
- }
- }
-
- ///
- /// Gets an error code that identifies a problem with the certificate
- /// provided by the client.
- ///
- ///
- /// An that represents an error code.
- ///
- ///
- /// This property is not supported.
- ///
- public int ClientCertificateError {
- get {
- throw new NotSupportedException ();
- }
- }
-
- ///
- /// Gets the encoding for the entity body data included in the request.
- ///
- ///
- ///
- /// A converted from the charset value of the
- /// Content-Type header.
- ///
- ///
- /// if the charset value is not available.
- ///
- ///
- public Encoding ContentEncoding {
- get {
- if (_contentEncoding == null)
- _contentEncoding = getContentEncoding ();
-
- return _contentEncoding;
- }
- }
-
- ///
- /// Gets the length in bytes of the entity body data included in the
- /// request.
- ///
- ///
- ///
- /// A converted from the value of the Content-Length
- /// header.
- ///
- ///
- /// -1 if the header is not present.
- ///
- ///
- public long ContentLength64 {
- get {
- return _contentLength;
- }
- }
-
- ///
- /// Gets the media type of the entity body data included in the request.
- ///
- ///
- ///
- /// A that represents the value of the Content-Type
- /// header.
- ///
- ///
- /// if the header is not present.
- ///
- ///
- public string ContentType {
- get {
- return _headers["Content-Type"];
- }
- }
-
- ///
- /// Gets the HTTP cookies included in the request.
- ///
- ///
- ///
- /// A that contains the cookies.
- ///
- ///
- /// An empty collection if not included.
- ///
- ///
- public CookieCollection Cookies {
- get {
- if (_cookies == null)
- _cookies = _headers.GetCookies (false);
-
- return _cookies;
- }
- }
-
- ///
- /// Gets a value indicating whether the request has the entity body data.
- ///
- ///
- /// true if the request has the entity body data; otherwise,
- /// false.
- ///
- public bool HasEntityBody {
- get {
- return _contentLength > 0 || _chunked;
- }
- }
-
- ///
- /// Gets the HTTP headers included in the request.
- ///
- ///
- /// A that contains the headers.
- ///
- public NameValueCollection Headers {
- get {
- return _headers;
- }
- }
-
- ///
- /// Gets the HTTP method specified by the client.
- ///
- ///
- /// A that represents the HTTP method specified in
- /// the request line.
- ///
- public string HttpMethod {
- get {
- return _httpMethod;
- }
- }
-
- ///
- /// Gets a stream that contains the entity body data included in
- /// the request.
- ///
- ///
- ///
- /// A that contains the entity body data.
- ///
- ///
- /// if the entity body data is not available.
- ///
- ///
- public Stream InputStream {
- get {
- if (_inputStream == null) {
- _inputStream = _contentLength > 0 || _chunked
- ? _connection
- .GetRequestStream (_contentLength, _chunked)
- : Stream.Null;
- }
-
- return _inputStream;
- }
- }
-
- ///
- /// Gets a value indicating whether the client is authenticated.
- ///
- ///
- /// true if the client is authenticated; otherwise, false.
- ///
- public bool IsAuthenticated {
- get {
- return _context.User != null;
- }
- }
-
- ///
- /// Gets a value indicating whether the request is sent from the
- /// local computer.
- ///
- ///
- /// true if the request is sent from the same computer as
- /// the server; otherwise, false.
- ///
- public bool IsLocal {
- get {
- return _connection.IsLocal;
- }
- }
-
- ///
- /// Gets a value indicating whether a secure connection is used to send
- /// the request.
- ///
- ///
- /// true if the connection is secure; otherwise, false.
- ///
- public bool IsSecureConnection {
- get {
- return _connection.IsSecure;
- }
- }
-
- ///
- /// Gets a value indicating whether the request is a WebSocket handshake
- /// request.
- ///
- ///
- /// true if the request is a WebSocket handshake request; otherwise,
- /// false.
- ///
- public bool IsWebSocketRequest {
- get {
- return _httpMethod == "GET" && _headers.Upgrades ("websocket");
- }
- }
-
- ///
- /// Gets a value indicating whether a persistent connection is requested.
- ///
- ///
- /// true if the request specifies that the connection is kept open;
- /// otherwise, false.
- ///
- public bool KeepAlive {
- get {
- return _headers.KeepsAlive (_protocolVersion);
- }
- }
-
- ///
- /// Gets the endpoint to which the request is sent.
- ///
- ///
- /// A that represents the server
- /// IP address and port number.
- ///
- public System.Net.IPEndPoint LocalEndPoint {
- get {
- return _connection.LocalEndPoint;
- }
- }
-
- ///
- /// Gets the HTTP version specified by the client.
- ///
- ///
- /// A that represents the HTTP version specified in
- /// the request line.
- ///
- public Version ProtocolVersion {
- get {
- return _protocolVersion;
- }
- }
-
- ///
- /// Gets the query string included in the request.
- ///
- ///
- ///
- /// A that contains the query
- /// parameters.
- ///
- ///
- /// Each query parameter is decoded in UTF-8.
- ///
- ///
- /// An empty collection if not included.
- ///
- ///
- public NameValueCollection QueryString {
- get {
- if (_queryString == null) {
- var url = Url;
- var query = url != null ? url.Query : null;
-
- _queryString = QueryStringCollection.Parse (query, _defaultEncoding);
- }
-
- return _queryString;
- }
- }
-
- ///
- /// Gets the raw URL specified by the client.
- ///
- ///
- /// A that represents the request target specified in
- /// the request line.
- ///
- public string RawUrl {
- get {
- return _rawUrl;
- }
- }
-
- ///
- /// Gets the endpoint from which the request is sent.
- ///
- ///
- /// A that represents the client
- /// IP address and port number.
- ///
- public System.Net.IPEndPoint RemoteEndPoint {
- get {
- return _connection.RemoteEndPoint;
- }
- }
-
- ///
- /// Gets the trace identifier of the request.
- ///
- ///
- /// A that represents the trace identifier.
- ///
- public Guid RequestTraceIdentifier {
- get {
- return _requestTraceIdentifier;
- }
- }
-
- ///
- /// Gets the URL requested by the client.
- ///
- ///
- ///
- /// A that represents the URL parsed from the request.
- ///
- ///
- /// if the URL cannot be parsed.
- ///
- ///
- public Uri Url {
- get {
- if (!_urlSet) {
- _url = HttpUtility
- .CreateRequestUrl (
- _rawUrl,
- _userHostName,
- IsWebSocketRequest,
- IsSecureConnection
- );
-
- _urlSet = true;
- }
-
- return _url;
- }
- }
-
- ///
- /// Gets the URI of the resource from which the requested URL was obtained.
- ///
- ///
- ///
- /// A that represents the value of the Referer header.
- ///
- ///
- /// if the header value is not available.
- ///
- ///
- public Uri UrlReferrer {
- get {
- var val = _headers["Referer"];
-
- if (val == null)
- return null;
-
- if (_urlReferrer == null)
- _urlReferrer = val.ToUri ();
-
- return _urlReferrer;
- }
- }
-
- ///
- /// Gets the user agent from which the request is originated.
- ///
- ///
- ///
- /// A that represents the value of the User-Agent
- /// header.
- ///
- ///
- /// if the header is not present.
- ///
- ///
- public string UserAgent {
- get {
- return _headers["User-Agent"];
- }
- }
-
- ///
- /// Gets the IP address and port number to which the request is sent.
- ///
- ///
- /// A that represents the server IP address and
- /// port number.
- ///
- public string UserHostAddress {
- get {
- return _connection.LocalEndPoint.ToString ();
- }
- }
-
- ///
- /// Gets the server host name requested by the client.
- ///
- ///
- ///
- /// A that represents the value of the Host header.
- ///
- ///
- /// It includes the port number if provided.
- ///
- ///
- public string UserHostName {
- get {
- return _userHostName;
- }
- }
-
- ///
- /// Gets the natural languages that are acceptable for the client.
- ///
- ///
- ///
- /// An array of that contains the names of the
- /// natural languages specified in the value of the Accept-Language
- /// header.
- ///
- ///
- /// if the header is not present.
- ///
- ///
- public string[] UserLanguages {
- get {
- var val = _headers["Accept-Language"];
-
- if (val == null)
- return null;
-
- if (_userLanguages == null)
- _userLanguages = val.Split (',').TrimEach ().ToList ().ToArray ();
-
- return _userLanguages;
- }
- }
-
- #endregion
-
- #region Private Methods
-
- private Encoding getContentEncoding ()
- {
- var val = _headers["Content-Type"];
-
- if (val == null)
- return _defaultEncoding;
-
- Encoding ret;
-
- return HttpUtility.TryGetEncoding (val, out ret)
- ? ret
- : _defaultEncoding;
- }
-
- #endregion
-
- #region Internal Methods
-
- internal void AddHeader (string headerField)
- {
- var start = headerField[0];
-
- if (start == ' ' || start == '\t') {
- _context.ErrorMessage = "Invalid header field";
-
- return;
- }
-
- var colon = headerField.IndexOf (':');
-
- if (colon < 1) {
- _context.ErrorMessage = "Invalid header field";
-
- return;
- }
-
- var name = headerField.Substring (0, colon).Trim ();
-
- if (name.Length == 0 || !name.IsToken ()) {
- _context.ErrorMessage = "Invalid header name";
-
- return;
- }
-
- var val = colon < headerField.Length - 1
- ? headerField.Substring (colon + 1).Trim ()
- : String.Empty;
-
- _headers.InternalSet (name, val, false);
-
- var lower = name.ToLower (CultureInfo.InvariantCulture);
-
- if (lower == "host") {
- if (_userHostName != null) {
- _context.ErrorMessage = "Invalid Host header";
-
- return;
- }
-
- if (val.Length == 0) {
- _context.ErrorMessage = "Invalid Host header";
-
- return;
- }
-
- _userHostName = val;
-
- return;
- }
-
- if (lower == "content-length") {
- if (_contentLength > -1) {
- _context.ErrorMessage = "Invalid Content-Length header";
-
- return;
- }
-
- long len;
-
- if (!Int64.TryParse (val, out len)) {
- _context.ErrorMessage = "Invalid Content-Length header";
-
- return;
- }
-
- if (len < 0) {
- _context.ErrorMessage = "Invalid Content-Length header";
-
- return;
- }
-
- _contentLength = len;
-
- return;
- }
- }
-
- internal void FinishInitialization ()
- {
- if (_userHostName == null) {
- _context.ErrorMessage = "Host header required";
-
- return;
- }
-
- var transferEnc = _headers["Transfer-Encoding"];
-
- if (transferEnc != null) {
- var compType = StringComparison.OrdinalIgnoreCase;
-
- if (!transferEnc.Equals ("chunked", compType)) {
- _context.ErrorStatusCode = 501;
- _context.ErrorMessage = "Invalid Transfer-Encoding header";
-
- return;
- }
-
- _chunked = true;
- }
-
- if (_httpMethod == "POST" || _httpMethod == "PUT") {
- if (_contentLength == -1 && !_chunked) {
- _context.ErrorStatusCode = 411;
- _context.ErrorMessage = "Content-Length header required";
-
- return;
- }
-
- if (_contentLength == 0 && !_chunked) {
- _context.ErrorStatusCode = 411;
- _context.ErrorMessage = "Invalid Content-Length header";
-
- return;
- }
- }
-
- var expect = _headers["Expect"];
-
- if (expect != null) {
- var compType = StringComparison.OrdinalIgnoreCase;
-
- if (!expect.Equals ("100-continue", compType)) {
- _context.ErrorStatusCode = 417;
- _context.ErrorMessage = "Invalid Expect header";
-
- return;
- }
-
- var output = _connection.GetResponseStream ();
-
- output.InternalWrite (_100continue, 0, _100continue.Length);
- }
- }
-
- internal bool FlushInput ()
- {
- var input = InputStream;
-
- if (input == Stream.Null)
- return true;
-
- var len = 2048;
-
- if (_contentLength > 0 && _contentLength < len)
- len = (int) _contentLength;
-
- var buff = new byte[len];
-
- while (true) {
- try {
- var ares = input.BeginRead (buff, 0, len, null, null);
-
- if (!ares.IsCompleted) {
- var timeout = 100;
-
- if (!ares.AsyncWaitHandle.WaitOne (timeout))
- return false;
- }
-
- if (input.EndRead (ares) <= 0)
- return true;
- }
- catch {
- return false;
- }
- }
- }
-
- internal bool IsUpgradeRequest (string protocol)
- {
- return _headers.Upgrades (protocol);
- }
-
- internal void SetRequestLine (string requestLine)
- {
- var parts = requestLine.Split (new[] { ' ' }, 3);
-
- if (parts.Length < 3) {
- _context.ErrorMessage = "Invalid request line (parts)";
-
- return;
- }
-
- var method = parts[0];
-
- if (method.Length == 0) {
- _context.ErrorMessage = "Invalid request line (method)";
-
- return;
- }
-
- if (!method.IsHttpMethod ()) {
- _context.ErrorStatusCode = 501;
- _context.ErrorMessage = "Invalid request line (method)";
-
- return;
- }
-
- var target = parts[1];
-
- if (target.Length == 0) {
- _context.ErrorMessage = "Invalid request line (target)";
-
- return;
- }
-
- var rawVer = parts[2];
-
- if (rawVer.Length != 8) {
- _context.ErrorMessage = "Invalid request line (version)";
-
- return;
- }
-
- if (!rawVer.StartsWith ("HTTP/", StringComparison.Ordinal)) {
- _context.ErrorMessage = "Invalid request line (version)";
-
- return;
- }
-
- Version ver;
-
- if (!rawVer.Substring (5).TryCreateVersion (out ver)) {
- _context.ErrorMessage = "Invalid request line (version)";
-
- return;
- }
-
- if (ver != HttpVersion.Version11) {
- _context.ErrorStatusCode = 505;
- _context.ErrorMessage = "Invalid request line (version)";
-
- return;
- }
-
- _httpMethod = method;
- _rawUrl = target;
- _protocolVersion = ver;
- }
-
- #endregion
-
- #region Public Methods
-
- ///
- /// Begins getting the certificate provided by the client asynchronously.
- ///
- ///
- /// An instance that represents the status of
- /// the asynchronous operation.
- ///
- ///
- ///
- /// An delegate.
- ///
- ///
- /// It specifies the delegate called when the asynchronous operation is
- /// complete.
- ///
- ///
- ///
- /// An that specifies a user defined object to pass to
- /// .
- ///
- ///
- /// This method is not supported.
- ///
- public IAsyncResult BeginGetClientCertificate (
- AsyncCallback requestCallback,
- object state
- )
- {
- throw new NotSupportedException ();
- }
-
- ///
- /// Ends an asynchronous operation to get the certificate provided by
- /// the client.
- ///
- ///
- /// A that represents an X.509 certificate
- /// provided by the client.
- ///
- ///
- /// An instance obtained by calling
- /// the method.
- ///
- ///
- /// This method is not supported.
- ///
- public X509Certificate2 EndGetClientCertificate (IAsyncResult asyncResult)
- {
- throw new NotSupportedException ();
- }
-
- ///
- /// Gets the certificate provided by the client.
- ///
- ///
- /// A that represents an X.509 certificate
- /// provided by the client.
- ///
- ///
- /// This method is not supported.
- ///
- public X509Certificate2 GetClientCertificate ()
- {
- throw new NotSupportedException ();
- }
-
- ///
- /// Returns a string that represents the current instance.
- ///
- ///
- /// A that contains the request line and headers
- /// included in the request.
- ///
- public override string ToString ()
- {
- var buff = new StringBuilder (64);
-
- var fmt = "{0} {1} HTTP/{2}\r\n";
- var headers = _headers.ToString ();
-
- buff
- .AppendFormat (fmt, _httpMethod, _rawUrl, _protocolVersion)
- .Append (headers);
-
- return buff.ToString ();
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Net/HttpListenerResponse.cs b/websocket-sharp/Net/HttpListenerResponse.cs
deleted file mode 100644
index 500d42827..000000000
--- a/websocket-sharp/Net/HttpListenerResponse.cs
+++ /dev/null
@@ -1,1201 +0,0 @@
-#region License
-/*
- * HttpListenerResponse.cs
- *
- * This code is derived from HttpListenerResponse.cs (System.Net) of Mono
- * (http://www.mono-project.com).
- *
- * The MIT License
- *
- * Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
- * Copyright (c) 2012-2024 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-#region Authors
-/*
- * Authors:
- * - Gonzalo Paniagua Javier
- */
-#endregion
-
-#region Contributors
-/*
- * Contributors:
- * - Nicholas Devenish
- */
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
-using System.Text;
-
-namespace WebSocketSharp.Net
-{
- ///
- /// Represents an HTTP response to an HTTP request received by
- /// a instance.
- ///
- ///
- /// This class cannot be inherited.
- ///
- public sealed class HttpListenerResponse : IDisposable
- {
- #region Private Fields
-
- private bool _closeConnection;
- private Encoding _contentEncoding;
- private long _contentLength;
- private string _contentType;
- private HttpListenerContext _context;
- private CookieCollection _cookies;
- private static readonly string _defaultProductName;
- private bool _disposed;
- private WebHeaderCollection _headers;
- private bool _headersSent;
- private bool _keepAlive;
- private ResponseStream _outputStream;
- private Uri _redirectLocation;
- private bool _sendChunked;
- private int _statusCode;
- private string _statusDescription;
- private Version _version;
-
- #endregion
-
- #region Static Constructor
-
- static HttpListenerResponse ()
- {
- _defaultProductName = "websocket-sharp/1.0";
- }
-
- #endregion
-
- #region Internal Constructors
-
- internal HttpListenerResponse (HttpListenerContext context)
- {
- _context = context;
-
- _keepAlive = true;
- _statusCode = 200;
- _statusDescription = "OK";
- _version = HttpVersion.Version11;
- }
-
- #endregion
-
- #region Internal Properties
-
- internal bool CloseConnection {
- get {
- return _closeConnection;
- }
-
- set {
- _closeConnection = value;
- }
- }
-
- internal WebHeaderCollection FullHeaders {
- get {
- var headers = new WebHeaderCollection (HttpHeaderType.Response, true);
-
- if (_headers != null)
- headers.Add (_headers);
-
- if (_contentType != null) {
- var val = createContentTypeHeaderText (_contentType, _contentEncoding);
-
- headers.InternalSet ("Content-Type", val, true);
- }
-
- if (headers["Server"] == null)
- headers.InternalSet ("Server", _defaultProductName, true);
-
- if (headers["Date"] == null) {
- var val = DateTime.UtcNow.ToString ("r", CultureInfo.InvariantCulture);
-
- headers.InternalSet ("Date", val, true);
- }
-
- if (_sendChunked) {
- headers.InternalSet ("Transfer-Encoding", "chunked", true);
- }
- else {
- var val = _contentLength.ToString (CultureInfo.InvariantCulture);
-
- headers.InternalSet ("Content-Length", val, true);
- }
-
- /*
- * Apache forces closing the connection for these status codes:
- * - 400 Bad Request
- * - 408 Request Timeout
- * - 411 Length Required
- * - 413 Request Entity Too Large
- * - 414 Request-Uri Too Long
- * - 500 Internal Server Error
- * - 503 Service Unavailable
- */
-
- var reuses = _context.Connection.Reuses;
- var closeConn = !_context.Request.KeepAlive
- || !_keepAlive
- || reuses >= 100
- || _statusCode == 400
- || _statusCode == 408
- || _statusCode == 411
- || _statusCode == 413
- || _statusCode == 414
- || _statusCode == 500
- || _statusCode == 503;
-
- if (closeConn) {
- headers.InternalSet ("Connection", "close", true);
- }
- else {
- var fmt = "timeout=15,max={0}";
- var max = 100 - reuses;
- var val = String.Format (fmt, max);
-
- headers.InternalSet ("Keep-Alive", val, true);
- }
-
- if (_redirectLocation != null)
- headers.InternalSet ("Location", _redirectLocation.AbsoluteUri, true);
-
- if (_cookies != null) {
- foreach (var cookie in _cookies) {
- var val = cookie.ToResponseString ();
-
- headers.InternalSet ("Set-Cookie", val, true);
- }
- }
-
- return headers;
- }
- }
-
- internal bool HeadersSent {
- get {
- return _headersSent;
- }
-
- set {
- _headersSent = value;
- }
- }
-
- internal string ObjectName {
- get {
- return GetType ().ToString ();
- }
- }
-
- internal string StatusLine {
- get {
- var fmt = "HTTP/{0} {1} {2}\r\n";
-
- return String.Format (fmt, _version, _statusCode, _statusDescription);
- }
- }
-
- #endregion
-
- #region Public Properties
-
- ///
- /// Gets or sets the encoding for the entity body data included in
- /// the response.
- ///
- ///
- ///
- /// A that represents the encoding for
- /// the entity body data.
- ///
- ///
- /// if no encoding is specified.
- ///
- ///
- /// The default value is .
- ///
- ///
- ///
- /// The response is already being sent.
- ///
- ///
- /// This instance is closed.
- ///
- public Encoding ContentEncoding {
- get {
- return _contentEncoding;
- }
-
- set {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- if (_headersSent) {
- var msg = "The response is already being sent.";
-
- throw new InvalidOperationException (msg);
- }
-
- _contentEncoding = value;
- }
- }
-
- ///
- /// Gets or sets the number of bytes in the entity body data included in
- /// the response.
- ///
- ///
- ///
- /// A that represents the number of bytes in
- /// the entity body data.
- ///
- ///
- /// It is used for the value of the Content-Length header.
- ///
- ///
- /// The default value is zero.
- ///
- ///
- ///
- /// The value specified for a set operation is less than zero.
- ///
- ///
- /// The response is already being sent.
- ///
- ///
- /// This instance is closed.
- ///
- public long ContentLength64 {
- get {
- return _contentLength;
- }
-
- set {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- if (_headersSent) {
- var msg = "The response is already being sent.";
-
- throw new InvalidOperationException (msg);
- }
-
- if (value < 0) {
- var msg = "Less than zero.";
-
- throw new ArgumentOutOfRangeException (msg, "value");
- }
-
- _contentLength = value;
- }
- }
-
- ///
- /// Gets or sets the media type of the entity body included in
- /// the response.
- ///
- ///
- ///
- /// A that represents the media type of
- /// the entity body.
- ///
- ///
- /// It is used for the value of the Content-Type header.
- ///
- ///
- /// if no media type is specified.
- ///
- ///
- /// The default value is .
- ///
- ///
- ///
- ///
- /// The value specified for a set operation is an empty string.
- ///
- ///
- /// -or-
- ///
- ///
- /// The value specified for a set operation contains
- /// an invalid character.
- ///
- ///
- ///
- /// The response is already being sent.
- ///
- ///
- /// This instance is closed.
- ///
- public string ContentType {
- get {
- return _contentType;
- }
-
- set {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- if (_headersSent) {
- var msg = "The response is already being sent.";
-
- throw new InvalidOperationException (msg);
- }
-
- if (value == null) {
- _contentType = null;
-
- return;
- }
-
- if (value.Length == 0)
- throw new ArgumentException ("An empty string.", "value");
-
- if (!isValidForContentType (value)) {
- var msg = "It contains an invalid character.";
-
- throw new ArgumentException (msg, "value");
- }
-
- _contentType = value;
- }
- }
-
- ///
- /// Gets or sets the collection of the HTTP cookies sent with the response.
- ///
- ///
- /// A that contains the cookies sent with
- /// the response.
- ///
- public CookieCollection Cookies {
- get {
- if (_cookies == null)
- _cookies = new CookieCollection ();
-
- return _cookies;
- }
-
- set {
- _cookies = value;
- }
- }
-
- ///
- /// Gets or sets the collection of the HTTP headers sent to the client.
- ///
- ///
- /// A that contains the headers sent to
- /// the client.
- ///
- ///
- /// The value specified for a set operation is not valid for a response.
- ///
- public WebHeaderCollection Headers {
- get {
- if (_headers == null)
- _headers = new WebHeaderCollection (HttpHeaderType.Response, false);
-
- return _headers;
- }
-
- set {
- if (value == null) {
- _headers = null;
-
- return;
- }
-
- if (value.State != HttpHeaderType.Response) {
- var msg = "The value is not valid for a response.";
-
- throw new InvalidOperationException (msg);
- }
-
- _headers = value;
- }
- }
-
- ///
- /// Gets or sets a value indicating whether the server requests
- /// a persistent connection.
- ///
- ///
- ///
- /// true if the server requests a persistent connection;
- /// otherwise, false.
- ///
- ///
- /// The default value is true.
- ///
- ///
- ///
- /// The response is already being sent.
- ///
- ///
- /// This instance is closed.
- ///
- public bool KeepAlive {
- get {
- return _keepAlive;
- }
-
- set {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- if (_headersSent) {
- var msg = "The response is already being sent.";
-
- throw new InvalidOperationException (msg);
- }
-
- _keepAlive = value;
- }
- }
-
- ///
- /// Gets a stream instance to which the entity body data can be written.
- ///
- ///
- /// A instance to which the entity body data can be
- /// written.
- ///
- ///
- /// This instance is closed.
- ///
- public Stream OutputStream {
- get {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- if (_outputStream == null)
- _outputStream = _context.Connection.GetResponseStream ();
-
- return _outputStream;
- }
- }
-
- ///
- /// Gets the HTTP version used for the response.
- ///
- ///
- ///
- /// A that represents the HTTP version used for
- /// the response.
- ///
- ///
- /// Always returns same as 1.1.
- ///
- ///
- public Version ProtocolVersion {
- get {
- return _version;
- }
- }
-
- ///
- /// Gets or sets the URL to which the client is redirected to locate
- /// a requested resource.
- ///
- ///
- ///
- /// A that represents the absolute URL for
- /// the redirect location.
- ///
- ///
- /// It is used for the value of the Location header.
- ///
- ///
- /// if no redirect location is specified.
- ///
- ///
- /// The default value is .
- ///
- ///
- ///
- ///
- /// The value specified for a set operation is an empty string.
- ///
- ///
- /// -or-
- ///
- ///
- /// The value specified for a set operation is not an absolute URL.
- ///
- ///
- ///
- /// The response is already being sent.
- ///
- ///
- /// This instance is closed.
- ///
- public string RedirectLocation {
- get {
- return _redirectLocation != null
- ? _redirectLocation.OriginalString
- : null;
- }
-
- set {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- if (_headersSent) {
- var msg = "The response is already being sent.";
-
- throw new InvalidOperationException (msg);
- }
-
- if (value == null) {
- _redirectLocation = null;
-
- return;
- }
-
- if (value.Length == 0)
- throw new ArgumentException ("An empty string.", "value");
-
- Uri uri;
-
- if (!Uri.TryCreate (value, UriKind.Absolute, out uri)) {
- var msg = "Not an absolute URL.";
-
- throw new ArgumentException (msg, "value");
- }
-
- _redirectLocation = uri;
- }
- }
-
- ///
- /// Gets or sets a value indicating whether the response uses the chunked
- /// transfer encoding.
- ///
- ///
- ///
- /// true if the response uses the chunked transfer encoding;
- /// otherwise, false.
- ///
- ///
- /// The default value is false.
- ///
- ///
- ///
- /// The response is already being sent.
- ///
- ///
- /// This instance is closed.
- ///
- public bool SendChunked {
- get {
- return _sendChunked;
- }
-
- set {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- if (_headersSent) {
- var msg = "The response is already being sent.";
-
- throw new InvalidOperationException (msg);
- }
-
- _sendChunked = value;
- }
- }
-
- ///
- /// Gets or sets the HTTP status code returned to the client.
- ///
- ///
- ///
- /// An that represents the HTTP status code for
- /// the response to the request.
- ///
- ///
- /// The default value is 200. It indicates that the request has
- /// succeeded.
- ///
- ///
- ///
- /// The response is already being sent.
- ///
- ///
- /// This instance is closed.
- ///
- ///
- ///
- /// The value specified for a set operation is invalid.
- ///
- ///
- /// Valid values are between 100 and 999 inclusive.
- ///
- ///
- public int StatusCode {
- get {
- return _statusCode;
- }
-
- set {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- if (_headersSent) {
- var msg = "The response is already being sent.";
-
- throw new InvalidOperationException (msg);
- }
-
- if (value < 100 || value > 999) {
- var msg = "A value is not between 100 and 999 inclusive.";
-
- throw new System.Net.ProtocolViolationException (msg);
- }
-
- _statusCode = value;
- _statusDescription = value.GetStatusDescription ();
- }
- }
-
- ///
- /// Gets or sets the description of the HTTP status code returned to
- /// the client.
- ///
- ///
- ///
- /// A that represents the description of
- /// the HTTP status code for the response to the request.
- ///
- ///
- /// The default value is
- /// the
- /// RFC 2616 description for the
- /// property value.
- ///
- ///
- /// An empty string if an RFC 2616 description does not exist.
- ///
- ///
- ///
- /// The value specified for a set operation contains an invalid character.
- ///
- ///
- /// The value specified for a set operation is .
- ///
- ///
- /// The response is already being sent.
- ///
- ///
- /// This instance is closed.
- ///
- public string StatusDescription {
- get {
- return _statusDescription;
- }
-
- set {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- if (_headersSent) {
- var msg = "The response is already being sent.";
-
- throw new InvalidOperationException (msg);
- }
-
- if (value == null)
- throw new ArgumentNullException ("value");
-
- if (value.Length == 0) {
- _statusDescription = _statusCode.GetStatusDescription ();
-
- return;
- }
-
- if (!isValidForStatusDescription (value)) {
- var msg = "It contains an invalid character.";
-
- throw new ArgumentException (msg, "value");
- }
-
- _statusDescription = value;
- }
- }
-
- #endregion
-
- #region Private Methods
-
- private bool canSetCookie (Cookie cookie)
- {
- var res = findCookie (cookie).ToList ();
-
- if (res.Count == 0)
- return true;
-
- var ver = cookie.Version;
-
- foreach (var c in res) {
- if (c.Version == ver)
- return true;
- }
-
- return false;
- }
-
- private void close (bool force)
- {
- _disposed = true;
-
- _context.Connection.Close (force);
- }
-
- private void close (byte[] responseEntity, int bufferLength, bool willBlock)
- {
- if (willBlock) {
- OutputStream.WriteBytes (responseEntity, bufferLength);
- close (false);
-
- return;
- }
-
- OutputStream.WriteBytesAsync (
- responseEntity,
- bufferLength,
- () => close (false),
- null
- );
- }
-
- private static string createContentTypeHeaderText (
- string value,
- Encoding encoding
- )
- {
- if (value.Contains ("charset="))
- return value;
-
- if (encoding == null)
- return value;
-
- var fmt = "{0}; charset={1}";
-
- return String.Format (fmt, value, encoding.WebName);
- }
-
- private IEnumerable findCookie (Cookie cookie)
- {
- if (_cookies == null || _cookies.Count == 0)
- yield break;
-
- foreach (var c in _cookies) {
- if (c.EqualsWithoutValueAndVersion (cookie))
- yield return c;
- }
- }
-
- private static bool isValidForContentType (string value)
- {
- foreach (var c in value) {
- if (c < 0x20)
- return false;
-
- if (c > 0x7e)
- return false;
-
- if ("()<>@:\\[]?{}".IndexOf (c) > -1)
- return false;
- }
-
- return true;
- }
-
- private static bool isValidForStatusDescription (string value)
- {
- foreach (var c in value) {
- if (c < 0x20)
- return false;
-
- if (c > 0x7e)
- return false;
- }
-
- return true;
- }
-
- #endregion
-
- #region Public Methods
-
- ///
- /// Closes the connection to the client without sending a response.
- ///
- public void Abort ()
- {
- if (_disposed)
- return;
-
- close (true);
- }
-
- ///
- /// Appends an HTTP cookie to the cookies sent with the response.
- ///
- ///
- /// A to append.
- ///
- ///
- /// is .
- ///
- public void AppendCookie (Cookie cookie)
- {
- Cookies.Add (cookie);
- }
-
- ///
- /// Appends an HTTP header with the specified name and value to
- /// the headers for the response.
- ///
- ///
- /// A that specifies the name of the header to
- /// append.
- ///
- ///
- /// A that specifies the value of the header to
- /// append.
- ///
- ///
- ///
- /// is an empty string.
- ///
- ///
- /// -or-
- ///
- ///
- /// is a string of spaces.
- ///
- ///
- /// -or-
- ///
- ///
- /// contains an invalid character.
- ///
- ///
- /// -or-
- ///
- ///
- /// contains an invalid character.
- ///
- ///
- /// -or-
- ///
- ///
- /// is a restricted header name.
- ///
- ///
- ///
- /// is .
- ///
- ///
- /// The length of is greater than 65,535
- /// characters.
- ///
- ///
- /// The current headers do not allow the header.
- ///
- public void AppendHeader (string name, string value)
- {
- Headers.Add (name, value);
- }
-
- ///
- /// Sends the response to the client and releases the resources used by
- /// this instance.
- ///
- public void Close ()
- {
- if (_disposed)
- return;
-
- close (false);
- }
-
- ///
- /// Sends the response with the specified entity body data to the client
- /// and releases the resources used by this instance.
- ///
- ///
- /// An array of that contains the entity body data.
- ///
- ///
- /// A : true if this method blocks execution while
- /// flushing the stream to the client; otherwise, false.
- ///
- ///
- /// is .
- ///
- ///
- /// This instance is closed.
- ///
- public void Close (byte[] responseEntity, bool willBlock)
- {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- if (responseEntity == null)
- throw new ArgumentNullException ("responseEntity");
-
- var len = responseEntity.LongLength;
-
- if (len > Int32.MaxValue) {
- close (responseEntity, 1024, willBlock);
-
- return;
- }
-
- var stream = OutputStream;
-
- if (willBlock) {
- stream.Write (responseEntity, 0, (int) len);
- close (false);
-
- return;
- }
-
- stream.BeginWrite (
- responseEntity,
- 0,
- (int) len,
- ar => {
- stream.EndWrite (ar);
- close (false);
- },
- null
- );
- }
-
- ///
- /// Copies some properties from the specified response instance to
- /// this instance.
- ///
- ///
- /// A to copy.
- ///
- ///
- /// is .
- ///
- public void CopyFrom (HttpListenerResponse templateResponse)
- {
- if (templateResponse == null)
- throw new ArgumentNullException ("templateResponse");
-
- var headers = templateResponse._headers;
-
- if (headers != null) {
- if (_headers != null)
- _headers.Clear ();
-
- Headers.Add (headers);
- }
- else {
- _headers = null;
- }
-
- _contentLength = templateResponse._contentLength;
- _statusCode = templateResponse._statusCode;
- _statusDescription = templateResponse._statusDescription;
- _keepAlive = templateResponse._keepAlive;
- _version = templateResponse._version;
- }
-
- ///
- /// Configures the response to redirect the client's request to
- /// the specified URL.
- ///
- ///
- /// This method sets the property to
- /// , the property to
- /// 302, and the property to "Found".
- ///
- ///
- /// A that specifies the absolute URL to which
- /// the client is redirected to locate a requested resource.
- ///
- ///
- ///
- /// is an empty string.
- ///
- ///
- /// -or-
- ///
- ///
- /// is not an absolute URL.
- ///
- ///
- ///
- /// is .
- ///
- ///
- /// The response is already being sent.
- ///
- ///
- /// This instance is closed.
- ///
- public void Redirect (string url)
- {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- if (_headersSent) {
- var msg = "The response is already being sent.";
-
- throw new InvalidOperationException (msg);
- }
-
- if (url == null)
- throw new ArgumentNullException ("url");
-
- if (url.Length == 0)
- throw new ArgumentException ("An empty string.", "url");
-
- Uri uri;
-
- if (!Uri.TryCreate (url, UriKind.Absolute, out uri)) {
- var msg = "Not an absolute URL.";
-
- throw new ArgumentException (msg, "url");
- }
-
- _redirectLocation = uri;
- _statusCode = 302;
- _statusDescription = "Found";
- }
-
- ///
- /// Adds or updates an HTTP cookie in the cookies sent with the response.
- ///
- ///
- /// A to set.
- ///
- ///
- /// already exists in the cookies but
- /// it cannot be updated.
- ///
- ///
- /// is .
- ///
- public void SetCookie (Cookie cookie)
- {
- if (cookie == null)
- throw new ArgumentNullException ("cookie");
-
- if (!canSetCookie (cookie)) {
- var msg = "It cannot be updated.";
-
- throw new ArgumentException (msg, "cookie");
- }
-
- Cookies.Add (cookie);
- }
-
- ///
- /// Adds or updates an HTTP header with the specified name and value in
- /// the headers for the response.
- ///
- ///
- /// A that specifies the name of the header to set.
- ///
- ///
- /// A that specifies the value of the header to set.
- ///
- ///
- ///
- /// is an empty string.
- ///
- ///
- /// -or-
- ///
- ///
- /// is a string of spaces.
- ///
- ///
- /// -or-
- ///
- ///
- /// contains an invalid character.
- ///
- ///
- /// -or-
- ///
- ///
- /// contains an invalid character.
- ///
- ///
- /// -or-
- ///
- ///
- /// is a restricted header name.
- ///
- ///
- ///
- /// is .
- ///
- ///
- /// The length of is greater than 65,535
- /// characters.
- ///
- ///
- /// The current headers do not allow the header.
- ///
- public void SetHeader (string name, string value)
- {
- Headers.Set (name, value);
- }
-
- #endregion
-
- #region Explicit Interface Implementations
-
- ///
- /// Releases all resources used by this instance.
- ///
- void IDisposable.Dispose ()
- {
- if (_disposed)
- return;
-
- close (true);
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Net/HttpRequestHeader.cs b/websocket-sharp/Net/HttpRequestHeader.cs
deleted file mode 100644
index aab3497ff..000000000
--- a/websocket-sharp/Net/HttpRequestHeader.cs
+++ /dev/null
@@ -1,233 +0,0 @@
-#region License
-/*
- * HttpRequestHeader.cs
- *
- * This code is derived from HttpRequestHeader.cs (System.Net) of Mono
- * (http://www.mono-project.com).
- *
- * The MIT License
- *
- * Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
- * Copyright (c) 2014-2020 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-#region Authors
-/*
- * Authors:
- * - Gonzalo Paniagua Javier
- */
-#endregion
-
-namespace WebSocketSharp.Net
-{
- ///
- /// Indicates the HTTP header that may be specified in a client request.
- ///
- ///
- /// The headers of this enumeration are defined in
- /// RFC 2616 or
- /// RFC 6455.
- ///
- public enum HttpRequestHeader
- {
- ///
- /// Indicates the Cache-Control header.
- ///
- CacheControl,
- ///
- /// Indicates the Connection header.
- ///
- Connection,
- ///
- /// Indicates the Date header.
- ///
- Date,
- ///
- /// Indicates the Keep-Alive header.
- ///
- KeepAlive,
- ///
- /// Indicates the Pragma header.
- ///
- Pragma,
- ///
- /// Indicates the Trailer header.
- ///
- Trailer,
- ///
- /// Indicates the Transfer-Encoding header.
- ///
- TransferEncoding,
- ///
- /// Indicates the Upgrade header.
- ///
- Upgrade,
- ///
- /// Indicates the Via header.
- ///
- Via,
- ///
- /// Indicates the Warning header.
- ///
- Warning,
- ///
- /// Indicates the Allow header.
- ///
- Allow,
- ///
- /// Indicates the Content-Length header.
- ///
- ContentLength,
- ///
- /// Indicates the Content-Type header.
- ///
- ContentType,
- ///
- /// Indicates the Content-Encoding header.
- ///
- ContentEncoding,
- ///
- /// Indicates the Content-Language header.
- ///
- ContentLanguage,
- ///
- /// Indicates the Content-Location header.
- ///
- ContentLocation,
- ///
- /// Indicates the Content-MD5 header.
- ///
- ContentMd5,
- ///
- /// Indicates the Content-Range header.
- ///
- ContentRange,
- ///
- /// Indicates the Expires header.
- ///
- Expires,
- ///
- /// Indicates the Last-Modified header.
- ///
- LastModified,
- ///
- /// Indicates the Accept header.
- ///
- Accept,
- ///
- /// Indicates the Accept-Charset header.
- ///
- AcceptCharset,
- ///
- /// Indicates the Accept-Encoding header.
- ///
- AcceptEncoding,
- ///
- /// Indicates the Accept-Language header.
- ///
- AcceptLanguage,
- ///
- /// Indicates the Authorization header.
- ///
- Authorization,
- ///
- /// Indicates the Cookie header.
- ///
- Cookie,
- ///
- /// Indicates the Expect header.
- ///
- Expect,
- ///
- /// Indicates the From header.
- ///
- From,
- ///
- /// Indicates the Host header.
- ///
- Host,
- ///
- /// Indicates the If-Match header.
- ///
- IfMatch,
- ///
- /// Indicates the If-Modified-Since header.
- ///
- IfModifiedSince,
- ///
- /// Indicates the If-None-Match header.
- ///
- IfNoneMatch,
- ///
- /// Indicates the If-Range header.
- ///
- IfRange,
- ///
- /// Indicates the If-Unmodified-Since header.
- ///
- IfUnmodifiedSince,
- ///
- /// Indicates the Max-Forwards header.
- ///
- MaxForwards,
- ///
- /// Indicates the Proxy-Authorization header.
- ///
- ProxyAuthorization,
- ///
- /// Indicates the Referer header.
- ///
- Referer,
- ///
- /// Indicates the Range header.
- ///
- Range,
- ///
- /// Indicates the TE header.
- ///
- Te,
- ///
- /// Indicates the Translate header.
- ///
- Translate,
- ///
- /// Indicates the User-Agent header.
- ///
- UserAgent,
- ///
- /// Indicates the Sec-WebSocket-Key header.
- ///
- SecWebSocketKey,
- ///
- /// Indicates the Sec-WebSocket-Extensions header.
- ///
- SecWebSocketExtensions,
- ///
- /// Indicates the Sec-WebSocket-Protocol header.
- ///
- SecWebSocketProtocol,
- ///
- /// Indicates the Sec-WebSocket-Version header.
- ///
- SecWebSocketVersion
- }
-}
diff --git a/websocket-sharp/Net/HttpResponseHeader.cs b/websocket-sharp/Net/HttpResponseHeader.cs
deleted file mode 100644
index d32afe6c9..000000000
--- a/websocket-sharp/Net/HttpResponseHeader.cs
+++ /dev/null
@@ -1,189 +0,0 @@
-#region License
-/*
- * HttpResponseHeader.cs
- *
- * This code is derived from HttpResponseHeader.cs (System.Net) of Mono
- * (http://www.mono-project.com).
- *
- * The MIT License
- *
- * Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
- * Copyright (c) 2014-2020 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-#region Authors
-/*
- * Authors:
- * - Gonzalo Paniagua Javier
- */
-#endregion
-
-namespace WebSocketSharp.Net
-{
- ///
- /// Indicates the HTTP header that can be specified in a server response.
- ///
- ///
- /// The headers of this enumeration are defined in
- /// RFC 2616 or
- /// RFC 6455.
- ///
- public enum HttpResponseHeader
- {
- ///
- /// Indicates the Cache-Control header.
- ///
- CacheControl,
- ///
- /// Indicates the Connection header.
- ///
- Connection,
- ///
- /// Indicates the Date header.
- ///
- Date,
- ///
- /// Indicates the Keep-Alive header.
- ///
- KeepAlive,
- ///
- /// Indicates the Pragma header.
- ///
- Pragma,
- ///
- /// Indicates the Trailer header.
- ///
- Trailer,
- ///
- /// Indicates the Transfer-Encoding header.
- ///
- TransferEncoding,
- ///
- /// Indicates the Upgrade header.
- ///
- Upgrade,
- ///
- /// Indicates the Via header.
- ///
- Via,
- ///
- /// Indicates the Warning header.
- ///
- Warning,
- ///
- /// Indicates the Allow header.
- ///
- Allow,
- ///
- /// Indicates the Content-Length header.
- ///
- ContentLength,
- ///
- /// Indicates the Content-Type header.
- ///
- ContentType,
- ///
- /// Indicates the Content-Encoding header.
- ///
- ContentEncoding,
- ///
- /// Indicates the Content-Language header.
- ///
- ContentLanguage,
- ///
- /// Indicates the Content-Location header.
- ///
- ContentLocation,
- ///
- /// Indicates the Content-MD5 header.
- ///
- ContentMd5,
- ///
- /// Indicates the Content-Range header.
- ///
- ContentRange,
- ///
- /// Indicates the Expires header.
- ///
- Expires,
- ///
- /// Indicates the Last-Modified header.
- ///
- LastModified,
- ///
- /// Indicates the Accept-Ranges header.
- ///
- AcceptRanges,
- ///
- /// Indicates the Age header.
- ///
- Age,
- ///
- /// Indicates the ETag header.
- ///
- ETag,
- ///
- /// Indicates the Location header.
- ///
- Location,
- ///
- /// Indicates the Proxy-Authenticate header.
- ///
- ProxyAuthenticate,
- ///
- /// Indicates the Retry-After header.
- ///
- RetryAfter,
- ///
- /// Indicates the Server header.
- ///
- Server,
- ///
- /// Indicates the Set-Cookie header.
- ///
- SetCookie,
- ///
- /// Indicates the Vary header.
- ///
- Vary,
- ///
- /// Indicates the WWW-Authenticate header.
- ///
- WwwAuthenticate,
- ///
- /// Indicates the Sec-WebSocket-Extensions header.
- ///
- SecWebSocketExtensions,
- ///
- /// Indicates the Sec-WebSocket-Accept header.
- ///
- SecWebSocketAccept,
- ///
- /// Indicates the Sec-WebSocket-Protocol header.
- ///
- SecWebSocketProtocol,
- ///
- /// Indicates the Sec-WebSocket-Version header.
- ///
- SecWebSocketVersion
- }
-}
diff --git a/websocket-sharp/Net/HttpStatusCode.cs b/websocket-sharp/Net/HttpStatusCode.cs
deleted file mode 100644
index b773a4964..000000000
--- a/websocket-sharp/Net/HttpStatusCode.cs
+++ /dev/null
@@ -1,346 +0,0 @@
-#region License
-/*
- * HttpStatusCode.cs
- *
- * This code is derived from HttpStatusCode.cs (System.Net) of Mono
- * (http://www.mono-project.com).
- *
- * It was automatically generated from ECMA CLI XML Library Specification.
- * Generator: libgen.xsl [1.0; (C) Sergey Chaban (serge@wildwestsoftware.com)]
- * Created: Wed, 5 Sep 2001 06:32:05 UTC
- * Source file: AllTypes.xml
- * URL: http://msdn.microsoft.com/net/ecma/AllTypes.xml
- *
- * The MIT License
- *
- * Copyright (c) 2001 Ximian, Inc. (http://www.ximian.com)
- * Copyright (c) 2012-2020 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-namespace WebSocketSharp.Net
-{
- ///
- /// Indicates the HTTP status code that can be specified in a server response.
- ///
- ///
- /// The values of this enumeration are defined in
- /// RFC 2616.
- ///
- public enum HttpStatusCode
- {
- ///
- /// Equivalent to status code 100. Indicates that the client should continue
- /// with its request.
- ///
- Continue = 100,
- ///
- /// Equivalent to status code 101. Indicates that the server is switching
- /// the HTTP version or protocol on the connection.
- ///
- SwitchingProtocols = 101,
- ///
- /// Equivalent to status code 200. Indicates that the client's request has
- /// succeeded.
- ///
- OK = 200,
- ///
- /// Equivalent to status code 201. Indicates that the client's request has
- /// been fulfilled and resulted in a new resource being created.
- ///
- Created = 201,
- ///
- /// Equivalent to status code 202. Indicates that the client's request has
- /// been accepted for processing, but the processing has not been completed.
- ///
- Accepted = 202,
- ///
- /// Equivalent to status code 203. Indicates that the returned metainformation
- /// is from a local or a third-party copy instead of the origin server.
- ///
- NonAuthoritativeInformation = 203,
- ///
- /// Equivalent to status code 204. Indicates that the server has fulfilled
- /// the client's request but does not need to return an entity-body.
- ///
- NoContent = 204,
- ///
- /// Equivalent to status code 205. Indicates that the server has fulfilled
- /// the client's request, and the user agent should reset the document view
- /// which caused the request to be sent.
- ///
- ResetContent = 205,
- ///
- /// Equivalent to status code 206. Indicates that the server has fulfilled
- /// the partial GET request for the resource.
- ///
- PartialContent = 206,
- ///
- ///
- /// Equivalent to status code 300. Indicates that the requested resource
- /// corresponds to any of multiple representations.
- ///
- ///
- /// MultipleChoices is a synonym for Ambiguous.
- ///
- ///
- MultipleChoices = 300,
- ///
- ///
- /// Equivalent to status code 300. Indicates that the requested resource
- /// corresponds to any of multiple representations.
- ///
- ///
- /// Ambiguous is a synonym for MultipleChoices.
- ///
- ///
- Ambiguous = 300,
- ///
- ///
- /// Equivalent to status code 301. Indicates that the requested resource
- /// has been assigned a new permanent URI and any future references to
- /// this resource should use one of the returned URIs.
- ///
- ///
- /// MovedPermanently is a synonym for Moved.
- ///
- ///
- MovedPermanently = 301,
- ///
- ///
- /// Equivalent to status code 301. Indicates that the requested resource
- /// has been assigned a new permanent URI and any future references to
- /// this resource should use one of the returned URIs.
- ///
- ///
- /// Moved is a synonym for MovedPermanently.
- ///
- ///
- Moved = 301,
- ///
- ///
- /// Equivalent to status code 302. Indicates that the requested resource
- /// is located temporarily under a different URI.
- ///
- ///
- /// Found is a synonym for Redirect.
- ///
- ///
- Found = 302,
- ///
- ///
- /// Equivalent to status code 302. Indicates that the requested resource
- /// is located temporarily under a different URI.
- ///
- ///
- /// Redirect is a synonym for Found.
- ///
- ///
- Redirect = 302,
- ///
- ///
- /// Equivalent to status code 303. Indicates that the response to
- /// the request can be found under a different URI and should be
- /// retrieved using a GET method on that resource.
- ///
- ///
- /// SeeOther is a synonym for RedirectMethod.
- ///
- ///
- SeeOther = 303,
- ///
- ///
- /// Equivalent to status code 303. Indicates that the response to
- /// the request can be found under a different URI and should be
- /// retrieved using a GET method on that resource.
- ///
- ///
- /// RedirectMethod is a synonym for SeeOther.
- ///
- ///
- RedirectMethod = 303,
- ///
- /// Equivalent to status code 304. Indicates that the client has performed
- /// a conditional GET request and access is allowed, but the document has
- /// not been modified.
- ///
- NotModified = 304,
- ///
- /// Equivalent to status code 305. Indicates that the requested resource
- /// must be accessed through the proxy given by the Location field.
- ///
- UseProxy = 305,
- ///
- /// Equivalent to status code 306. This status code was used in a previous
- /// version of the specification, is no longer used, and is reserved for
- /// future use.
- ///
- Unused = 306,
- ///
- ///
- /// Equivalent to status code 307. Indicates that the requested resource
- /// is located temporarily under a different URI.
- ///
- ///
- /// TemporaryRedirect is a synonym for RedirectKeepVerb.
- ///
- ///
- TemporaryRedirect = 307,
- ///
- ///
- /// Equivalent to status code 307. Indicates that the requested resource
- /// is located temporarily under a different URI.
- ///
- ///
- /// RedirectKeepVerb is a synonym for TemporaryRedirect.
- ///
- ///
- RedirectKeepVerb = 307,
- ///
- /// Equivalent to status code 400. Indicates that the client's request could
- /// not be understood by the server due to malformed syntax.
- ///
- BadRequest = 400,
- ///
- /// Equivalent to status code 401. Indicates that the client's request
- /// requires user authentication.
- ///
- Unauthorized = 401,
- ///
- /// Equivalent to status code 402. This status code is reserved for future
- /// use.
- ///
- PaymentRequired = 402,
- ///
- /// Equivalent to status code 403. Indicates that the server understood
- /// the client's request but is refusing to fulfill it.
- ///
- Forbidden = 403,
- ///
- /// Equivalent to status code 404. Indicates that the server has not found
- /// anything matching the request URI.
- ///
- NotFound = 404,
- ///
- /// Equivalent to status code 405. Indicates that the method specified
- /// in the request line is not allowed for the resource identified by
- /// the request URI.
- ///
- MethodNotAllowed = 405,
- ///
- /// Equivalent to status code 406. Indicates that the server does not
- /// have the appropriate resource to respond to the Accept headers in
- /// the client's request.
- ///
- NotAcceptable = 406,
- ///
- /// Equivalent to status code 407. Indicates that the client must first
- /// authenticate itself with the proxy.
- ///
- ProxyAuthenticationRequired = 407,
- ///
- /// Equivalent to status code 408. Indicates that the client did not produce
- /// a request within the time that the server was prepared to wait.
- ///
- RequestTimeout = 408,
- ///
- /// Equivalent to status code 409. Indicates that the client's request could
- /// not be completed due to a conflict on the server.
- ///
- Conflict = 409,
- ///
- /// Equivalent to status code 410. Indicates that the requested resource is
- /// no longer available at the server and no forwarding address is known.
- ///
- Gone = 410,
- ///
- /// Equivalent to status code 411. Indicates that the server refuses to
- /// accept the client's request without a defined Content-Length.
- ///
- LengthRequired = 411,
- ///
- /// Equivalent to status code 412. Indicates that the precondition given in
- /// one or more of the request headers evaluated to false when it was tested
- /// on the server.
- ///
- PreconditionFailed = 412,
- ///
- /// Equivalent to status code 413. Indicates that the entity of the client's
- /// request is larger than the server is willing or able to process.
- ///
- RequestEntityTooLarge = 413,
- ///
- /// Equivalent to status code 414. Indicates that the request URI is longer
- /// than the server is willing to interpret.
- ///
- RequestUriTooLong = 414,
- ///
- /// Equivalent to status code 415. Indicates that the entity of the client's
- /// request is in a format not supported by the requested resource for the
- /// requested method.
- ///
- UnsupportedMediaType = 415,
- ///
- /// Equivalent to status code 416. Indicates that none of the range
- /// specifier values in a Range request header overlap the current
- /// extent of the selected resource.
- ///
- RequestedRangeNotSatisfiable = 416,
- ///
- /// Equivalent to status code 417. Indicates that the expectation given in
- /// an Expect request header could not be met by the server.
- ///
- ExpectationFailed = 417,
- ///
- /// Equivalent to status code 500. Indicates that the server encountered
- /// an unexpected condition which prevented it from fulfilling the client's
- /// request.
- ///
- InternalServerError = 500,
- ///
- /// Equivalent to status code 501. Indicates that the server does not
- /// support the functionality required to fulfill the client's request.
- ///
- NotImplemented = 501,
- ///
- /// Equivalent to status code 502. Indicates that a gateway or proxy server
- /// received an invalid response from the upstream server.
- ///
- BadGateway = 502,
- ///
- /// Equivalent to status code 503. Indicates that the server is currently
- /// unable to handle the client's request due to a temporary overloading
- /// or maintenance of the server.
- ///
- ServiceUnavailable = 503,
- ///
- /// Equivalent to status code 504. Indicates that a gateway or proxy server
- /// did not receive a timely response from the upstream server or some other
- /// auxiliary server.
- ///
- GatewayTimeout = 504,
- ///
- /// Equivalent to status code 505. Indicates that the server does not
- /// support the HTTP version used in the client's request.
- ///
- HttpVersionNotSupported = 505,
- }
-}
diff --git a/websocket-sharp/Net/HttpStreamAsyncResult.cs b/websocket-sharp/Net/HttpStreamAsyncResult.cs
deleted file mode 100644
index 09447ea21..000000000
--- a/websocket-sharp/Net/HttpStreamAsyncResult.cs
+++ /dev/null
@@ -1,201 +0,0 @@
-#region License
-/*
- * HttpStreamAsyncResult.cs
- *
- * This code is derived from HttpStreamAsyncResult.cs (System.Net) of Mono
- * (http://www.mono-project.com).
- *
- * The MIT License
- *
- * Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
- * Copyright (c) 2012-2021 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-#region Authors
-/*
- * Authors:
- * - Gonzalo Paniagua Javier
- */
-#endregion
-
-using System;
-using System.Threading;
-
-namespace WebSocketSharp.Net
-{
- internal class HttpStreamAsyncResult : IAsyncResult
- {
- #region Private Fields
-
- private byte[] _buffer;
- private AsyncCallback _callback;
- private bool _completed;
- private int _count;
- private Exception _exception;
- private int _offset;
- private object _state;
- private object _sync;
- private int _syncRead;
- private ManualResetEvent _waitHandle;
-
- #endregion
-
- #region Internal Constructors
-
- internal HttpStreamAsyncResult (AsyncCallback callback, object state)
- {
- _callback = callback;
- _state = state;
-
- _sync = new object ();
- }
-
- #endregion
-
- #region Internal Properties
-
- internal byte[] Buffer {
- get {
- return _buffer;
- }
-
- set {
- _buffer = value;
- }
- }
-
- internal int Count {
- get {
- return _count;
- }
-
- set {
- _count = value;
- }
- }
-
- internal Exception Exception {
- get {
- return _exception;
- }
- }
-
- internal bool HasException {
- get {
- return _exception != null;
- }
- }
-
- internal int Offset {
- get {
- return _offset;
- }
-
- set {
- _offset = value;
- }
- }
-
- internal int SyncRead {
- get {
- return _syncRead;
- }
-
- set {
- _syncRead = value;
- }
- }
-
- #endregion
-
- #region Public Properties
-
- public object AsyncState {
- get {
- return _state;
- }
- }
-
- public WaitHandle AsyncWaitHandle {
- get {
- lock (_sync) {
- if (_waitHandle == null)
- _waitHandle = new ManualResetEvent (_completed);
-
- return _waitHandle;
- }
- }
- }
-
- public bool CompletedSynchronously {
- get {
- return _syncRead == _count;
- }
- }
-
- public bool IsCompleted {
- get {
- lock (_sync)
- return _completed;
- }
- }
-
- #endregion
-
- #region Internal Methods
-
- internal void Complete ()
- {
- lock (_sync) {
- if (_completed)
- return;
-
- _completed = true;
-
- if (_waitHandle != null)
- _waitHandle.Set ();
-
- if (_callback != null)
- _callback.BeginInvoke (this, ar => _callback.EndInvoke (ar), null);
- }
- }
-
- internal void Complete (Exception exception)
- {
- lock (_sync) {
- if (_completed)
- return;
-
- _completed = true;
- _exception = exception;
-
- if (_waitHandle != null)
- _waitHandle.Set ();
-
- if (_callback != null)
- _callback.BeginInvoke (this, ar => _callback.EndInvoke (ar), null);
- }
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Net/HttpUtility.cs b/websocket-sharp/Net/HttpUtility.cs
deleted file mode 100644
index b7db7b922..000000000
--- a/websocket-sharp/Net/HttpUtility.cs
+++ /dev/null
@@ -1,1237 +0,0 @@
-#region License
-/*
- * HttpUtility.cs
- *
- * This code is derived from HttpUtility.cs (System.Net) of Mono
- * (http://www.mono-project.com).
- *
- * The MIT License
- *
- * Copyright (c) 2005-2009 Novell, Inc. (http://www.novell.com)
- * Copyright (c) 2012-2024 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-#region Authors
-/*
- * Authors:
- * - Patrik Torstensson
- * - Wictor Wilén (decode/encode functions)
- * - Tim Coleman
- * - Gonzalo Paniagua Javier
- */
-#endregion
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Collections.Specialized;
-using System.Globalization;
-using System.IO;
-using System.Security.Principal;
-using System.Text;
-
-namespace WebSocketSharp.Net
-{
- internal static class HttpUtility
- {
- #region Private Fields
-
- private static Dictionary _entities;
- private static char[] _hexChars;
- private static object _sync;
-
- #endregion
-
- #region Static Constructor
-
- static HttpUtility ()
- {
- _hexChars = "0123456789ABCDEF".ToCharArray ();
- _sync = new object ();
- }
-
- #endregion
-
- #region Private Methods
-
- private static Dictionary getEntities ()
- {
- lock (_sync) {
- if (_entities == null)
- initEntities ();
-
- return _entities;
- }
- }
-
- private static int getNumber (char c)
- {
- if (c >= '0' && c <= '9')
- return c - '0';
-
- if (c >= 'A' && c <= 'F')
- return c - 'A' + 10;
-
- if (c >= 'a' && c <= 'f')
- return c - 'a' + 10;
-
- return -1;
- }
-
- private static int getNumber (byte[] bytes, int offset, int count)
- {
- var ret = 0;
-
- var end = offset + count - 1;
-
- for (var i = offset; i <= end; i++) {
- var c = (char) bytes[i];
- var n = getNumber (c);
-
- if (n == -1)
- return -1;
-
- ret = (ret << 4) + n;
- }
-
- return ret;
- }
-
- private static int getNumber (string s, int offset, int count)
- {
- var ret = 0;
-
- var end = offset + count - 1;
-
- for (var i = offset; i <= end; i++) {
- var c = s[i];
- var n = getNumber (c);
-
- if (n == -1)
- return -1;
-
- ret = (ret << 4) + n;
- }
-
- return ret;
- }
-
- private static string htmlDecode (string s)
- {
- var buff = new StringBuilder ();
-
- // 0: None
- // 1: Right after '&'
- // 2: Between '&' and ';' but no NCR
- // 3: '#' found after '&' and getting numbers
- // 4: 'x' found after '#' and getting numbers
- var state = 0;
-
- var reference = new StringBuilder ();
- var num = 0;
-
- foreach (var c in s) {
- if (state == 0) {
- if (c == '&') {
- reference.Append ('&');
-
- state = 1;
-
- continue;
- }
-
- buff.Append (c);
-
- continue;
- }
-
- if (c == '&') {
- buff.Append (reference.ToString ());
-
- reference.Length = 0;
-
- reference.Append ('&');
-
- state = 1;
-
- continue;
- }
-
- reference.Append (c);
-
- if (state == 1) {
- if (c == ';') {
- buff.Append (reference.ToString ());
-
- reference.Length = 0;
- state = 0;
-
- continue;
- }
-
- num = 0;
- state = c == '#' ? 3 : 2;
-
- continue;
- }
-
- if (state == 2) {
- if (c == ';') {
- var entity = reference.ToString ();
- var name = entity.Substring (1, entity.Length - 2);
-
- var entities = getEntities ();
-
- if (entities.ContainsKey (name))
- buff.Append (entities[name]);
- else
- buff.Append (entity);
-
- reference.Length = 0;
- state = 0;
-
- continue;
- }
-
- continue;
- }
-
- if (state == 3) {
- if (c == ';') {
- if (reference.Length > 3 && num < 65536)
- buff.Append ((char) num);
- else
- buff.Append (reference.ToString ());
-
- reference.Length = 0;
- state = 0;
-
- continue;
- }
-
- if (c == 'x') {
- state = reference.Length == 3 ? 4 : 2;
-
- continue;
- }
-
- if (!isNumeric (c)) {
- state = 2;
-
- continue;
- }
-
- num = num * 10 + (c - '0');
-
- continue;
- }
-
- if (state == 4) {
- if (c == ';') {
- if (reference.Length > 4 && num < 65536)
- buff.Append ((char) num);
- else
- buff.Append (reference.ToString ());
-
- reference.Length = 0;
- state = 0;
-
- continue;
- }
-
- var n = getNumber (c);
-
- if (n == -1) {
- state = 2;
-
- continue;
- }
-
- num = (num << 4) + n;
- }
- }
-
- if (reference.Length > 0)
- buff.Append (reference.ToString ());
-
- return buff.ToString ();
- }
-
- ///
- /// Converts the specified string to an HTML-encoded string.
- ///
- ///
- ///
- /// This method starts encoding with a NCR from the character code 160
- /// but does not stop at the character code 255.
- ///
- ///
- /// One reason is the unicode characters < and > that
- /// look like < and >.
- ///
- ///
- ///
- /// A that represents an encoded string.
- ///
- ///
- /// A to encode.
- ///
- ///
- /// A : true if encodes without a NCR;
- /// otherwise, false.
- ///
- private static string htmlEncode (string s, bool minimal)
- {
- var buff = new StringBuilder ();
-
- foreach (var c in s) {
- if (c == '"') {
- buff.Append (""");
-
- continue;
- }
-
- if (c == '&') {
- buff.Append ("&");
-
- continue;
- }
-
- if (c == '<') {
- buff.Append ("<");
-
- continue;
- }
-
- if (c == '>') {
- buff.Append (">");
-
- continue;
- }
-
- if (c > 159) {
- if (!minimal) {
- var val = String.Format ("{0};", (int) c);
-
- buff.Append (val);
-
- continue;
- }
- }
-
- buff.Append (c);
- }
-
- return buff.ToString ();
- }
-
- ///
- /// Initializes the _entities field.
- ///
- ///
- /// This method builds a dictionary of HTML character entity references.
- /// This dictionary comes from the HTML 4.01 W3C recommendation.
- ///
- private static void initEntities ()
- {
- _entities = new Dictionary ();
-
- _entities.Add ("nbsp", '\u00A0');
- _entities.Add ("iexcl", '\u00A1');
- _entities.Add ("cent", '\u00A2');
- _entities.Add ("pound", '\u00A3');
- _entities.Add ("curren", '\u00A4');
- _entities.Add ("yen", '\u00A5');
- _entities.Add ("brvbar", '\u00A6');
- _entities.Add ("sect", '\u00A7');
- _entities.Add ("uml", '\u00A8');
- _entities.Add ("copy", '\u00A9');
- _entities.Add ("ordf", '\u00AA');
- _entities.Add ("laquo", '\u00AB');
- _entities.Add ("not", '\u00AC');
- _entities.Add ("shy", '\u00AD');
- _entities.Add ("reg", '\u00AE');
- _entities.Add ("macr", '\u00AF');
- _entities.Add ("deg", '\u00B0');
- _entities.Add ("plusmn", '\u00B1');
- _entities.Add ("sup2", '\u00B2');
- _entities.Add ("sup3", '\u00B3');
- _entities.Add ("acute", '\u00B4');
- _entities.Add ("micro", '\u00B5');
- _entities.Add ("para", '\u00B6');
- _entities.Add ("middot", '\u00B7');
- _entities.Add ("cedil", '\u00B8');
- _entities.Add ("sup1", '\u00B9');
- _entities.Add ("ordm", '\u00BA');
- _entities.Add ("raquo", '\u00BB');
- _entities.Add ("frac14", '\u00BC');
- _entities.Add ("frac12", '\u00BD');
- _entities.Add ("frac34", '\u00BE');
- _entities.Add ("iquest", '\u00BF');
- _entities.Add ("Agrave", '\u00C0');
- _entities.Add ("Aacute", '\u00C1');
- _entities.Add ("Acirc", '\u00C2');
- _entities.Add ("Atilde", '\u00C3');
- _entities.Add ("Auml", '\u00C4');
- _entities.Add ("Aring", '\u00C5');
- _entities.Add ("AElig", '\u00C6');
- _entities.Add ("Ccedil", '\u00C7');
- _entities.Add ("Egrave", '\u00C8');
- _entities.Add ("Eacute", '\u00C9');
- _entities.Add ("Ecirc", '\u00CA');
- _entities.Add ("Euml", '\u00CB');
- _entities.Add ("Igrave", '\u00CC');
- _entities.Add ("Iacute", '\u00CD');
- _entities.Add ("Icirc", '\u00CE');
- _entities.Add ("Iuml", '\u00CF');
- _entities.Add ("ETH", '\u00D0');
- _entities.Add ("Ntilde", '\u00D1');
- _entities.Add ("Ograve", '\u00D2');
- _entities.Add ("Oacute", '\u00D3');
- _entities.Add ("Ocirc", '\u00D4');
- _entities.Add ("Otilde", '\u00D5');
- _entities.Add ("Ouml", '\u00D6');
- _entities.Add ("times", '\u00D7');
- _entities.Add ("Oslash", '\u00D8');
- _entities.Add ("Ugrave", '\u00D9');
- _entities.Add ("Uacute", '\u00DA');
- _entities.Add ("Ucirc", '\u00DB');
- _entities.Add ("Uuml", '\u00DC');
- _entities.Add ("Yacute", '\u00DD');
- _entities.Add ("THORN", '\u00DE');
- _entities.Add ("szlig", '\u00DF');
- _entities.Add ("agrave", '\u00E0');
- _entities.Add ("aacute", '\u00E1');
- _entities.Add ("acirc", '\u00E2');
- _entities.Add ("atilde", '\u00E3');
- _entities.Add ("auml", '\u00E4');
- _entities.Add ("aring", '\u00E5');
- _entities.Add ("aelig", '\u00E6');
- _entities.Add ("ccedil", '\u00E7');
- _entities.Add ("egrave", '\u00E8');
- _entities.Add ("eacute", '\u00E9');
- _entities.Add ("ecirc", '\u00EA');
- _entities.Add ("euml", '\u00EB');
- _entities.Add ("igrave", '\u00EC');
- _entities.Add ("iacute", '\u00ED');
- _entities.Add ("icirc", '\u00EE');
- _entities.Add ("iuml", '\u00EF');
- _entities.Add ("eth", '\u00F0');
- _entities.Add ("ntilde", '\u00F1');
- _entities.Add ("ograve", '\u00F2');
- _entities.Add ("oacute", '\u00F3');
- _entities.Add ("ocirc", '\u00F4');
- _entities.Add ("otilde", '\u00F5');
- _entities.Add ("ouml", '\u00F6');
- _entities.Add ("divide", '\u00F7');
- _entities.Add ("oslash", '\u00F8');
- _entities.Add ("ugrave", '\u00F9');
- _entities.Add ("uacute", '\u00FA');
- _entities.Add ("ucirc", '\u00FB');
- _entities.Add ("uuml", '\u00FC');
- _entities.Add ("yacute", '\u00FD');
- _entities.Add ("thorn", '\u00FE');
- _entities.Add ("yuml", '\u00FF');
- _entities.Add ("fnof", '\u0192');
- _entities.Add ("Alpha", '\u0391');
- _entities.Add ("Beta", '\u0392');
- _entities.Add ("Gamma", '\u0393');
- _entities.Add ("Delta", '\u0394');
- _entities.Add ("Epsilon", '\u0395');
- _entities.Add ("Zeta", '\u0396');
- _entities.Add ("Eta", '\u0397');
- _entities.Add ("Theta", '\u0398');
- _entities.Add ("Iota", '\u0399');
- _entities.Add ("Kappa", '\u039A');
- _entities.Add ("Lambda", '\u039B');
- _entities.Add ("Mu", '\u039C');
- _entities.Add ("Nu", '\u039D');
- _entities.Add ("Xi", '\u039E');
- _entities.Add ("Omicron", '\u039F');
- _entities.Add ("Pi", '\u03A0');
- _entities.Add ("Rho", '\u03A1');
- _entities.Add ("Sigma", '\u03A3');
- _entities.Add ("Tau", '\u03A4');
- _entities.Add ("Upsilon", '\u03A5');
- _entities.Add ("Phi", '\u03A6');
- _entities.Add ("Chi", '\u03A7');
- _entities.Add ("Psi", '\u03A8');
- _entities.Add ("Omega", '\u03A9');
- _entities.Add ("alpha", '\u03B1');
- _entities.Add ("beta", '\u03B2');
- _entities.Add ("gamma", '\u03B3');
- _entities.Add ("delta", '\u03B4');
- _entities.Add ("epsilon", '\u03B5');
- _entities.Add ("zeta", '\u03B6');
- _entities.Add ("eta", '\u03B7');
- _entities.Add ("theta", '\u03B8');
- _entities.Add ("iota", '\u03B9');
- _entities.Add ("kappa", '\u03BA');
- _entities.Add ("lambda", '\u03BB');
- _entities.Add ("mu", '\u03BC');
- _entities.Add ("nu", '\u03BD');
- _entities.Add ("xi", '\u03BE');
- _entities.Add ("omicron", '\u03BF');
- _entities.Add ("pi", '\u03C0');
- _entities.Add ("rho", '\u03C1');
- _entities.Add ("sigmaf", '\u03C2');
- _entities.Add ("sigma", '\u03C3');
- _entities.Add ("tau", '\u03C4');
- _entities.Add ("upsilon", '\u03C5');
- _entities.Add ("phi", '\u03C6');
- _entities.Add ("chi", '\u03C7');
- _entities.Add ("psi", '\u03C8');
- _entities.Add ("omega", '\u03C9');
- _entities.Add ("thetasym", '\u03D1');
- _entities.Add ("upsih", '\u03D2');
- _entities.Add ("piv", '\u03D6');
- _entities.Add ("bull", '\u2022');
- _entities.Add ("hellip", '\u2026');
- _entities.Add ("prime", '\u2032');
- _entities.Add ("Prime", '\u2033');
- _entities.Add ("oline", '\u203E');
- _entities.Add ("frasl", '\u2044');
- _entities.Add ("weierp", '\u2118');
- _entities.Add ("image", '\u2111');
- _entities.Add ("real", '\u211C');
- _entities.Add ("trade", '\u2122');
- _entities.Add ("alefsym", '\u2135');
- _entities.Add ("larr", '\u2190');
- _entities.Add ("uarr", '\u2191');
- _entities.Add ("rarr", '\u2192');
- _entities.Add ("darr", '\u2193');
- _entities.Add ("harr", '\u2194');
- _entities.Add ("crarr", '\u21B5');
- _entities.Add ("lArr", '\u21D0');
- _entities.Add ("uArr", '\u21D1');
- _entities.Add ("rArr", '\u21D2');
- _entities.Add ("dArr", '\u21D3');
- _entities.Add ("hArr", '\u21D4');
- _entities.Add ("forall", '\u2200');
- _entities.Add ("part", '\u2202');
- _entities.Add ("exist", '\u2203');
- _entities.Add ("empty", '\u2205');
- _entities.Add ("nabla", '\u2207');
- _entities.Add ("isin", '\u2208');
- _entities.Add ("notin", '\u2209');
- _entities.Add ("ni", '\u220B');
- _entities.Add ("prod", '\u220F');
- _entities.Add ("sum", '\u2211');
- _entities.Add ("minus", '\u2212');
- _entities.Add ("lowast", '\u2217');
- _entities.Add ("radic", '\u221A');
- _entities.Add ("prop", '\u221D');
- _entities.Add ("infin", '\u221E');
- _entities.Add ("ang", '\u2220');
- _entities.Add ("and", '\u2227');
- _entities.Add ("or", '\u2228');
- _entities.Add ("cap", '\u2229');
- _entities.Add ("cup", '\u222A');
- _entities.Add ("int", '\u222B');
- _entities.Add ("there4", '\u2234');
- _entities.Add ("sim", '\u223C');
- _entities.Add ("cong", '\u2245');
- _entities.Add ("asymp", '\u2248');
- _entities.Add ("ne", '\u2260');
- _entities.Add ("equiv", '\u2261');
- _entities.Add ("le", '\u2264');
- _entities.Add ("ge", '\u2265');
- _entities.Add ("sub", '\u2282');
- _entities.Add ("sup", '\u2283');
- _entities.Add ("nsub", '\u2284');
- _entities.Add ("sube", '\u2286');
- _entities.Add ("supe", '\u2287');
- _entities.Add ("oplus", '\u2295');
- _entities.Add ("otimes", '\u2297');
- _entities.Add ("perp", '\u22A5');
- _entities.Add ("sdot", '\u22C5');
- _entities.Add ("lceil", '\u2308');
- _entities.Add ("rceil", '\u2309');
- _entities.Add ("lfloor", '\u230A');
- _entities.Add ("rfloor", '\u230B');
- _entities.Add ("lang", '\u2329');
- _entities.Add ("rang", '\u232A');
- _entities.Add ("loz", '\u25CA');
- _entities.Add ("spades", '\u2660');
- _entities.Add ("clubs", '\u2663');
- _entities.Add ("hearts", '\u2665');
- _entities.Add ("diams", '\u2666');
- _entities.Add ("quot", '\u0022');
- _entities.Add ("amp", '\u0026');
- _entities.Add ("lt", '\u003C');
- _entities.Add ("gt", '\u003E');
- _entities.Add ("OElig", '\u0152');
- _entities.Add ("oelig", '\u0153');
- _entities.Add ("Scaron", '\u0160');
- _entities.Add ("scaron", '\u0161');
- _entities.Add ("Yuml", '\u0178');
- _entities.Add ("circ", '\u02C6');
- _entities.Add ("tilde", '\u02DC');
- _entities.Add ("ensp", '\u2002');
- _entities.Add ("emsp", '\u2003');
- _entities.Add ("thinsp", '\u2009');
- _entities.Add ("zwnj", '\u200C');
- _entities.Add ("zwj", '\u200D');
- _entities.Add ("lrm", '\u200E');
- _entities.Add ("rlm", '\u200F');
- _entities.Add ("ndash", '\u2013');
- _entities.Add ("mdash", '\u2014');
- _entities.Add ("lsquo", '\u2018');
- _entities.Add ("rsquo", '\u2019');
- _entities.Add ("sbquo", '\u201A');
- _entities.Add ("ldquo", '\u201C');
- _entities.Add ("rdquo", '\u201D');
- _entities.Add ("bdquo", '\u201E');
- _entities.Add ("dagger", '\u2020');
- _entities.Add ("Dagger", '\u2021');
- _entities.Add ("permil", '\u2030');
- _entities.Add ("lsaquo", '\u2039');
- _entities.Add ("rsaquo", '\u203A');
- _entities.Add ("euro", '\u20AC');
- }
-
- private static bool isAlphabet (char c)
- {
- return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
- }
-
- private static bool isNumeric (char c)
- {
- return c >= '0' && c <= '9';
- }
-
- private static bool isUnreserved (char c)
- {
- return c == '*'
- || c == '-'
- || c == '.'
- || c == '_';
- }
-
- private static bool isUnreservedInRfc2396 (char c)
- {
- return c == '!'
- || c == '\''
- || c == '('
- || c == ')'
- || c == '*'
- || c == '-'
- || c == '.'
- || c == '_'
- || c == '~';
- }
-
- private static bool isUnreservedInRfc3986 (char c)
- {
- return c == '-'
- || c == '.'
- || c == '_'
- || c == '~';
- }
-
- private static byte[] urlDecodeToBytes (byte[] bytes, int offset, int count)
- {
- using (var buff = new MemoryStream ()) {
- var end = offset + count - 1;
-
- for (var i = offset; i <= end; i++) {
- var b = bytes[i];
- var c = (char) b;
-
- if (c == '%') {
- if (i > end - 2)
- break;
-
- var num = getNumber (bytes, i + 1, 2);
-
- if (num == -1)
- break;
-
- buff.WriteByte ((byte) num);
-
- i += 2;
-
- continue;
- }
-
- if (c == '+') {
- buff.WriteByte ((byte) ' ');
-
- continue;
- }
-
- buff.WriteByte (b);
- }
-
- buff.Close ();
-
- return buff.ToArray ();
- }
- }
-
- private static void urlEncode (byte b, Stream output)
- {
- if (b > 31 && b < 127) {
- var c = (char) b;
-
- if (c == ' ') {
- output.WriteByte ((byte) '+');
-
- return;
- }
-
- if (isNumeric (c)) {
- output.WriteByte (b);
-
- return;
- }
-
- if (isAlphabet (c)) {
- output.WriteByte (b);
-
- return;
- }
-
- if (isUnreserved (c)) {
- output.WriteByte (b);
-
- return;
- }
- }
-
- var i = (int) b;
- var bytes = new byte[] {
- (byte) '%',
- (byte) _hexChars[i >> 4],
- (byte) _hexChars[i & 0x0F]
- };
-
- output.Write (bytes, 0, 3);
- }
-
- private static byte[] urlEncodeToBytes (byte[] bytes, int offset, int count)
- {
- using (var buff = new MemoryStream ()) {
- var end = offset + count - 1;
-
- for (var i = offset; i <= end; i++)
- urlEncode (bytes[i], buff);
-
- buff.Close ();
-
- return buff.ToArray ();
- }
- }
-
- #endregion
-
- #region Internal Methods
-
- internal static Uri CreateRequestUrl (
- string requestUri,
- string host,
- bool websocketRequest,
- bool secure
- )
- {
- if (requestUri == null || requestUri.Length == 0)
- return null;
-
- if (host == null || host.Length == 0)
- return null;
-
- string schm = null;
- string path = null;
-
- if (requestUri.IndexOf ('/') == 0) {
- path = requestUri;
- }
- else if (requestUri.MaybeUri ()) {
- Uri uri;
-
- if (!Uri.TryCreate (requestUri, UriKind.Absolute, out uri))
- return null;
-
- schm = uri.Scheme;
- var valid = websocketRequest
- ? schm == "ws" || schm == "wss"
- : schm == "http" || schm == "https";
-
- if (!valid)
- return null;
-
- host = uri.Authority;
- path = uri.PathAndQuery;
- }
- else if (requestUri == "*") {
- }
- else {
- // As the authority form.
-
- host = requestUri;
- }
-
- if (schm == null) {
- schm = websocketRequest
- ? (secure ? "wss" : "ws")
- : (secure ? "https" : "http");
- }
-
- if (host.IndexOf (':') == -1)
- host = String.Format ("{0}:{1}", host, secure ? 443 : 80);
-
- var url = String.Format ("{0}://{1}{2}", schm, host, path);
- Uri ret;
-
- return Uri.TryCreate (url, UriKind.Absolute, out ret) ? ret : null;
- }
-
- internal static IPrincipal CreateUser (
- string response,
- AuthenticationSchemes scheme,
- string realm,
- string method,
- Func credentialsFinder
- )
- {
- if (response == null || response.Length == 0)
- return null;
-
- if (scheme == AuthenticationSchemes.Digest) {
- if (realm == null || realm.Length == 0)
- return null;
-
- if (method == null || method.Length == 0)
- return null;
- }
- else {
- if (scheme != AuthenticationSchemes.Basic)
- return null;
- }
-
- if (credentialsFinder == null)
- return null;
-
- var compType = StringComparison.OrdinalIgnoreCase;
-
- if (!response.StartsWith (scheme.ToString (), compType))
- return null;
-
- var res = AuthenticationResponse.Parse (response);
-
- if (res == null)
- return null;
-
- var id = res.ToIdentity ();
-
- if (id == null)
- return null;
-
- NetworkCredential cred = null;
-
- try {
- cred = credentialsFinder (id);
- }
- catch {
- }
-
- if (cred == null)
- return null;
-
- if (scheme == AuthenticationSchemes.Basic) {
- var basicId = (HttpBasicIdentity) id;
-
- return basicId.Password == cred.Password
- ? new GenericPrincipal (id, cred.Roles)
- : null;
- }
-
- var digestId = (HttpDigestIdentity) id;
-
- return digestId.IsValid (cred.Password, realm, method, null)
- ? new GenericPrincipal (id, cred.Roles)
- : null;
- }
-
- internal static Encoding GetEncoding (string contentType)
- {
- var name = "charset=";
- var compType = StringComparison.OrdinalIgnoreCase;
-
- foreach (var elm in contentType.SplitHeaderValue (';')) {
- var part = elm.Trim ();
-
- if (!part.StartsWith (name, compType))
- continue;
-
- var val = part.GetValue ('=', true);
-
- if (val == null || val.Length == 0)
- return null;
-
- return Encoding.GetEncoding (val);
- }
-
- return null;
- }
-
- internal static bool TryGetEncoding (
- string contentType,
- out Encoding result
- )
- {
- result = null;
-
- try {
- result = GetEncoding (contentType);
- }
- catch {
- return false;
- }
-
- return result != null;
- }
-
- #endregion
-
- #region Public Methods
-
- public static string HtmlAttributeEncode (string s)
- {
- if (s == null)
- throw new ArgumentNullException ("s");
-
- return s.Length > 0 ? htmlEncode (s, true) : s;
- }
-
- public static void HtmlAttributeEncode (string s, TextWriter output)
- {
- if (s == null)
- throw new ArgumentNullException ("s");
-
- if (output == null)
- throw new ArgumentNullException ("output");
-
- if (s.Length == 0)
- return;
-
- var encodedS = htmlEncode (s, true);
-
- output.Write (encodedS);
- }
-
- public static string HtmlDecode (string s)
- {
- if (s == null)
- throw new ArgumentNullException ("s");
-
- return s.Length > 0 ? htmlDecode (s) : s;
- }
-
- public static void HtmlDecode (string s, TextWriter output)
- {
- if (s == null)
- throw new ArgumentNullException ("s");
-
- if (output == null)
- throw new ArgumentNullException ("output");
-
- if (s.Length == 0)
- return;
-
- var decodedS = htmlDecode (s);
-
- output.Write (decodedS);
- }
-
- public static string HtmlEncode (string s)
- {
- if (s == null)
- throw new ArgumentNullException ("s");
-
- return s.Length > 0 ? htmlEncode (s, false) : s;
- }
-
- public static void HtmlEncode (string s, TextWriter output)
- {
- if (s == null)
- throw new ArgumentNullException ("s");
-
- if (output == null)
- throw new ArgumentNullException ("output");
-
- if (s.Length == 0)
- return;
-
- var encodedS = htmlEncode (s, false);
-
- output.Write (encodedS);
- }
-
- public static string UrlDecode (string s)
- {
- return UrlDecode (s, Encoding.UTF8);
- }
-
- public static string UrlDecode (byte[] bytes, Encoding encoding)
- {
- if (bytes == null)
- throw new ArgumentNullException ("bytes");
-
- var len = bytes.Length;
-
- if (len == 0)
- return String.Empty;
-
- var decodedBytes = urlDecodeToBytes (bytes, 0, len);
-
- return (encoding ?? Encoding.UTF8).GetString (decodedBytes);
- }
-
- public static string UrlDecode (string s, Encoding encoding)
- {
- if (s == null)
- throw new ArgumentNullException ("s");
-
- if (s.Length == 0)
- return s;
-
- var bytes = Encoding.ASCII.GetBytes (s);
- var decodedBytes = urlDecodeToBytes (bytes, 0, bytes.Length);
-
- return (encoding ?? Encoding.UTF8).GetString (decodedBytes);
- }
-
- public static string UrlDecode (
- byte[] bytes,
- int offset,
- int count,
- Encoding encoding
- )
- {
- if (bytes == null)
- throw new ArgumentNullException ("bytes");
-
- var len = bytes.Length;
-
- if (len == 0) {
- if (offset != 0)
- throw new ArgumentOutOfRangeException ("offset");
-
- if (count != 0)
- throw new ArgumentOutOfRangeException ("count");
-
- return String.Empty;
- }
-
- if (offset < 0 || offset >= len)
- throw new ArgumentOutOfRangeException ("offset");
-
- if (count < 0 || count > len - offset)
- throw new ArgumentOutOfRangeException ("count");
-
- if (count == 0)
- return String.Empty;
-
- var decodedBytes = urlDecodeToBytes (bytes, offset, count);
-
- return (encoding ?? Encoding.UTF8).GetString (decodedBytes);
- }
-
- public static byte[] UrlDecodeToBytes (byte[] bytes)
- {
- if (bytes == null)
- throw new ArgumentNullException ("bytes");
-
- var len = bytes.Length;
-
- return len > 0 ? urlDecodeToBytes (bytes, 0, len) : bytes;
- }
-
- public static byte[] UrlDecodeToBytes (string s)
- {
- if (s == null)
- throw new ArgumentNullException ("s");
-
- if (s.Length == 0)
- return new byte[0];
-
- var bytes = Encoding.ASCII.GetBytes (s);
-
- return urlDecodeToBytes (bytes, 0, bytes.Length);
- }
-
- public static byte[] UrlDecodeToBytes (byte[] bytes, int offset, int count)
- {
- if (bytes == null)
- throw new ArgumentNullException ("bytes");
-
- var len = bytes.Length;
-
- if (len == 0) {
- if (offset != 0)
- throw new ArgumentOutOfRangeException ("offset");
-
- if (count != 0)
- throw new ArgumentOutOfRangeException ("count");
-
- return bytes;
- }
-
- if (offset < 0 || offset >= len)
- throw new ArgumentOutOfRangeException ("offset");
-
- if (count < 0 || count > len - offset)
- throw new ArgumentOutOfRangeException ("count");
-
- return count > 0 ? urlDecodeToBytes (bytes, offset, count) : new byte[0];
- }
-
- public static string UrlEncode (byte[] bytes)
- {
- if (bytes == null)
- throw new ArgumentNullException ("bytes");
-
- var len = bytes.Length;
-
- if (len == 0)
- return String.Empty;
-
- var encodedBytes = urlEncodeToBytes (bytes, 0, len);
-
- return Encoding.ASCII.GetString (encodedBytes);
- }
-
- public static string UrlEncode (string s)
- {
- return UrlEncode (s, Encoding.UTF8);
- }
-
- public static string UrlEncode (string s, Encoding encoding)
- {
- if (s == null)
- throw new ArgumentNullException ("s");
-
- var len = s.Length;
-
- if (len == 0)
- return s;
-
- if (encoding == null)
- encoding = Encoding.UTF8;
-
- var maxCnt = encoding.GetMaxByteCount (len);
- var bytes = new byte[maxCnt];
- var cnt = encoding.GetBytes (s, 0, len, bytes, 0);
- var encodedBytes = urlEncodeToBytes (bytes, 0, cnt);
-
- return Encoding.ASCII.GetString (encodedBytes);
- }
-
- public static string UrlEncode (byte[] bytes, int offset, int count)
- {
- if (bytes == null)
- throw new ArgumentNullException ("bytes");
-
- var len = bytes.Length;
-
- if (len == 0) {
- if (offset != 0)
- throw new ArgumentOutOfRangeException ("offset");
-
- if (count != 0)
- throw new ArgumentOutOfRangeException ("count");
-
- return String.Empty;
- }
-
- if (offset < 0 || offset >= len)
- throw new ArgumentOutOfRangeException ("offset");
-
- if (count < 0 || count > len - offset)
- throw new ArgumentOutOfRangeException ("count");
-
- if (count == 0)
- return String.Empty;
-
- var encodedBytes = urlEncodeToBytes (bytes, offset, count);
-
- return Encoding.ASCII.GetString (encodedBytes);
- }
-
- public static byte[] UrlEncodeToBytes (byte[] bytes)
- {
- if (bytes == null)
- throw new ArgumentNullException ("bytes");
-
- var len = bytes.Length;
-
- return len > 0 ? urlEncodeToBytes (bytes, 0, len) : bytes;
- }
-
- public static byte[] UrlEncodeToBytes (string s)
- {
- return UrlEncodeToBytes (s, Encoding.UTF8);
- }
-
- public static byte[] UrlEncodeToBytes (string s, Encoding encoding)
- {
- if (s == null)
- throw new ArgumentNullException ("s");
-
- if (s.Length == 0)
- return new byte[0];
-
- var bytes = (encoding ?? Encoding.UTF8).GetBytes (s);
-
- return urlEncodeToBytes (bytes, 0, bytes.Length);
- }
-
- public static byte[] UrlEncodeToBytes (byte[] bytes, int offset, int count)
- {
- if (bytes == null)
- throw new ArgumentNullException ("bytes");
-
- var len = bytes.Length;
-
- if (len == 0) {
- if (offset != 0)
- throw new ArgumentOutOfRangeException ("offset");
-
- if (count != 0)
- throw new ArgumentOutOfRangeException ("count");
-
- return bytes;
- }
-
- if (offset < 0 || offset >= len)
- throw new ArgumentOutOfRangeException ("offset");
-
- if (count < 0 || count > len - offset)
- throw new ArgumentOutOfRangeException ("count");
-
- return count > 0 ? urlEncodeToBytes (bytes, offset, count) : new byte[0];
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Net/HttpVersion.cs b/websocket-sharp/Net/HttpVersion.cs
deleted file mode 100644
index 95f8f0a38..000000000
--- a/websocket-sharp/Net/HttpVersion.cs
+++ /dev/null
@@ -1,73 +0,0 @@
-#region License
-/*
- * HttpVersion.cs
- *
- * This code is derived from HttpVersion.cs (System.Net) of Mono
- * (http://www.mono-project.com).
- *
- * The MIT License
- *
- * Copyright (c) 2012-2024 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-#region Authors
-/*
- * Authors:
- * - Lawrence Pit
- */
-#endregion
-
-using System;
-
-namespace WebSocketSharp.Net
-{
- ///
- /// Provides the HTTP version numbers.
- ///
- public class HttpVersion
- {
- #region Public Fields
-
- ///
- /// Provides a instance for the HTTP/1.0.
- ///
- public static readonly Version Version10 = new Version (1, 0);
-
- ///
- /// Provides a instance for the HTTP/1.1.
- ///
- public static readonly Version Version11 = new Version (1, 1);
-
- #endregion
-
- #region Public Constructors
-
- ///
- /// Initializes a new instance of the class.
- ///
- public HttpVersion ()
- {
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Net/InputChunkState.cs b/websocket-sharp/Net/InputChunkState.cs
deleted file mode 100644
index f50ad6b7a..000000000
--- a/websocket-sharp/Net/InputChunkState.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-#region License
-/*
- * InputChunkState.cs
- *
- * This code is derived from ChunkStream.cs (System.Net) of Mono
- * (http://www.mono-project.com).
- *
- * The MIT License
- *
- * Copyright (c) 2003 Ximian, Inc (http://www.ximian.com)
- * Copyright (c) 2014-2015 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-#region Authors
-/*
- * Authors:
- * - Gonzalo Paniagua Javier
- */
-#endregion
-
-using System;
-
-namespace WebSocketSharp.Net
-{
- internal enum InputChunkState
- {
- None,
- Data,
- DataEnded,
- Trailer,
- End
- }
-}
diff --git a/websocket-sharp/Net/InputState.cs b/websocket-sharp/Net/InputState.cs
deleted file mode 100644
index 9f566d246..000000000
--- a/websocket-sharp/Net/InputState.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-#region License
-/*
- * InputState.cs
- *
- * This code is derived from HttpConnection.cs (System.Net) of Mono
- * (http://www.mono-project.com).
- *
- * The MIT License
- *
- * Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
- * Copyright (c) 2014-2015 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-#region Authors
-/*
- * Authors:
- * - Gonzalo Paniagua Javier
- */
-#endregion
-
-using System;
-
-namespace WebSocketSharp.Net
-{
- internal enum InputState
- {
- RequestLine,
- Headers
- }
-}
diff --git a/websocket-sharp/Net/LineState.cs b/websocket-sharp/Net/LineState.cs
deleted file mode 100644
index 84e271a7b..000000000
--- a/websocket-sharp/Net/LineState.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-#region License
-/*
- * LineState.cs
- *
- * This code is derived from HttpConnection.cs (System.Net) of Mono
- * (http://www.mono-project.com).
- *
- * The MIT License
- *
- * Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
- * Copyright (c) 2014-2015 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-#region Authors
-/*
- * Authors:
- * - Gonzalo Paniagua Javier
- */
-#endregion
-
-using System;
-
-namespace WebSocketSharp.Net
-{
- internal enum LineState
- {
- None,
- Cr,
- Lf
- }
-}
diff --git a/websocket-sharp/Net/NetworkCredential.cs b/websocket-sharp/Net/NetworkCredential.cs
deleted file mode 100644
index f97df971f..000000000
--- a/websocket-sharp/Net/NetworkCredential.cs
+++ /dev/null
@@ -1,217 +0,0 @@
-#region License
-/*
- * NetworkCredential.cs
- *
- * The MIT License
- *
- * Copyright (c) 2014-2024 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-using System;
-
-namespace WebSocketSharp.Net
-{
- ///
- /// Provides the credentials for the password-based authentication.
- ///
- public class NetworkCredential
- {
- #region Private Fields
-
- private string _domain;
- private static readonly string[] _noRoles;
- private string _password;
- private string[] _roles;
- private string _username;
-
- #endregion
-
- #region Static Constructor
-
- static NetworkCredential ()
- {
- _noRoles = new string[0];
- }
-
- #endregion
-
- #region Public Constructors
-
- ///
- /// Initializes a new instance of the class
- /// with the specified username and password.
- ///
- ///
- /// A that specifies the username associated with
- /// the credentials.
- ///
- ///
- /// A that specifies the password for the username
- /// associated with the credentials.
- ///
- ///
- /// is an empty string.
- ///
- ///
- /// is .
- ///
- public NetworkCredential (string username, string password)
- : this (username, password, null, null)
- {
- }
-
- ///
- /// Initializes a new instance of the class
- /// with the specified username, password, domain and roles.
- ///
- ///
- /// A that specifies the username associated with
- /// the credentials.
- ///
- ///
- /// A that specifies the password for the username
- /// associated with the credentials.
- ///
- ///
- /// A that specifies the domain associated with
- /// the credentials.
- ///
- ///
- /// An array of that specifies the roles associated
- /// with the credentials if any.
- ///
- ///
- /// is an empty string.
- ///
- ///
- /// is .
- ///
- public NetworkCredential (
- string username,
- string password,
- string domain,
- params string[] roles
- )
- {
- if (username == null)
- throw new ArgumentNullException ("username");
-
- if (username.Length == 0)
- throw new ArgumentException ("An empty string.", "username");
-
- _username = username;
- _password = password;
- _domain = domain;
- _roles = roles;
- }
-
- #endregion
-
- #region Public Properties
-
- ///
- /// Gets the domain associated with the credentials.
- ///
- ///
- ///
- /// A that represents the domain name
- /// to which the username belongs.
- ///
- ///
- /// An empty string if the value was initialized with
- /// .
- ///
- ///
- public string Domain {
- get {
- return _domain ?? String.Empty;
- }
-
- internal set {
- _domain = value;
- }
- }
-
- ///
- /// Gets the password for the username associated with the credentials.
- ///
- ///
- ///
- /// A that represents the password.
- ///
- ///
- /// An empty string if the value was initialized with
- /// .
- ///
- ///
- public string Password {
- get {
- return _password ?? String.Empty;
- }
-
- internal set {
- _password = value;
- }
- }
-
- ///
- /// Gets the roles associated with the credentials.
- ///
- ///
- ///
- /// An array of that represents the role names
- /// to which the username belongs.
- ///
- ///
- /// An empty array if the value was initialized with
- /// .
- ///
- ///
- public string[] Roles {
- get {
- return _roles ?? _noRoles;
- }
-
- internal set {
- _roles = value;
- }
- }
-
- ///
- /// Gets the username associated with the credentials.
- ///
- ///
- /// A that represents the username.
- ///
- public string Username {
- get {
- return _username;
- }
-
- internal set {
- _username = value;
- }
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Net/QueryStringCollection.cs b/websocket-sharp/Net/QueryStringCollection.cs
deleted file mode 100644
index d5b7a8d9a..000000000
--- a/websocket-sharp/Net/QueryStringCollection.cs
+++ /dev/null
@@ -1,144 +0,0 @@
-#region License
-/*
- * QueryStringCollection.cs
- *
- * This code is derived from HttpUtility.cs (System.Net) of Mono
- * (http://www.mono-project.com).
- *
- * The MIT License
- *
- * Copyright (c) 2005-2009 Novell, Inc. (http://www.novell.com)
- * Copyright (c) 2018-2023 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-#region Authors
-/*
- * Authors:
- * - Patrik Torstensson
- * - Wictor Wilén (decode/encode functions)
- * - Tim Coleman
- * - Gonzalo Paniagua Javier
- */
-#endregion
-
-using System;
-using System.Collections.Specialized;
-using System.Text;
-
-namespace WebSocketSharp.Net
-{
- internal sealed class QueryStringCollection : NameValueCollection
- {
- #region Public Constructors
-
- public QueryStringCollection ()
- {
- }
-
- public QueryStringCollection (int capacity)
- : base (capacity)
- {
- }
-
- #endregion
-
- #region Public Methods
-
- public static QueryStringCollection Parse (string query)
- {
- return Parse (query, Encoding.UTF8);
- }
-
- public static QueryStringCollection Parse (string query, Encoding encoding)
- {
- if (query == null)
- return new QueryStringCollection (1);
-
- if (query.Length == 0)
- return new QueryStringCollection (1);
-
- if (query == "?")
- return new QueryStringCollection (1);
-
- if (query[0] == '?')
- query = query.Substring (1);
-
- if (encoding == null)
- encoding = Encoding.UTF8;
-
- var ret = new QueryStringCollection ();
-
- foreach (var component in query.Split ('&')) {
- var len = component.Length;
-
- if (len == 0)
- continue;
-
- if (component == "=")
- continue;
-
- string name = null;
- string val = null;
-
- var idx = component.IndexOf ('=');
-
- if (idx < 0) {
- val = component.UrlDecode (encoding);
- }
- else if (idx == 0) {
- val = component.Substring (1).UrlDecode (encoding);
- }
- else {
- name = component.Substring (0, idx).UrlDecode (encoding);
-
- var start = idx + 1;
- val = start < len
- ? component.Substring (start).UrlDecode (encoding)
- : String.Empty;
- }
-
- ret.Add (name, val);
- }
-
- return ret;
- }
-
- public override string ToString ()
- {
- if (Count == 0)
- return String.Empty;
-
- var buff = new StringBuilder ();
-
- var fmt = "{0}={1}&";
-
- foreach (var key in AllKeys)
- buff.AppendFormat (fmt, key, this[key]);
-
- buff.Length--;
-
- return buff.ToString ();
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Net/ReadBufferState.cs b/websocket-sharp/Net/ReadBufferState.cs
deleted file mode 100644
index bf0de8848..000000000
--- a/websocket-sharp/Net/ReadBufferState.cs
+++ /dev/null
@@ -1,129 +0,0 @@
-#region License
-/*
- * ReadBufferState.cs
- *
- * This code is derived from ChunkedInputStream.cs (System.Net) of Mono
- * (http://www.mono-project.com).
- *
- * The MIT License
- *
- * Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
- * Copyright (c) 2014-2023 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-#region Authors
-/*
- * Authors:
- * - Gonzalo Paniagua Javier
- */
-#endregion
-
-using System;
-
-namespace WebSocketSharp.Net
-{
- internal class ReadBufferState
- {
- #region Private Fields
-
- private HttpStreamAsyncResult _asyncResult;
- private byte[] _buffer;
- private int _count;
- private int _initialCount;
- private int _offset;
-
- #endregion
-
- #region Public Constructors
-
- public ReadBufferState (
- byte[] buffer,
- int offset,
- int count,
- HttpStreamAsyncResult asyncResult
- )
- {
- _buffer = buffer;
- _offset = offset;
- _count = count;
- _asyncResult = asyncResult;
-
- _initialCount = count;
- }
-
- #endregion
-
- #region Public Properties
-
- public HttpStreamAsyncResult AsyncResult {
- get {
- return _asyncResult;
- }
-
- set {
- _asyncResult = value;
- }
- }
-
- public byte[] Buffer {
- get {
- return _buffer;
- }
-
- set {
- _buffer = value;
- }
- }
-
- public int Count {
- get {
- return _count;
- }
-
- set {
- _count = value;
- }
- }
-
- public int InitialCount {
- get {
- return _initialCount;
- }
-
- set {
- _initialCount = value;
- }
- }
-
- public int Offset {
- get {
- return _offset;
- }
-
- set {
- _offset = value;
- }
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Net/RequestStream.cs b/websocket-sharp/Net/RequestStream.cs
deleted file mode 100644
index dd40f920a..000000000
--- a/websocket-sharp/Net/RequestStream.cs
+++ /dev/null
@@ -1,354 +0,0 @@
-#region License
-/*
- * RequestStream.cs
- *
- * This code is derived from RequestStream.cs (System.Net) of Mono
- * (http://www.mono-project.com).
- *
- * The MIT License
- *
- * Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
- * Copyright (c) 2012-2023 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-#region Authors
-/*
- * Authors:
- * - Gonzalo Paniagua Javier
- */
-#endregion
-
-using System;
-using System.IO;
-
-namespace WebSocketSharp.Net
-{
- internal class RequestStream : Stream
- {
- #region Private Fields
-
- private long _bodyLeft;
- private int _count;
- private bool _disposed;
- private byte[] _initialBuffer;
- private Stream _innerStream;
- private int _offset;
-
- #endregion
-
- #region Internal Constructors
-
- internal RequestStream (
- Stream innerStream,
- byte[] initialBuffer,
- int offset,
- int count,
- long contentLength
- )
- {
- _innerStream = innerStream;
- _initialBuffer = initialBuffer;
- _offset = offset;
- _count = count;
- _bodyLeft = contentLength;
- }
-
- #endregion
-
- #region Internal Properties
-
- internal int Count {
- get {
- return _count;
- }
- }
-
- internal byte[] InitialBuffer {
- get {
- return _initialBuffer;
- }
- }
-
- internal string ObjectName {
- get {
- return GetType ().ToString ();
- }
- }
-
- internal int Offset {
- get {
- return _offset;
- }
- }
-
- #endregion
-
- #region Public Properties
-
- public override bool CanRead {
- get {
- return true;
- }
- }
-
- public override bool CanSeek {
- get {
- return false;
- }
- }
-
- public override bool CanWrite {
- get {
- return false;
- }
- }
-
- public override long Length {
- get {
- throw new NotSupportedException ();
- }
- }
-
- public override long Position {
- get {
- throw new NotSupportedException ();
- }
-
- set {
- throw new NotSupportedException ();
- }
- }
-
- #endregion
-
- #region Private Methods
-
- private int fillFromInitialBuffer (byte[] buffer, int offset, int count)
- {
- // This method returns a int:
- // - > 0 The number of bytes read from the initial buffer
- // - 0 No more bytes read from the initial buffer
- // - -1 No more content data
-
- if (_bodyLeft == 0)
- return -1;
-
- if (_count == 0)
- return 0;
-
- if (count > _count)
- count = _count;
-
- if (_bodyLeft > 0 && _bodyLeft < count)
- count = (int) _bodyLeft;
-
- Buffer.BlockCopy (_initialBuffer, _offset, buffer, offset, count);
-
- _offset += count;
- _count -= count;
-
- if (_bodyLeft > 0)
- _bodyLeft -= count;
-
- return count;
- }
-
- #endregion
-
- #region Public Methods
-
- public override IAsyncResult BeginRead (
- byte[] buffer,
- int offset,
- int count,
- AsyncCallback callback,
- object state
- )
- {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- if (buffer == null)
- throw new ArgumentNullException ("buffer");
-
- if (offset < 0) {
- var msg = "A negative value.";
-
- throw new ArgumentOutOfRangeException ("offset", msg);
- }
-
- if (count < 0) {
- var msg = "A negative value.";
-
- throw new ArgumentOutOfRangeException ("count", msg);
- }
-
- var len = buffer.Length;
-
- if (offset + count > len) {
- var msg = "The sum of offset and count is greater than the length of buffer.";
-
- throw new ArgumentException (msg);
- }
-
- if (count == 0)
- return _innerStream.BeginRead (buffer, offset, 0, callback, state);
-
- var nread = fillFromInitialBuffer (buffer, offset, count);
-
- if (nread != 0) {
- var ares = new HttpStreamAsyncResult (callback, state);
-
- ares.Buffer = buffer;
- ares.Offset = offset;
- ares.Count = count;
- ares.SyncRead = nread > 0 ? nread : 0;
-
- ares.Complete ();
-
- return ares;
- }
-
- if (_bodyLeft > 0 && _bodyLeft < count)
- count = (int) _bodyLeft;
-
- return _innerStream.BeginRead (buffer, offset, count, callback, state);
- }
-
- public override IAsyncResult BeginWrite (
- byte[] buffer,
- int offset,
- int count,
- AsyncCallback callback,
- object state
- )
- {
- throw new NotSupportedException ();
- }
-
- public override void Close ()
- {
- _disposed = true;
- }
-
- public override int EndRead (IAsyncResult asyncResult)
- {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- if (asyncResult == null)
- throw new ArgumentNullException ("asyncResult");
-
- if (asyncResult is HttpStreamAsyncResult) {
- var ares = (HttpStreamAsyncResult) asyncResult;
-
- if (!ares.IsCompleted)
- ares.AsyncWaitHandle.WaitOne ();
-
- return ares.SyncRead;
- }
-
- var nread = _innerStream.EndRead (asyncResult);
-
- if (nread > 0 && _bodyLeft > 0)
- _bodyLeft -= nread;
-
- return nread;
- }
-
- public override void EndWrite (IAsyncResult asyncResult)
- {
- throw new NotSupportedException ();
- }
-
- public override void Flush ()
- {
- }
-
- public override int Read (byte[] buffer, int offset, int count)
- {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- if (buffer == null)
- throw new ArgumentNullException ("buffer");
-
- if (offset < 0) {
- var msg = "A negative value.";
-
- throw new ArgumentOutOfRangeException ("offset", msg);
- }
-
- if (count < 0) {
- var msg = "A negative value.";
-
- throw new ArgumentOutOfRangeException ("count", msg);
- }
-
- var len = buffer.Length;
-
- if (offset + count > len) {
- var msg = "The sum of offset and count is greater than the length of buffer.";
-
- throw new ArgumentException (msg);
- }
-
- if (count == 0)
- return 0;
-
- var nread = fillFromInitialBuffer (buffer, offset, count);
-
- if (nread == -1)
- return 0;
-
- if (nread > 0)
- return nread;
-
- if (_bodyLeft > 0 && _bodyLeft < count)
- count = (int) _bodyLeft;
-
- nread = _innerStream.Read (buffer, offset, count);
-
- if (nread > 0 && _bodyLeft > 0)
- _bodyLeft -= nread;
-
- return nread;
- }
-
- public override long Seek (long offset, SeekOrigin origin)
- {
- throw new NotSupportedException ();
- }
-
- public override void SetLength (long value)
- {
- throw new NotSupportedException ();
- }
-
- public override void Write (byte[] buffer, int offset, int count)
- {
- throw new NotSupportedException ();
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Net/ResponseStream.cs b/websocket-sharp/Net/ResponseStream.cs
deleted file mode 100644
index 456d1e470..000000000
--- a/websocket-sharp/Net/ResponseStream.cs
+++ /dev/null
@@ -1,416 +0,0 @@
-#region License
-/*
- * ResponseStream.cs
- *
- * This code is derived from ResponseStream.cs (System.Net) of Mono
- * (http://www.mono-project.com).
- *
- * The MIT License
- *
- * Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
- * Copyright (c) 2012-2023 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-#region Authors
-/*
- * Authors:
- * - Gonzalo Paniagua Javier
- */
-#endregion
-
-using System;
-using System.IO;
-using System.Text;
-
-namespace WebSocketSharp.Net
-{
- internal class ResponseStream : Stream
- {
- #region Private Fields
-
- private MemoryStream _bodyBuffer;
- private static readonly byte[] _crlf;
- private bool _disposed;
- private Stream _innerStream;
- private static readonly byte[] _lastChunk;
- private static readonly int _maxHeadersLength;
- private HttpListenerResponse _response;
- private bool _sendChunked;
- private Action _write;
- private Action _writeBody;
- private Action _writeChunked;
-
- #endregion
-
- #region Static Constructor
-
- static ResponseStream ()
- {
- _crlf = new byte[] { 13, 10 }; // "\r\n"
- _lastChunk = new byte[] { 48, 13, 10, 13, 10 }; // "0\r\n\r\n"
- _maxHeadersLength = 32768;
- }
-
- #endregion
-
- #region Internal Constructors
-
- internal ResponseStream (
- Stream innerStream,
- HttpListenerResponse response,
- bool ignoreWriteExceptions
- )
- {
- _innerStream = innerStream;
- _response = response;
-
- if (ignoreWriteExceptions) {
- _write = writeWithoutThrowingException;
- _writeChunked = writeChunkedWithoutThrowingException;
- }
- else {
- _write = innerStream.Write;
- _writeChunked = writeChunked;
- }
-
- _bodyBuffer = new MemoryStream ();
- }
-
- #endregion
-
- #region Internal Properties
-
- internal string ObjectName {
- get {
- return GetType ().ToString ();
- }
- }
-
- #endregion
-
- #region Public Properties
-
- public override bool CanRead {
- get {
- return false;
- }
- }
-
- public override bool CanSeek {
- get {
- return false;
- }
- }
-
- public override bool CanWrite {
- get {
- return !_disposed;
- }
- }
-
- public override long Length {
- get {
- throw new NotSupportedException ();
- }
- }
-
- public override long Position {
- get {
- throw new NotSupportedException ();
- }
-
- set {
- throw new NotSupportedException ();
- }
- }
-
- #endregion
-
- #region Private Methods
-
- private bool flush (bool closing)
- {
- if (!_response.HeadersSent) {
- if (!flushHeaders ())
- return false;
-
- _response.HeadersSent = true;
-
- _sendChunked = _response.SendChunked;
- _writeBody = _sendChunked ? _writeChunked : _write;
- }
-
- flushBody (closing);
-
- return true;
- }
-
- private void flushBody (bool closing)
- {
- using (_bodyBuffer) {
- var len = _bodyBuffer.Length;
-
- if (len > Int32.MaxValue) {
- _bodyBuffer.Position = 0;
-
- var buffLen = 1024;
- var buff = new byte[buffLen];
- var nread = 0;
-
- while (true) {
- nread = _bodyBuffer.Read (buff, 0, buffLen);
-
- if (nread <= 0)
- break;
-
- _writeBody (buff, 0, nread);
- }
- }
- else if (len > 0) {
- var buff = _bodyBuffer.GetBuffer ();
-
- _writeBody (buff, 0, (int) len);
- }
- }
-
- if (!closing) {
- _bodyBuffer = new MemoryStream ();
-
- return;
- }
-
- if (_sendChunked)
- _write (_lastChunk, 0, 5);
-
- _bodyBuffer = null;
- }
-
- private bool flushHeaders ()
- {
- if (!_response.SendChunked) {
- if (_response.ContentLength64 != _bodyBuffer.Length)
- return false;
- }
-
- var headers = _response.FullHeaders;
-
- var stream = new MemoryStream ();
- var enc = Encoding.UTF8;
-
- using (var writer = new StreamWriter (stream, enc, 256)) {
- writer.Write (_response.StatusLine);
-
- var s = headers.ToStringMultiValue (true);
-
- writer.Write (s);
- writer.Flush ();
-
- var start = enc.GetPreamble ().Length;
- var len = stream.Length - start;
-
- if (len > _maxHeadersLength)
- return false;
-
- var buff = stream.GetBuffer ();
-
- _write (buff, start, (int) len);
- }
-
- _response.CloseConnection = headers["Connection"] == "close";
-
- return true;
- }
-
- private static byte[] getChunkSizeStringAsBytes (int size)
- {
- var fmt = "{0:x}\r\n";
- var s = String.Format (fmt, size);
-
- return Encoding.ASCII.GetBytes (s);
- }
-
- private void writeChunked (byte[] buffer, int offset, int count)
- {
- var size = getChunkSizeStringAsBytes (count);
-
- _innerStream.Write (size, 0, size.Length);
- _innerStream.Write (buffer, offset, count);
- _innerStream.Write (_crlf, 0, 2);
- }
-
- private void writeChunkedWithoutThrowingException (
- byte[] buffer,
- int offset,
- int count
- )
- {
- try {
- writeChunked (buffer, offset, count);
- }
- catch {
- }
- }
-
- private void writeWithoutThrowingException (
- byte[] buffer,
- int offset,
- int count
- )
- {
- try {
- _innerStream.Write (buffer, offset, count);
- }
- catch {
- }
- }
-
- #endregion
-
- #region Internal Methods
-
- internal void Close (bool force)
- {
- if (_disposed)
- return;
-
- _disposed = true;
-
- if (!force) {
- if (flush (true)) {
- _response.Close ();
-
- _response = null;
- _innerStream = null;
-
- return;
- }
-
- _response.CloseConnection = true;
- }
-
- if (_sendChunked)
- _write (_lastChunk, 0, 5);
-
- _bodyBuffer.Dispose ();
- _response.Abort ();
-
- _bodyBuffer = null;
- _response = null;
- _innerStream = null;
- }
-
- internal void InternalWrite (byte[] buffer, int offset, int count)
- {
- _write (buffer, offset, count);
- }
-
- #endregion
-
- #region Public Methods
-
- public override IAsyncResult BeginRead (
- byte[] buffer,
- int offset,
- int count,
- AsyncCallback callback,
- object state
- )
- {
- throw new NotSupportedException ();
- }
-
- public override IAsyncResult BeginWrite (
- byte[] buffer,
- int offset,
- int count,
- AsyncCallback callback,
- object state
- )
- {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- return _bodyBuffer.BeginWrite (buffer, offset, count, callback, state);
- }
-
- public override void Close ()
- {
- Close (false);
- }
-
- protected override void Dispose (bool disposing)
- {
- Close (!disposing);
- }
-
- public override int EndRead (IAsyncResult asyncResult)
- {
- throw new NotSupportedException ();
- }
-
- public override void EndWrite (IAsyncResult asyncResult)
- {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- _bodyBuffer.EndWrite (asyncResult);
- }
-
- public override void Flush ()
- {
- if (_disposed)
- return;
-
- var sendChunked = _sendChunked || _response.SendChunked;
-
- if (!sendChunked)
- return;
-
- flush (false);
- }
-
- public override int Read (byte[] buffer, int offset, int count)
- {
- throw new NotSupportedException ();
- }
-
- public override long Seek (long offset, SeekOrigin origin)
- {
- throw new NotSupportedException ();
- }
-
- public override void SetLength (long value)
- {
- throw new NotSupportedException ();
- }
-
- public override void Write (byte[] buffer, int offset, int count)
- {
- if (_disposed)
- throw new ObjectDisposedException (ObjectName);
-
- _bodyBuffer.Write (buffer, offset, count);
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Net/ServerSslConfiguration.cs b/websocket-sharp/Net/ServerSslConfiguration.cs
deleted file mode 100644
index b4de5d64c..000000000
--- a/websocket-sharp/Net/ServerSslConfiguration.cs
+++ /dev/null
@@ -1,239 +0,0 @@
-#region License
-/*
- * ServerSslConfiguration.cs
- *
- * The MIT License
- *
- * Copyright (c) 2014 liryna
- * Copyright (c) 2014-2024 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-#region Authors
-/*
- * Authors:
- * - Liryna
- */
-#endregion
-
-using System;
-using System.Net.Security;
-using System.Security.Authentication;
-using System.Security.Cryptography.X509Certificates;
-
-namespace WebSocketSharp.Net
-{
- ///
- /// Stores the parameters for instances used by
- /// a server.
- ///
- public class ServerSslConfiguration
- {
- #region Private Fields
-
- private bool _checkCertRevocation;
- private bool _clientCertRequired;
- private RemoteCertificateValidationCallback _clientCertValidationCallback;
- private SslProtocols _enabledSslProtocols;
- private X509Certificate2 _serverCert;
-
- #endregion
-
- #region Public Constructors
-
- ///
- /// Initializes a new instance of the
- /// class.
- ///
- public ServerSslConfiguration ()
- {
- _enabledSslProtocols = SslProtocols.None;
- }
-
- ///
- /// Initializes a new instance of the
- /// class copying from the specified configuration.
- ///
- ///
- /// A from which to copy.
- ///
- ///
- /// is .
- ///
- public ServerSslConfiguration (ServerSslConfiguration configuration)
- {
- if (configuration == null)
- throw new ArgumentNullException ("configuration");
-
- _checkCertRevocation = configuration._checkCertRevocation;
- _clientCertRequired = configuration._clientCertRequired;
- _clientCertValidationCallback = configuration._clientCertValidationCallback;
- _enabledSslProtocols = configuration._enabledSslProtocols;
- _serverCert = configuration._serverCert;
- }
-
- #endregion
-
- #region Public Properties
-
- ///
- /// Gets or sets a value indicating whether the certificate revocation
- /// list is checked during authentication.
- ///
- ///
- ///
- /// true if the certificate revocation list is checked during
- /// authentication; otherwise, false.
- ///
- ///
- /// The default value is false.
- ///
- ///
- public bool CheckCertificateRevocation {
- get {
- return _checkCertRevocation;
- }
-
- set {
- _checkCertRevocation = value;
- }
- }
-
- ///
- /// Gets or sets a value indicating whether each client is asked for
- /// a certificate for authentication.
- ///
- ///
- ///
- /// true if each client is asked for a certificate for
- /// authentication; otherwise, false.
- ///
- ///
- /// The default value is false.
- ///
- ///
- public bool ClientCertificateRequired {
- get {
- return _clientCertRequired;
- }
-
- set {
- _clientCertRequired = value;
- }
- }
-
- ///
- /// Gets or sets the callback used to validate the certificate supplied by
- /// each client.
- ///
- ///
- /// The certificate is valid if the callback returns true.
- ///
- ///
- ///
- /// A delegate.
- ///
- ///
- /// It represents the delegate called when the server validates
- /// the certificate.
- ///
- ///
- /// The default value invokes a method that only returns true.
- ///
- ///
- public RemoteCertificateValidationCallback ClientCertificateValidationCallback {
- get {
- if (_clientCertValidationCallback == null)
- _clientCertValidationCallback = defaultValidateClientCertificate;
-
- return _clientCertValidationCallback;
- }
-
- set {
- _clientCertValidationCallback = value;
- }
- }
-
- ///
- /// Gets or sets the enabled versions of the SSL/TLS protocols.
- ///
- ///
- ///
- /// Any of the enum values.
- ///
- ///
- /// It represents the enabled versions of the SSL/TLS protocols.
- ///
- ///
- /// The default value is .
- ///
- ///
- public SslProtocols EnabledSslProtocols {
- get {
- return _enabledSslProtocols;
- }
-
- set {
- _enabledSslProtocols = value;
- }
- }
-
- ///
- /// Gets or sets the certificate used to authenticate the server.
- ///
- ///
- ///
- /// A that represents an X.509 certificate.
- ///
- ///
- /// if not present.
- ///
- ///
- /// The default value is .
- ///
- ///
- public X509Certificate2 ServerCertificate {
- get {
- return _serverCert;
- }
-
- set {
- _serverCert = value;
- }
- }
-
- #endregion
-
- #region Private Methods
-
- private static bool defaultValidateClientCertificate (
- object sender,
- X509Certificate certificate,
- X509Chain chain,
- SslPolicyErrors sslPolicyErrors
- )
- {
- return true;
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Net/WebHeaderCollection.cs b/websocket-sharp/Net/WebHeaderCollection.cs
deleted file mode 100644
index 3f3ca74a9..000000000
--- a/websocket-sharp/Net/WebHeaderCollection.cs
+++ /dev/null
@@ -1,2006 +0,0 @@
-#region License
-/*
- * WebHeaderCollection.cs
- *
- * This code is derived from WebHeaderCollection.cs (System.Net) of Mono
- * (http://www.mono-project.com).
- *
- * The MIT License
- *
- * Copyright (c) 2003 Ximian, Inc. (http://www.ximian.com)
- * Copyright (c) 2007 Novell, Inc. (http://www.novell.com)
- * Copyright (c) 2012-2026 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-#region Authors
-/*
- * Authors:
- * - Lawrence Pit
- * - Gonzalo Paniagua Javier
- * - Miguel de Icaza
- */
-#endregion
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Collections.Specialized;
-using System.Runtime.InteropServices;
-using System.Runtime.Serialization;
-using System.Security.Permissions;
-using System.Text;
-
-namespace WebSocketSharp.Net
-{
- ///
- /// Provides a collection of the HTTP headers associated with a request or
- /// response.
- ///
- [Serializable]
- [ComVisible (true)]
- public class WebHeaderCollection : NameValueCollection, ISerializable
- {
- #region Private Fields
-
- private static readonly Dictionary _headers;
- private bool _internallyUsed;
- private HttpHeaderType _state;
-
- #endregion
-
- #region Static Constructor
-
- static WebHeaderCollection ()
- {
- _headers =
- new Dictionary (
- StringComparer.InvariantCultureIgnoreCase
- )
- {
- {
- "Accept",
- new HttpHeaderInfo (
- "Accept",
- HttpHeaderType.Request
- | HttpHeaderType.Restricted
- | HttpHeaderType.MultiValue
- )
- },
- {
- "AcceptCharset",
- new HttpHeaderInfo (
- "Accept-Charset",
- HttpHeaderType.Request | HttpHeaderType.MultiValue
- )
- },
- {
- "AcceptEncoding",
- new HttpHeaderInfo (
- "Accept-Encoding",
- HttpHeaderType.Request | HttpHeaderType.MultiValue
- )
- },
- {
- "AcceptLanguage",
- new HttpHeaderInfo (
- "Accept-Language",
- HttpHeaderType.Request | HttpHeaderType.MultiValue
- )
- },
- {
- "AcceptRanges",
- new HttpHeaderInfo (
- "Accept-Ranges",
- HttpHeaderType.Response | HttpHeaderType.MultiValue
- )
- },
- {
- "Age",
- new HttpHeaderInfo (
- "Age",
- HttpHeaderType.Response
- )
- },
- {
- "Allow",
- new HttpHeaderInfo (
- "Allow",
- HttpHeaderType.Request
- | HttpHeaderType.Response
- | HttpHeaderType.MultiValue
- )
- },
- {
- "Authorization",
- new HttpHeaderInfo (
- "Authorization",
- HttpHeaderType.Request
- | HttpHeaderType.Restricted
- | HttpHeaderType.MultiValue
- )
- },
- {
- "CacheControl",
- new HttpHeaderInfo (
- "Cache-Control",
- HttpHeaderType.Request
- | HttpHeaderType.Response
- | HttpHeaderType.MultiValue
- )
- },
- {
- "Connection",
- new HttpHeaderInfo (
- "Connection",
- HttpHeaderType.Request
- | HttpHeaderType.Response
- | HttpHeaderType.Restricted
- | HttpHeaderType.MultiValue
- )
- },
- {
- "ContentEncoding",
- new HttpHeaderInfo (
- "Content-Encoding",
- HttpHeaderType.Request
- | HttpHeaderType.Response
- | HttpHeaderType.MultiValue
- )
- },
- {
- "ContentLanguage",
- new HttpHeaderInfo (
- "Content-Language",
- HttpHeaderType.Request
- | HttpHeaderType.Response
- | HttpHeaderType.MultiValue
- )
- },
- {
- "ContentLength",
- new HttpHeaderInfo (
- "Content-Length",
- HttpHeaderType.Request
- | HttpHeaderType.Response
- | HttpHeaderType.Restricted
- )
- },
- {
- "ContentLocation",
- new HttpHeaderInfo (
- "Content-Location",
- HttpHeaderType.Request | HttpHeaderType.Response
- )
- },
- {
- "ContentMd5",
- new HttpHeaderInfo (
- "Content-MD5",
- HttpHeaderType.Request | HttpHeaderType.Response
- )
- },
- {
- "ContentRange",
- new HttpHeaderInfo (
- "Content-Range",
- HttpHeaderType.Request | HttpHeaderType.Response
- )
- },
- {
- "ContentType",
- new HttpHeaderInfo (
- "Content-Type",
- HttpHeaderType.Request
- | HttpHeaderType.Response
- | HttpHeaderType.Restricted
- )
- },
- {
- "Cookie",
- new HttpHeaderInfo (
- "Cookie",
- HttpHeaderType.Request | HttpHeaderType.Restricted
- )
- },
- {
- "Cookie2",
- new HttpHeaderInfo (
- "Cookie2",
- HttpHeaderType.Request | HttpHeaderType.Restricted
- )
- },
- {
- "Date",
- new HttpHeaderInfo (
- "Date",
- HttpHeaderType.Request
- | HttpHeaderType.Response
- | HttpHeaderType.Restricted
- )
- },
- {
- "Expect",
- new HttpHeaderInfo (
- "Expect",
- HttpHeaderType.Request
- | HttpHeaderType.Restricted
- | HttpHeaderType.MultiValue
- )
- },
- {
- "Expires",
- new HttpHeaderInfo (
- "Expires",
- HttpHeaderType.Request | HttpHeaderType.Response
- )
- },
- {
- "ETag",
- new HttpHeaderInfo (
- "ETag",
- HttpHeaderType.Response
- )
- },
- {
- "From",
- new HttpHeaderInfo (
- "From",
- HttpHeaderType.Request
- )
- },
- {
- "Host",
- new HttpHeaderInfo (
- "Host",
- HttpHeaderType.Request | HttpHeaderType.Restricted
- )
- },
- {
- "IfMatch",
- new HttpHeaderInfo (
- "If-Match",
- HttpHeaderType.Request | HttpHeaderType.MultiValue
- )
- },
- {
- "IfModifiedSince",
- new HttpHeaderInfo (
- "If-Modified-Since",
- HttpHeaderType.Request | HttpHeaderType.Restricted
- )
- },
- {
- "IfNoneMatch",
- new HttpHeaderInfo (
- "If-None-Match",
- HttpHeaderType.Request | HttpHeaderType.MultiValue
- )
- },
- {
- "IfRange",
- new HttpHeaderInfo (
- "If-Range",
- HttpHeaderType.Request
- )
- },
- {
- "IfUnmodifiedSince",
- new HttpHeaderInfo (
- "If-Unmodified-Since",
- HttpHeaderType.Request
- )
- },
- {
- "KeepAlive",
- new HttpHeaderInfo (
- "Keep-Alive",
- HttpHeaderType.Request
- | HttpHeaderType.Response
- | HttpHeaderType.MultiValue
- )
- },
- {
- "LastModified",
- new HttpHeaderInfo (
- "Last-Modified",
- HttpHeaderType.Request | HttpHeaderType.Response
- )
- },
- {
- "Location",
- new HttpHeaderInfo (
- "Location",
- HttpHeaderType.Response | HttpHeaderType.Restricted
- )
- },
- {
- "MaxForwards",
- new HttpHeaderInfo (
- "Max-Forwards",
- HttpHeaderType.Request
- )
- },
- {
- "Pragma",
- new HttpHeaderInfo (
- "Pragma",
- HttpHeaderType.Request | HttpHeaderType.Response
- )
- },
- {
- "ProxyAuthenticate",
- new HttpHeaderInfo (
- "Proxy-Authenticate",
- HttpHeaderType.Response
- | HttpHeaderType.Restricted
- | HttpHeaderType.MultiValue
- )
- },
- {
- "ProxyAuthorization",
- new HttpHeaderInfo (
- "Proxy-Authorization",
- HttpHeaderType.Request | HttpHeaderType.Restricted
- )
- },
- {
- "ProxyConnection",
- new HttpHeaderInfo (
- "Proxy-Connection",
- HttpHeaderType.Request
- | HttpHeaderType.Response
- | HttpHeaderType.Restricted
- )
- },
- {
- "Public",
- new HttpHeaderInfo (
- "Public",
- HttpHeaderType.Response | HttpHeaderType.MultiValue
- )
- },
- {
- "Range",
- new HttpHeaderInfo (
- "Range",
- HttpHeaderType.Request
- | HttpHeaderType.Restricted
- | HttpHeaderType.MultiValue
- )
- },
- {
- "Referer",
- new HttpHeaderInfo (
- "Referer",
- HttpHeaderType.Request | HttpHeaderType.Restricted
- )
- },
- {
- "RetryAfter",
- new HttpHeaderInfo (
- "Retry-After",
- HttpHeaderType.Response
- )
- },
- {
- "SecWebSocketAccept",
- new HttpHeaderInfo (
- "Sec-WebSocket-Accept",
- HttpHeaderType.Response | HttpHeaderType.Restricted
- )
- },
- {
- "SecWebSocketExtensions",
- new HttpHeaderInfo (
- "Sec-WebSocket-Extensions",
- HttpHeaderType.Request
- | HttpHeaderType.Response
- | HttpHeaderType.Restricted
- | HttpHeaderType.MultiValueInRequest
- )
- },
- {
- "SecWebSocketKey",
- new HttpHeaderInfo (
- "Sec-WebSocket-Key",
- HttpHeaderType.Request | HttpHeaderType.Restricted
- )
- },
- {
- "SecWebSocketProtocol",
- new HttpHeaderInfo (
- "Sec-WebSocket-Protocol",
- HttpHeaderType.Request
- | HttpHeaderType.Response
- | HttpHeaderType.Restricted
- | HttpHeaderType.MultiValueInRequest
- )
- },
- {
- "SecWebSocketVersion",
- new HttpHeaderInfo (
- "Sec-WebSocket-Version",
- HttpHeaderType.Request
- | HttpHeaderType.Response
- | HttpHeaderType.Restricted
- | HttpHeaderType.MultiValueInResponse
- )
- },
- {
- "Server",
- new HttpHeaderInfo (
- "Server",
- HttpHeaderType.Response
- )
- },
- {
- "SetCookie",
- new HttpHeaderInfo (
- "Set-Cookie",
- HttpHeaderType.Response
- | HttpHeaderType.Restricted
- | HttpHeaderType.MultiValue
- )
- },
- {
- "SetCookie2",
- new HttpHeaderInfo (
- "Set-Cookie2",
- HttpHeaderType.Response
- | HttpHeaderType.Restricted
- | HttpHeaderType.MultiValue
- )
- },
- {
- "Te",
- new HttpHeaderInfo (
- "TE",
- HttpHeaderType.Request
- )
- },
- {
- "Trailer",
- new HttpHeaderInfo (
- "Trailer",
- HttpHeaderType.Request | HttpHeaderType.Response
- )
- },
- {
- "TransferEncoding",
- new HttpHeaderInfo (
- "Transfer-Encoding",
- HttpHeaderType.Request
- | HttpHeaderType.Response
- | HttpHeaderType.Restricted
- | HttpHeaderType.MultiValue
- )
- },
- {
- "Translate",
- new HttpHeaderInfo (
- "Translate",
- HttpHeaderType.Request
- )
- },
- {
- "Upgrade",
- new HttpHeaderInfo (
- "Upgrade",
- HttpHeaderType.Request
- | HttpHeaderType.Response
- | HttpHeaderType.Restricted
- | HttpHeaderType.MultiValue
- )
- },
- {
- "UserAgent",
- new HttpHeaderInfo (
- "User-Agent",
- HttpHeaderType.Request | HttpHeaderType.Restricted
- )
- },
- {
- "Vary",
- new HttpHeaderInfo (
- "Vary",
- HttpHeaderType.Response | HttpHeaderType.MultiValue
- )
- },
- {
- "Via",
- new HttpHeaderInfo (
- "Via",
- HttpHeaderType.Request
- | HttpHeaderType.Response
- | HttpHeaderType.MultiValue
- )
- },
- {
- "Warning",
- new HttpHeaderInfo (
- "Warning",
- HttpHeaderType.Request
- | HttpHeaderType.Response
- | HttpHeaderType.MultiValue
- )
- },
- {
- "WwwAuthenticate",
- new HttpHeaderInfo (
- "WWW-Authenticate",
- HttpHeaderType.Response
- | HttpHeaderType.Restricted
- | HttpHeaderType.MultiValue
- )
- }
- };
- }
-
- #endregion
-
- #region Internal Constructors
-
- internal WebHeaderCollection (HttpHeaderType state, bool internallyUsed)
- {
- _state = state;
- _internallyUsed = internallyUsed;
- }
-
- #endregion
-
- #region Protected Constructors
-
- ///
- /// Initializes a new instance of the
- /// class with the specified serialized data.
- ///
- ///
- /// A that contains the serialized
- /// object data.
- ///
- ///
- /// A that specifies the source for
- /// the deserialization.
- ///
- ///
- /// An element with the specified name is not found in
- /// .
- ///
- ///
- /// is .
- ///
- protected WebHeaderCollection (
- SerializationInfo serializationInfo,
- StreamingContext streamingContext
- )
- {
- if (serializationInfo == null)
- throw new ArgumentNullException ("serializationInfo");
-
- try {
- _internallyUsed = serializationInfo.GetBoolean ("InternallyUsed");
- _state = (HttpHeaderType) serializationInfo.GetInt32 ("State");
-
- var cnt = serializationInfo.GetInt32 ("Count");
-
- for (var i = 0; i < cnt; i++) {
- base.Add (
- serializationInfo.GetString (i.ToString ()),
- serializationInfo.GetString ((cnt + i).ToString ())
- );
- }
- }
- catch (SerializationException ex) {
- throw new ArgumentException (ex.Message, "serializationInfo", ex);
- }
- }
-
- #endregion
-
- #region Public Constructors
-
- ///
- /// Initializes a new instance of the
- /// class.
- ///
- public WebHeaderCollection ()
- {
- }
-
- #endregion
-
- #region Internal Properties
-
- internal HttpHeaderType State {
- get {
- return _state;
- }
- }
-
- #endregion
-
- #region Public Properties
-
- ///
- /// Gets all header names in the collection.
- ///
- ///
- /// An array of that contains all header names in
- /// the collection.
- ///
- public override string[] AllKeys {
- get {
- return base.AllKeys;
- }
- }
-
- ///
- /// Gets the number of headers in the collection.
- ///
- ///
- /// An that represents the number of headers in
- /// the collection.
- ///
- public override int Count {
- get {
- return base.Count;
- }
- }
-
- ///
- /// Gets or sets the specified request header.
- ///
- ///
- ///
- /// A that represents the value of the specified
- /// request header.
- ///
- ///
- /// The get operation returns if not found.
- ///
- ///
- ///
- ///
- /// One of the enum values.
- ///
- ///
- /// It specifies a request header to get or set.
- ///
- ///
- ///
- ///
- /// The set operation throws this exception if
- /// is a restricted header.
- ///
- ///
- /// -or-
- ///
- ///
- /// The set operation throws this exception if
- /// contains an invalid character.
- ///
- ///
- ///
- /// The set operation throws this exception if the length of
- /// is greater than 65,535 characters.
- ///
- ///
- /// The set operation is not available if the current instance does not
- /// allow the request header.
- ///
- public string this[HttpRequestHeader header] {
- get {
- var key = header.ToString ();
- var name = getHeaderName (key);
-
- return Get (name);
- }
-
- set {
- Add (header, value);
- }
- }
-
- ///
- /// Gets or sets the specified response header.
- ///
- ///
- ///
- /// A that represents the value of the specified
- /// response header.
- ///
- ///
- /// The get operation returns if not found.
- ///
- ///
- ///
- ///
- /// One of the enum values.
- ///
- ///
- /// It specifies a response header to get or set.
- ///
- ///
- ///
- ///
- /// The set operation throws this exception if
- /// is a restricted header.
- ///
- ///
- /// -or-
- ///
- ///
- /// The set operation throws this exception if
- /// contains an invalid character.
- ///
- ///
- ///
- /// The set operation throws this exception if the length of
- /// is greater than 65,535 characters.
- ///
- ///
- /// The set operation is not available if the current instance does not
- /// allow the response header.
- ///
- public string this[HttpResponseHeader header] {
- get {
- var key = header.ToString ();
- var name = getHeaderName (key);
-
- return Get (name);
- }
-
- set {
- Add (header, value);
- }
- }
-
- ///
- /// Gets a collection of header names in the collection.
- ///
- ///
- /// A that contains
- /// all header names in the collection.
- ///
- public override NameObjectCollectionBase.KeysCollection Keys {
- get {
- return base.Keys;
- }
- }
-
- #endregion
-
- #region Private Methods
-
- private void add (string name, string value, HttpHeaderType headerType)
- {
- base.Add (name, value);
-
- if (_state != HttpHeaderType.Unspecified)
- return;
-
- if (headerType == HttpHeaderType.Unspecified)
- return;
-
- _state = headerType;
- }
-
- private void checkAllowed (HttpHeaderType headerType)
- {
- if (_state == HttpHeaderType.Unspecified)
- return;
-
- if (headerType == HttpHeaderType.Unspecified)
- return;
-
- if (headerType != _state) {
- var msg = "The current instance does not allow that header type.";
-
- throw new InvalidOperationException (msg);
- }
- }
-
- private static string checkName (string name, string paramName)
- {
- if (name == null)
- throw new ArgumentNullException (paramName);
-
- if (name.Length == 0) {
- var msg = "An empty string.";
-
- throw new ArgumentException (msg, paramName);
- }
-
- name = name.Trim ();
-
- if (name.Length == 0) {
- var msg = "That name is a string of spaces.";
-
- throw new ArgumentException (msg, paramName);
- }
-
- if (!name.IsToken ()) {
- var msg = "That name contains an invalid character.";
-
- throw new ArgumentException (msg, paramName);
- }
-
- return name;
- }
-
- private void checkRestricted (string name, HttpHeaderType headerType)
- {
- if (_internallyUsed)
- return;
-
- var res = headerType == HttpHeaderType.Response;
-
- if (isRestricted (name, res)) {
- var msg = "That header is a restricted header.";
-
- throw new ArgumentException (msg);
- }
- }
-
- private static string checkValue (string value, string paramName)
- {
- if (value == null)
- return String.Empty;
-
- value = value.Trim ();
-
- var len = value.Length;
-
- if (len == 0)
- return value;
-
- if (len > 65535) {
- var msg = "The length of that value is greater than 65,535 characters.";
-
- throw new ArgumentOutOfRangeException (paramName, msg);
- }
-
- if (!value.IsText ()) {
- var msg = "That value contains an invalid character.";
-
- throw new ArgumentException (msg, paramName);
- }
-
- return value;
- }
-
- private static HttpHeaderInfo getHeaderInfo (string name)
- {
- var compType = StringComparison.InvariantCultureIgnoreCase;
-
- foreach (var headerInfo in _headers.Values) {
- if (headerInfo.HeaderName.Equals (name, compType))
- return headerInfo;
- }
-
- return null;
- }
-
- private static string getHeaderName (string key)
- {
- HttpHeaderInfo headerInfo;
-
- return _headers.TryGetValue (key, out headerInfo)
- ? headerInfo.HeaderName
- : null;
- }
-
- private static HttpHeaderType getHeaderType (string name)
- {
- var headerInfo = getHeaderInfo (name);
-
- if (headerInfo == null)
- return HttpHeaderType.Unspecified;
-
- if (headerInfo.IsRequest) {
- return !headerInfo.IsResponse
- ? HttpHeaderType.Request
- : HttpHeaderType.Unspecified;
- }
-
- return headerInfo.IsResponse
- ? HttpHeaderType.Response
- : HttpHeaderType.Unspecified;
- }
-
- private static bool isMultiValue (string name, bool response)
- {
- var headerInfo = getHeaderInfo (name);
-
- return headerInfo != null && headerInfo.IsMultiValue (response);
- }
-
- private static bool isRestricted (string name, bool response)
- {
- var headerInfo = getHeaderInfo (name);
-
- return headerInfo != null && headerInfo.IsRestricted (response);
- }
-
- private void set (string name, string value, HttpHeaderType headerType)
- {
- base.Set (name, value);
-
- if (_state != HttpHeaderType.Unspecified)
- return;
-
- if (headerType == HttpHeaderType.Unspecified)
- return;
-
- _state = headerType;
- }
-
- #endregion
-
- #region Internal Methods
-
- internal void InternalRemove (string name)
- {
- base.Remove (name);
- }
-
- internal void InternalSet (string header, bool response)
- {
- var idx = header.IndexOf (':');
-
- if (idx == -1) {
- var msg = "It does not contain a colon character.";
-
- throw new ArgumentException (msg, "header");
- }
-
- if (idx == 0) {
- var msg = "It does not include a header name.";
-
- throw new ArgumentException (msg, "header");
- }
-
- var name = header.Substring (0, idx);
- var val = idx < header.Length - 1
- ? header.Substring (idx + 1)
- : String.Empty;
-
- name = checkName (name, "header");
- val = checkValue (val, "header");
-
- if (isMultiValue (name, response)) {
- base.Add (name, val);
-
- return;
- }
-
- base.Set (name, val);
- }
-
- internal void InternalSet (string name, string value, bool response)
- {
- value = checkValue (value, "value");
-
- if (isMultiValue (name, response)) {
- base.Add (name, value);
-
- return;
- }
-
- base.Set (name, value);
- }
-
- internal string ToStringMultiValue (bool response)
- {
- var cnt = Count;
-
- if (cnt == 0)
- return "\r\n";
-
- var buff = new StringBuilder ();
-
- var fmt = "{0}: {1}\r\n";
-
- for (var i = 0; i < cnt; i++) {
- var name = GetKey (i);
-
- if (isMultiValue (name, response)) {
- foreach (var val in GetValues (i))
- buff.AppendFormat (fmt, name, val);
-
- continue;
- }
-
- buff.AppendFormat (fmt, name, Get (i));
- }
-
- buff.Append ("\r\n");
-
- return buff.ToString ();
- }
-
- #endregion
-
- #region Protected Methods
-
- ///
- /// Adds a header to the collection without checking if that header is
- /// on the restricted header list.
- ///
- ///
- /// If the specified header is already present in the collection,
- /// is added to the comma-separated
- /// list of the existing values.
- ///
- ///
- /// A that specifies the name of a header to add.
- ///
- ///
- /// A that specifies the value of the header.
- ///
- ///
- ///
- /// is an empty string.
- ///
- ///
- /// -or-
- ///
- ///
- /// is a string of spaces.
- ///
- ///
- /// -or-
- ///
- ///
- /// contains an invalid character.
- ///
- ///
- /// -or-
- ///
- ///
- /// contains an invalid character.
- ///
- ///
- ///
- /// is .
- ///
- ///
- /// The length of is greater than 65,535
- /// characters.
- ///
- ///
- /// This method is not available if the current instance does not allow
- /// that header type.
- ///
- protected void AddWithoutValidate (string headerName, string headerValue)
- {
- headerName = checkName (headerName, "headerName");
-
- var headerType = getHeaderType (headerName);
-
- checkAllowed (headerType);
-
- headerValue = checkValue (headerValue, "headerValue");
-
- add (headerName, headerValue, headerType);
- }
-
- #endregion
-
- #region Public Methods
-
- ///
- /// Adds the specified header to the collection.
- ///
- ///
- /// If the specified header is already present in the collection,
- /// the value part of is added to the
- /// comma-separated list of the existing values.
- ///
- ///
- /// A that specifies a header to add,
- /// with the name and value separated by a colon character (':').
- ///
- ///
- ///
- /// is an empty string.
- ///
- ///
- /// -or-
- ///
- ///
- /// does not contain a colon character.
- ///
- ///
- /// -or-
- ///
- ///
- /// does not include a header name.
- ///
- ///
- /// -or-
- ///
- ///
- /// The name part of is a string of spaces.
- ///
- ///
- /// -or-
- ///
- ///
- /// The name part of contains an invalid
- /// character.
- ///
- ///
- /// -or-
- ///
- ///
- /// is a restricted header.
- ///
- ///
- /// -or-
- ///
- ///
- /// The value part of contains an invalid
- /// character.
- ///
- ///
- ///
- /// is .
- ///
- ///
- /// The length of the value part of is greater
- /// than 65,535 characters.
- ///
- ///
- /// This method is not available if the current instance does not allow
- /// that header type.
- ///
- public void Add (string header)
- {
- if (header == null)
- throw new ArgumentNullException ("header");
-
- var len = header.Length;
-
- if (len == 0) {
- var msg = "An empty string.";
-
- throw new ArgumentException (msg, "header");
- }
-
- var idx = header.IndexOf (':');
-
- if (idx == -1) {
- var msg = "It does not contain a colon character.";
-
- throw new ArgumentException (msg, "header");
- }
-
- if (idx == 0) {
- var msg = "It does not include a header name.";
-
- throw new ArgumentException (msg, "header");
- }
-
- var name = header.Substring (0, idx);
- var val = idx < len - 1 ? header.Substring (idx + 1) : String.Empty;
-
- name = checkName (name, "header");
-
- var headerType = getHeaderType (name);
-
- checkAllowed (headerType);
-
- checkRestricted (name, headerType);
-
- val = checkValue (val, "header");
-
- add (name, val, headerType);
- }
-
- ///
- /// Adds the specified request header with the specified value to
- /// the collection.
- ///
- ///
- /// If the specified request header is already present in the collection,
- /// is added to the comma-separated list of the
- /// existing values.
- ///
- ///
- ///
- /// One of the enum values.
- ///
- ///
- /// It specifies a request header to add.
- ///
- ///
- ///
- /// A that specifies the value of the header.
- ///
- ///
- ///
- /// is a restricted header.
- ///
- ///
- /// -or-
- ///
- ///
- /// contains an invalid character.
- ///
- ///
- ///
- /// The length of is greater than 65,535
- /// characters.
- ///
- ///
- /// This method is not available if the current instance does not allow
- /// the request header.
- ///
- public void Add (HttpRequestHeader header, string value)
- {
- checkAllowed (HttpHeaderType.Request);
-
- var key = header.ToString ();
- var name = getHeaderName (key);
-
- checkRestricted (name, HttpHeaderType.Request);
-
- value = checkValue (value, "value");
-
- add (name, value, HttpHeaderType.Request);
- }
-
- ///
- /// Adds the specified response header with the specified value to
- /// the collection.
- ///
- ///
- /// If the specified response header is already present in the collection,
- /// is added to the comma-separated list of the
- /// existing values.
- ///
- ///
- ///
- /// One of the enum values.
- ///
- ///
- /// It specifies a response header to add.
- ///
- ///
- ///
- /// A that specifies the value of the header.
- ///
- ///
- ///
- /// is a restricted header.
- ///
- ///
- /// -or-
- ///
- ///
- /// contains an invalid character.
- ///
- ///
- ///
- /// The length of is greater than 65,535
- /// characters.
- ///
- ///
- /// This method is not available if the current instance does not allow
- /// the response header.
- ///
- public void Add (HttpResponseHeader header, string value)
- {
- checkAllowed (HttpHeaderType.Response);
-
- var key = header.ToString ();
- var name = getHeaderName (key);
-
- checkRestricted (name, HttpHeaderType.Response);
-
- value = checkValue (value, "value");
-
- add (name, value, HttpHeaderType.Response);
- }
-
- ///
- /// Adds a header with the specified name and value to the collection.
- ///
- ///
- /// If the specified header is already present in the collection,
- /// is added to the comma-separated list of
- /// the existing values.
- ///
- ///
- /// A that specifies the name of a header to add.
- ///
- ///
- /// A that specifies the value of the header.
- ///
- ///
- ///
- /// is an empty string.
- ///
- ///
- /// -or-
- ///
- ///
- /// is a string of spaces.
- ///
- ///
- /// -or-
- ///
- ///
- /// contains an invalid character.
- ///
- ///
- /// -or-
- ///
- ///
- /// is a restricted header name.
- ///
- ///
- /// -or-
- ///
- ///
- /// contains an invalid character.
- ///
- ///
- ///
- /// is .
- ///
- ///
- /// The length of is greater than 65,535
- /// characters.
- ///
- ///
- /// This method is not available if the current instance does not allow
- /// that header type.
- ///
- public override void Add (string name, string value)
- {
- name = checkName (name, "name");
-
- var headerType = getHeaderType (name);
-
- checkAllowed (headerType);
-
- checkRestricted (name, headerType);
-
- value = checkValue (value, "value");
-
- add (name, value, headerType);
- }
-
- ///
- /// Removes all headers from the collection.
- ///
- public override void Clear ()
- {
- base.Clear ();
-
- _state = HttpHeaderType.Unspecified;
- }
-
- ///
- /// Get the value of a header at the specified index from the collection.
- ///
- ///
- /// A that holds the value of the specified header.
- ///
- ///
- /// An that specifies the zero-based index of a header
- /// to get.
- ///
- ///
- /// is out of allowable range of indexes for
- /// the collection.
- ///
- public override string Get (int index)
- {
- return base.Get (index);
- }
-
- ///
- /// Get the value of a header with the specified name from the collection.
- ///
- ///
- ///
- /// A that holds the value of the specified header.
- ///
- ///
- /// if not found.
- ///
- ///
- ///
- /// A that specifies the name of a header to get.
- ///
- public override string Get (string name)
- {
- return base.Get (name);
- }
-
- ///
- /// Gets the enumerator used to iterate through the collection.
- ///
- ///
- /// An instance used to iterate through
- /// the collection.
- ///
- public override IEnumerator GetEnumerator ()
- {
- return base.GetEnumerator ();
- }
-
- ///
- /// Get the name of a header at the specified index from the collection.
- ///
- ///
- /// A that holds the name of the specified header.
- ///
- ///
- /// An that specifies the zero-based index of a header
- /// to get.
- ///
- ///
- /// is out of allowable range of indexes for
- /// the collection.
- ///
- public override string GetKey (int index)
- {
- return base.GetKey (index);
- }
-
- ///
- /// Get the values of a header at the specified index from the collection.
- ///
- ///
- ///
- /// An array of that holds the values of
- /// the specified header.
- ///
- ///
- /// if not present.
- ///
- ///
- ///
- /// An that specifies the zero-based index of a header
- /// to get.
- ///
- ///
- /// is out of allowable range of indexes for
- /// the collection.
- ///
- public override string[] GetValues (int index)
- {
- var vals = base.GetValues (index);
-
- return vals != null && vals.Length > 0 ? vals : null;
- }
-
- ///
- /// Get the values of a header with the specified name from the collection.
- ///
- ///
- ///
- /// An array of that holds the values of
- /// the specified header.
- ///
- ///
- /// if not present.
- ///
- ///
- ///
- /// A that specifies the name of a header to get.
- ///
- public override string[] GetValues (string name)
- {
- var vals = base.GetValues (name);
-
- return vals != null && vals.Length > 0 ? vals : null;
- }
-
- ///
- /// Populates the specified instance with
- /// the data needed to serialize the current instance.
- ///
- ///
- /// A that holds the serialized object data.
- ///
- ///
- /// A that specifies the destination for
- /// the serialization.
- ///
- ///
- /// is .
- ///
- [
- SecurityPermission (
- SecurityAction.LinkDemand,
- Flags = SecurityPermissionFlag.SerializationFormatter
- )
- ]
- public override void GetObjectData (
- SerializationInfo serializationInfo,
- StreamingContext streamingContext
- )
- {
- if (serializationInfo == null)
- throw new ArgumentNullException ("serializationInfo");
-
- serializationInfo.AddValue ("InternallyUsed", _internallyUsed);
- serializationInfo.AddValue ("State", (int) _state);
-
- var cnt = Count;
-
- serializationInfo.AddValue ("Count", cnt);
-
- for (var i = 0; i < cnt; i++) {
- serializationInfo.AddValue (i.ToString (), GetKey (i));
- serializationInfo.AddValue ((cnt + i).ToString (), Get (i));
- }
- }
-
- ///
- /// Determines whether the specified header can be set for the request.
- ///
- ///
- /// true if the specified header cannot be set; otherwise,
- /// false.
- ///
- ///
- /// A that specifies the name of a header to test.
- ///
- ///
- ///
- /// is an empty string.
- ///
- ///
- /// -or-
- ///
- ///
- /// is a string of spaces.
- ///
- ///
- /// -or-
- ///
- ///
- /// contains an invalid character.
- ///
- ///
- ///
- /// is .
- ///
- public static bool IsRestricted (string headerName)
- {
- return IsRestricted (headerName, false);
- }
-
- ///
- /// Determines whether the specified header can be set for the request or
- /// the response.
- ///
- ///
- /// true if the specified header cannot be set; otherwise,
- /// false.
- ///
- ///
- /// A that specifies the name of a header to test.
- ///
- ///
- /// A : true if the test is for the response;
- /// otherwise, false.
- ///
- ///
- ///
- /// is an empty string.
- ///
- ///
- /// -or-
- ///
- ///
- /// is a string of spaces.
- ///
- ///
- /// -or-
- ///
- ///
- /// contains an invalid character.
- ///
- ///
- ///
- /// is .
- ///
- public static bool IsRestricted (string headerName, bool response)
- {
- headerName = checkName (headerName, "headerName");
-
- return isRestricted (headerName, response);
- }
-
- ///
- /// Implements the interface and raises
- /// the deserialization event when the deserialization is complete.
- ///
- ///
- /// An instance that represents the source of
- /// the deserialization event.
- ///
- public override void OnDeserialization (object sender)
- {
- }
-
- ///
- /// Removes the specified request header from the collection.
- ///
- ///
- ///
- /// One of the enum values.
- ///
- ///
- /// It specifies a request header to remove.
- ///
- ///
- ///
- /// is a restricted header.
- ///
- ///
- /// This method is not available if the current instance does not allow
- /// the request header.
- ///
- public void Remove (HttpRequestHeader header)
- {
- checkAllowed (HttpHeaderType.Request);
-
- var key = header.ToString ();
- var name = getHeaderName (key);
-
- checkRestricted (name, HttpHeaderType.Request);
-
- base.Remove (name);
- }
-
- ///
- /// Removes the specified response header from the collection.
- ///
- ///
- ///
- /// One of the enum values.
- ///
- ///
- /// It specifies a response header to remove.
- ///
- ///
- ///
- /// is a restricted header.
- ///
- ///
- /// This method is not available if the current instance does not allow
- /// the response header.
- ///
- public void Remove (HttpResponseHeader header)
- {
- checkAllowed (HttpHeaderType.Response);
-
- var key = header.ToString ();
- var name = getHeaderName (key);
-
- checkRestricted (name, HttpHeaderType.Response);
-
- base.Remove (name);
- }
-
- ///
- /// Removes the specified header from the collection.
- ///
- ///
- /// A that specifies the name of a header to remove.
- ///
- ///
- ///
- /// is an empty string.
- ///
- ///
- /// -or-
- ///
- ///
- /// is a string of spaces.
- ///
- ///
- /// -or-
- ///
- ///
- /// contains an invalid character.
- ///
- ///
- /// -or-
- ///
- ///
- /// is a restricted header name.
- ///
- ///
- ///
- /// is .
- ///
- ///
- /// This method is not available if the current instance does not allow
- /// that header type.
- ///
- public override void Remove (string name)
- {
- name = checkName (name, "name");
-
- var headerType = getHeaderType (name);
-
- checkAllowed (headerType);
-
- checkRestricted (name, headerType);
-
- base.Remove (name);
- }
-
- ///
- /// Sets the specified request header to the specified value.
- ///
- ///
- /// If the specified request header is already present in the collection,
- /// replaces the existing value.
- ///
- ///
- ///
- /// One of the enum values.
- ///
- ///
- /// It specifies a request header to set.
- ///
- ///
- ///
- /// A that specifies the value of the header.
- ///
- ///
- ///
- /// is a restricted header.
- ///
- ///
- /// -or-
- ///
- ///
- /// contains an invalid character.
- ///
- ///
- ///
- /// The length of is greater than 65,535
- /// characters.
- ///
- ///
- /// This method is not available if the current instance does not allow
- /// the request header.
- ///
- public void Set (HttpRequestHeader header, string value)
- {
- checkAllowed (HttpHeaderType.Request);
-
- var key = header.ToString ();
- var name = getHeaderName (key);
-
- checkRestricted (name, HttpHeaderType.Request);
-
- value = checkValue (value, "value");
-
- set (name, value, HttpHeaderType.Request);
- }
-
- ///
- /// Sets the specified response header to the specified value.
- ///
- ///
- /// If the specified response header is already present in the collection,
- /// replaces the existing value.
- ///
- ///
- ///
- /// One of the enum values.
- ///
- ///
- /// It specifies a response header to set.
- ///
- ///
- ///
- /// A that specifies the value of the header.
- ///
- ///
- ///
- /// is a restricted header.
- ///
- ///
- /// -or-
- ///
- ///
- /// contains an invalid character.
- ///
- ///
- ///
- /// The length of is greater than 65,535
- /// characters.
- ///
- ///
- /// This method is not available if the current instance does not allow
- /// the response header.
- ///
- public void Set (HttpResponseHeader header, string value)
- {
- checkAllowed (HttpHeaderType.Response);
-
- var key = header.ToString ();
- var name = getHeaderName (key);
-
- checkRestricted (name, HttpHeaderType.Response);
-
- value = checkValue (value, "value");
-
- set (name, value, HttpHeaderType.Response);
- }
-
- ///
- /// Sets the specified header to the specified value.
- ///
- ///
- /// If the specified header is already present in the collection,
- /// replaces the existing value.
- ///
- ///
- /// A that specifies the name of a header to set.
- ///
- ///
- /// A that specifies the value of the header.
- ///
- ///
- ///
- /// is an empty string.
- ///
- ///
- /// -or-
- ///
- ///
- /// is a string of spaces.
- ///
- ///
- /// -or-
- ///
- ///
- /// contains an invalid character.
- ///
- ///
- /// -or-
- ///
- ///
- /// is a restricted header name.
- ///
- ///
- /// -or-
- ///
- ///
- /// contains an invalid character.
- ///
- ///
- ///
- /// is .
- ///
- ///
- /// The length of is greater than 65,535
- /// characters.
- ///
- ///
- /// This method is not available if the current instance does not allow
- /// that header type.
- ///
- public override void Set (string name, string value)
- {
- name = checkName (name, "name");
-
- var headerType = getHeaderType (name);
-
- checkAllowed (headerType);
-
- checkRestricted (name, headerType);
-
- value = checkValue (value, "value");
-
- set (name, value, headerType);
- }
-
- ///
- /// Converts the current instance to an array of byte.
- ///
- ///
- /// An array of converted from a string that represents
- /// the current instance.
- ///
- public byte[] ToByteArray ()
- {
- var s = ToString ();
-
- return Encoding.UTF8.GetBytes (s);
- }
-
- ///
- /// Returns a string that represents the current instance.
- ///
- ///
- /// A that represents all headers in the collection.
- ///
- public override string ToString ()
- {
- var cnt = Count;
-
- if (cnt == 0)
- return "\r\n";
-
- var buff = new StringBuilder ();
-
- var fmt = "{0}: {1}\r\n";
-
- for (var i = 0; i < cnt; i++)
- buff.AppendFormat (fmt, GetKey (i), Get (i));
-
- buff.Append ("\r\n");
-
- return buff.ToString ();
- }
-
- #endregion
-
- #region Explicit Interface Implementations
-
- ///
- /// Populates the specified instance with
- /// the data needed to serialize the current instance.
- ///
- ///
- /// A that holds the serialized object data.
- ///
- ///
- /// A that specifies the destination for
- /// the serialization.
- ///
- ///
- /// is .
- ///
- [
- SecurityPermission (
- SecurityAction.LinkDemand,
- Flags = SecurityPermissionFlag.SerializationFormatter,
- SerializationFormatter = true
- )
- ]
- void ISerializable.GetObjectData (
- SerializationInfo serializationInfo,
- StreamingContext streamingContext
- )
- {
- GetObjectData (serializationInfo, streamingContext);
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Net/WebSockets/HttpListenerWebSocketContext.cs b/websocket-sharp/Net/WebSockets/HttpListenerWebSocketContext.cs
deleted file mode 100644
index 7e0358d1f..000000000
--- a/websocket-sharp/Net/WebSockets/HttpListenerWebSocketContext.cs
+++ /dev/null
@@ -1,406 +0,0 @@
-#region License
-/*
- * HttpListenerWebSocketContext.cs
- *
- * The MIT License
- *
- * Copyright (c) 2012-2025 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Collections.Specialized;
-using System.IO;
-using System.Net.Sockets;
-using System.Security.Principal;
-
-namespace WebSocketSharp.Net.WebSockets
-{
- ///
- /// Provides the access to the information in a WebSocket handshake request
- /// to a instance.
- ///
- public class HttpListenerWebSocketContext : WebSocketContext
- {
- #region Private Fields
-
- private HttpListenerContext _context;
- private WebSocket _websocket;
-
- #endregion
-
- #region Internal Constructors
-
- internal HttpListenerWebSocketContext (
- HttpListenerContext context,
- string protocol
- )
- {
- _context = context;
- _websocket = new WebSocket (this, protocol);
- }
-
- #endregion
-
- #region Internal Properties
-
- internal Logger Log {
- get {
- return _context.Listener.Log;
- }
- }
-
- internal Socket Socket {
- get {
- return _context.Connection.Socket;
- }
- }
-
- internal Stream Stream {
- get {
- return _context.Connection.Stream;
- }
- }
-
- #endregion
-
- #region Public Properties
-
- ///
- /// Gets the HTTP cookies included in the handshake request.
- ///
- ///
- ///
- /// A that contains
- /// the cookies.
- ///
- ///
- /// An empty collection if not included.
- ///
- ///
- public override CookieCollection CookieCollection {
- get {
- return _context.Request.Cookies;
- }
- }
-
- ///
- /// Gets the HTTP headers included in the handshake request.
- ///
- ///
- /// A that contains the headers.
- ///
- public override NameValueCollection Headers {
- get {
- return _context.Request.Headers;
- }
- }
-
- ///
- /// Gets the value of the Host header included in the handshake request.
- ///
- ///
- ///
- /// A that represents the server host name requested
- /// by the client.
- ///
- ///
- /// It includes the port number if provided.
- ///
- ///
- public override string Host {
- get {
- return _context.Request.UserHostName;
- }
- }
-
- ///
- /// Gets a value indicating whether the client is authenticated.
- ///
- ///
- /// true if the client is authenticated; otherwise, false.
- ///
- public override bool IsAuthenticated {
- get {
- return _context.Request.IsAuthenticated;
- }
- }
-
- ///
- /// Gets a value indicating whether the handshake request is sent from
- /// the local computer.
- ///
- ///
- /// true if the handshake request is sent from the same computer
- /// as the server; otherwise, false.
- ///
- public override bool IsLocal {
- get {
- return _context.Request.IsLocal;
- }
- }
-
- ///
- /// Gets a value indicating whether a secure connection is used to send
- /// the handshake request.
- ///
- ///
- /// true if the connection is secure; otherwise, false.
- ///
- public override bool IsSecureConnection {
- get {
- return _context.Request.IsSecureConnection;
- }
- }
-
- ///
- /// Gets a value indicating whether the request is a WebSocket handshake
- /// request.
- ///
- ///
- /// true if the request is a WebSocket handshake request; otherwise,
- /// false.
- ///
- public override bool IsWebSocketRequest {
- get {
- return _context.Request.IsWebSocketRequest;
- }
- }
-
- ///
- /// Gets the value of the Origin header included in the handshake request.
- ///
- ///
- ///
- /// A that represents the value of the Origin header.
- ///
- ///
- /// if not included.
- ///
- ///
- public override string Origin {
- get {
- return _context.Request.Headers["Origin"];
- }
- }
-
- ///
- /// Gets the query string included in the handshake request.
- ///
- ///
- ///
- /// A that contains the query
- /// parameters.
- ///
- ///
- /// An empty collection if not included.
- ///
- ///
- public override NameValueCollection QueryString {
- get {
- return _context.Request.QueryString;
- }
- }
-
- ///
- /// Gets the URI requested by the client.
- ///
- ///
- ///
- /// A that represents the URI parsed from the request.
- ///
- ///
- /// if the URI cannot be parsed.
- ///
- ///
- public override Uri RequestUri {
- get {
- return _context.Request.Url;
- }
- }
-
- ///
- /// Gets the value of the Sec-WebSocket-Key header included in
- /// the handshake request.
- ///
- ///
- ///
- /// A that represents the value of
- /// the Sec-WebSocket-Key header.
- ///
- ///
- /// The value is used to prove that the server received
- /// a valid WebSocket handshake request.
- ///
- ///
- /// if not included.
- ///
- ///
- public override string SecWebSocketKey {
- get {
- return _context.Request.Headers["Sec-WebSocket-Key"];
- }
- }
-
- ///
- /// Gets the names of the subprotocols from the Sec-WebSocket-Protocol
- /// header included in the handshake request.
- ///
- ///
- ///
- /// An
- /// instance.
- ///
- ///
- /// It provides an enumerator which supports the iteration over
- /// the collection of the names of the subprotocols.
- ///
- ///
- public override IEnumerable SecWebSocketProtocols {
- get {
- var val = _context.Request.Headers["Sec-WebSocket-Protocol"];
-
- if (val == null || val.Length == 0)
- yield break;
-
- foreach (var elm in val.Split (',')) {
- var protocol = elm.Trim ();
-
- if (protocol.Length == 0)
- continue;
-
- yield return protocol;
- }
- }
- }
-
- ///
- /// Gets the value of the Sec-WebSocket-Version header included in
- /// the handshake request.
- ///
- ///
- ///
- /// A that represents the WebSocket protocol
- /// version specified by the client.
- ///
- ///
- /// if not included.
- ///
- ///
- public override string SecWebSocketVersion {
- get {
- return _context.Request.Headers["Sec-WebSocket-Version"];
- }
- }
-
- ///
- /// Gets the endpoint to which the handshake request is sent.
- ///
- ///
- /// A that represents the server
- /// IP address and port number.
- ///
- public override System.Net.IPEndPoint ServerEndPoint {
- get {
- return _context.Request.LocalEndPoint;
- }
- }
-
- ///
- /// Gets the client information.
- ///
- ///
- ///
- /// A instance that represents identity,
- /// authentication, and security roles for the client.
- ///
- ///
- /// if the client is not authenticated.
- ///
- ///
- public override IPrincipal User {
- get {
- return _context.User;
- }
- }
-
- ///
- /// Gets the endpoint from which the handshake request is sent.
- ///
- ///
- /// A that represents the client
- /// IP address and port number.
- ///
- public override System.Net.IPEndPoint UserEndPoint {
- get {
- return _context.Request.RemoteEndPoint;
- }
- }
-
- ///
- /// Gets the WebSocket interface used for two-way communication between
- /// the client and server.
- ///
- ///
- /// A that represents the interface.
- ///
- public override WebSocket WebSocket {
- get {
- return _websocket;
- }
- }
-
- #endregion
-
- #region Internal Methods
-
- internal void Close ()
- {
- _context.Connection.Close (true);
- }
-
- internal void Close (HttpStatusCode code)
- {
- _context.Response.StatusCode = (int) code;
-
- _context.Response.Close ();
- }
-
- #endregion
-
- #region Public Methods
-
- ///
- /// Returns a string that represents the current instance.
- ///
- ///
- /// A that contains the request line and headers
- /// included in the handshake request.
- ///
- public override string ToString ()
- {
- return _context.Request.ToString ();
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Net/WebSockets/TcpListenerWebSocketContext.cs b/websocket-sharp/Net/WebSockets/TcpListenerWebSocketContext.cs
deleted file mode 100644
index 3e8d12777..000000000
--- a/websocket-sharp/Net/WebSockets/TcpListenerWebSocketContext.cs
+++ /dev/null
@@ -1,501 +0,0 @@
-#region License
-/*
- * TcpListenerWebSocketContext.cs
- *
- * The MIT License
- *
- * Copyright (c) 2012-2025 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-#region Contributors
-/*
- * Contributors:
- * - Liryna
- */
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Collections.Specialized;
-using System.IO;
-using System.Net.Security;
-using System.Net.Sockets;
-using System.Security.Principal;
-using System.Text;
-
-namespace WebSocketSharp.Net.WebSockets
-{
- ///
- /// Provides the access to the information in a WebSocket handshake request
- /// to a instance.
- ///
- internal class TcpListenerWebSocketContext : WebSocketContext
- {
- #region Private Fields
-
- private bool _isSecureConnection;
- private Logger _log;
- private NameValueCollection _queryString;
- private HttpRequest _request;
- private Uri _requestUri;
- private Stream _stream;
- private TcpClient _tcpClient;
- private IPrincipal _user;
- private WebSocket _websocket;
-
- #endregion
-
- #region Internal Constructors
-
- internal TcpListenerWebSocketContext (
- TcpClient tcpClient,
- string protocol,
- bool secure,
- ServerSslConfiguration sslConfig,
- Logger log
- )
- {
- _tcpClient = tcpClient;
- _log = log;
-
- var netStream = tcpClient.GetStream ();
-
- if (secure) {
- var sslStream = new SslStream (
- netStream,
- false,
- sslConfig.ClientCertificateValidationCallback
- );
-
- sslStream.AuthenticateAsServer (
- sslConfig.ServerCertificate,
- sslConfig.ClientCertificateRequired,
- sslConfig.EnabledSslProtocols,
- sslConfig.CheckCertificateRevocation
- );
-
- _isSecureConnection = true;
- _stream = sslStream;
- }
- else {
- _stream = netStream;
- }
-
- _request = HttpRequest.ReadRequest (_stream, 90000);
- _websocket = new WebSocket (this, protocol);
- }
-
- #endregion
-
- #region Internal Properties
-
- internal Logger Log {
- get {
- return _log;
- }
- }
-
- internal Socket Socket {
- get {
- return _tcpClient.Client;
- }
- }
-
- internal Stream Stream {
- get {
- return _stream;
- }
- }
-
- #endregion
-
- #region Public Properties
-
- ///
- /// Gets the HTTP cookies included in the handshake request.
- ///
- ///
- ///
- /// A that contains
- /// the cookies.
- ///
- ///
- /// An empty collection if not included.
- ///
- ///
- public override CookieCollection CookieCollection {
- get {
- return _request.Cookies;
- }
- }
-
- ///
- /// Gets the HTTP headers included in the handshake request.
- ///
- ///
- /// A that contains the headers.
- ///
- public override NameValueCollection Headers {
- get {
- return _request.Headers;
- }
- }
-
- ///
- /// Gets the value of the Host header included in the handshake request.
- ///
- ///
- ///
- /// A that represents the server host name requested
- /// by the client.
- ///
- ///
- /// It includes the port number if provided.
- ///
- ///
- public override string Host {
- get {
- return _request.Headers["Host"];
- }
- }
-
- ///
- /// Gets a value indicating whether the client is authenticated.
- ///
- ///
- /// true if the client is authenticated; otherwise, false.
- ///
- public override bool IsAuthenticated {
- get {
- return _user != null;
- }
- }
-
- ///
- /// Gets a value indicating whether the handshake request is sent from
- /// the local computer.
- ///
- ///
- /// true if the handshake request is sent from the same computer
- /// as the server; otherwise, false.
- ///
- public override bool IsLocal {
- get {
- return UserEndPoint.Address.IsLocal ();
- }
- }
-
- ///
- /// Gets a value indicating whether a secure connection is used to send
- /// the handshake request.
- ///
- ///
- /// true if the connection is secure; otherwise, false.
- ///
- public override bool IsSecureConnection {
- get {
- return _isSecureConnection;
- }
- }
-
- ///
- /// Gets a value indicating whether the request is a WebSocket handshake
- /// request.
- ///
- ///
- /// true if the request is a WebSocket handshake request; otherwise,
- /// false.
- ///
- public override bool IsWebSocketRequest {
- get {
- return _request.IsWebSocketRequest;
- }
- }
-
- ///
- /// Gets the value of the Origin header included in the handshake request.
- ///
- ///
- ///
- /// A that represents the value of the Origin header.
- ///
- ///
- /// if not included.
- ///
- ///
- public override string Origin {
- get {
- return _request.Headers["Origin"];
- }
- }
-
- ///
- /// Gets the query string included in the handshake request.
- ///
- ///
- ///
- /// A that contains the query
- /// parameters.
- ///
- ///
- /// An empty collection if not included.
- ///
- ///
- public override NameValueCollection QueryString {
- get {
- if (_queryString == null) {
- var uri = RequestUri;
- var query = uri != null ? uri.Query : null;
-
- _queryString = QueryStringCollection.Parse (query, Encoding.UTF8);
- }
-
- return _queryString;
- }
- }
-
- ///
- /// Gets the URI requested by the client.
- ///
- ///
- ///
- /// A that represents the URI parsed from the request.
- ///
- ///
- /// if the URI cannot be parsed.
- ///
- ///
- public override Uri RequestUri {
- get {
- if (_requestUri == null) {
- _requestUri = HttpUtility.CreateRequestUrl (
- _request.RequestTarget,
- _request.Headers["Host"],
- _request.IsWebSocketRequest,
- _isSecureConnection
- );
- }
-
- return _requestUri;
- }
- }
-
- ///
- /// Gets the value of the Sec-WebSocket-Key header included in
- /// the handshake request.
- ///
- ///
- ///
- /// A that represents the value of
- /// the Sec-WebSocket-Key header.
- ///
- ///
- /// The value is used to prove that the server received
- /// a valid WebSocket handshake request.
- ///
- ///
- /// if not included.
- ///
- ///
- public override string SecWebSocketKey {
- get {
- return _request.Headers["Sec-WebSocket-Key"];
- }
- }
-
- ///
- /// Gets the names of the subprotocols from the Sec-WebSocket-Protocol
- /// header included in the handshake request.
- ///
- ///
- ///
- /// An
- /// instance.
- ///
- ///
- /// It provides an enumerator which supports the iteration over
- /// the collection of the names of the subprotocols.
- ///
- ///
- public override IEnumerable SecWebSocketProtocols {
- get {
- var val = _request.Headers["Sec-WebSocket-Protocol"];
-
- if (val == null || val.Length == 0)
- yield break;
-
- foreach (var elm in val.Split (',')) {
- var protocol = elm.Trim ();
-
- if (protocol.Length == 0)
- continue;
-
- yield return protocol;
- }
- }
- }
-
- ///
- /// Gets the value of the Sec-WebSocket-Version header included in
- /// the handshake request.
- ///
- ///
- ///
- /// A that represents the WebSocket protocol
- /// version specified by the client.
- ///
- ///
- /// if not included.
- ///
- ///
- public override string SecWebSocketVersion {
- get {
- return _request.Headers["Sec-WebSocket-Version"];
- }
- }
-
- ///
- /// Gets the endpoint to which the handshake request is sent.
- ///
- ///
- /// A that represents the server
- /// IP address and port number.
- ///
- public override System.Net.IPEndPoint ServerEndPoint {
- get {
- return (System.Net.IPEndPoint) _tcpClient.Client.LocalEndPoint;
- }
- }
-
- ///
- /// Gets the client information.
- ///
- ///
- ///
- /// A instance that represents identity,
- /// authentication, and security roles for the client.
- ///
- ///
- /// if the client is not authenticated.
- ///
- ///
- public override IPrincipal User {
- get {
- return _user;
- }
- }
-
- ///
- /// Gets the endpoint from which the handshake request is sent.
- ///
- ///
- /// A that represents the client
- /// IP address and port number.
- ///
- public override System.Net.IPEndPoint UserEndPoint {
- get {
- return (System.Net.IPEndPoint) _tcpClient.Client.RemoteEndPoint;
- }
- }
-
- ///
- /// Gets the WebSocket interface used for two-way communication between
- /// the client and server.
- ///
- ///
- /// A that represents the interface.
- ///
- public override WebSocket WebSocket {
- get {
- return _websocket;
- }
- }
-
- #endregion
-
- #region Internal Methods
-
- internal void Close ()
- {
- _stream.Close ();
- _tcpClient.Close ();
- }
-
- internal void Close (HttpStatusCode code)
- {
- HttpResponse.CreateCloseResponse (code).WriteTo (_stream);
-
- _stream.Close ();
- _tcpClient.Close ();
- }
-
- internal void SendAuthenticationChallenge (string challenge)
- {
- HttpResponse.CreateUnauthorizedResponse (challenge).WriteTo (_stream);
-
- _request = HttpRequest.ReadRequest (_stream, 15000);
- }
-
- internal bool SetUser (
- AuthenticationSchemes scheme,
- string realm,
- Func credentialsFinder
- )
- {
- var user = HttpUtility.CreateUser (
- _request.Headers["Authorization"],
- scheme,
- realm,
- _request.HttpMethod,
- credentialsFinder
- );
-
- if (user == null)
- return false;
-
- if (!user.Identity.IsAuthenticated)
- return false;
-
- _user = user;
-
- return true;
- }
-
- #endregion
-
- #region Public Methods
-
- ///
- /// Returns a string that represents the current instance.
- ///
- ///
- /// A that contains the request line and headers
- /// included in the handshake request.
- ///
- public override string ToString ()
- {
- return _request.ToString ();
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Net/WebSockets/WebSocketContext.cs b/websocket-sharp/Net/WebSockets/WebSocketContext.cs
deleted file mode 100644
index 84841f5bd..000000000
--- a/websocket-sharp/Net/WebSockets/WebSocketContext.cs
+++ /dev/null
@@ -1,224 +0,0 @@
-#region License
-/*
- * WebSocketContext.cs
- *
- * The MIT License
- *
- * Copyright (c) 2012-2022 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Collections.Specialized;
-using System.Security.Principal;
-
-namespace WebSocketSharp.Net.WebSockets
-{
- ///
- /// Exposes the access to the information in a WebSocket handshake request.
- ///
- ///
- /// This class is an abstract class.
- ///
- public abstract class WebSocketContext
- {
- #region Protected Constructors
-
- ///
- /// Initializes a new instance of the class.
- ///
- protected WebSocketContext ()
- {
- }
-
- #endregion
-
- #region Public Properties
-
- ///
- /// Gets the HTTP cookies included in the handshake request.
- ///
- ///
- /// A that contains
- /// the cookies.
- ///
- public abstract CookieCollection CookieCollection { get; }
-
- ///
- /// Gets the HTTP headers included in the handshake request.
- ///
- ///
- /// A that contains the headers.
- ///
- public abstract NameValueCollection Headers { get; }
-
- ///
- /// Gets the value of the Host header included in the handshake request.
- ///
- ///
- /// A that represents the server host name requested
- /// by the client.
- ///
- public abstract string Host { get; }
-
- ///
- /// Gets a value indicating whether the client is authenticated.
- ///
- ///
- /// true if the client is authenticated; otherwise, false.
- ///
- public abstract bool IsAuthenticated { get; }
-
- ///
- /// Gets a value indicating whether the handshake request is sent from
- /// the local computer.
- ///
- ///
- /// true if the handshake request is sent from the same computer
- /// as the server; otherwise, false.
- ///
- public abstract bool IsLocal { get; }
-
- ///
- /// Gets a value indicating whether a secure connection is used to send
- /// the handshake request.
- ///
- ///
- /// true if the connection is secure; otherwise, false.
- ///
- public abstract bool IsSecureConnection { get; }
-
- ///
- /// Gets a value indicating whether the request is a WebSocket handshake
- /// request.
- ///
- ///
- /// true if the request is a WebSocket handshake request; otherwise,
- /// false.
- ///
- public abstract bool IsWebSocketRequest { get; }
-
- ///
- /// Gets the value of the Origin header included in the handshake request.
- ///
- ///
- /// A that represents the value of the Origin header.
- ///
- public abstract string Origin { get; }
-
- ///
- /// Gets the query string included in the handshake request.
- ///
- ///
- /// A that contains the query parameters.
- ///
- public abstract NameValueCollection QueryString { get; }
-
- ///
- /// Gets the URI requested by the client.
- ///
- ///
- /// A that represents the URI parsed from the request.
- ///
- public abstract Uri RequestUri { get; }
-
- ///
- /// Gets the value of the Sec-WebSocket-Key header included in
- /// the handshake request.
- ///
- ///
- ///
- /// A that represents the value of
- /// the Sec-WebSocket-Key header.
- ///
- ///
- /// The value is used to prove that the server received
- /// a valid WebSocket handshake request.
- ///
- ///
- public abstract string SecWebSocketKey { get; }
-
- ///
- /// Gets the names of the subprotocols from the Sec-WebSocket-Protocol
- /// header included in the handshake request.
- ///
- ///
- ///
- /// An
- /// instance.
- ///
- ///
- /// It provides an enumerator which supports the iteration over
- /// the collection of the names of the subprotocols.
- ///
- ///
- public abstract IEnumerable SecWebSocketProtocols { get; }
-
- ///
- /// Gets the value of the Sec-WebSocket-Version header included in
- /// the handshake request.
- ///
- ///
- /// A that represents the WebSocket protocol
- /// version specified by the client.
- ///
- public abstract string SecWebSocketVersion { get; }
-
- ///
- /// Gets the endpoint to which the handshake request is sent.
- ///
- ///
- /// A that represents the server
- /// IP address and port number.
- ///
- public abstract System.Net.IPEndPoint ServerEndPoint { get; }
-
- ///
- /// Gets the client information.
- ///
- ///
- /// A instance that represents identity,
- /// authentication, and security roles for the client.
- ///
- public abstract IPrincipal User { get; }
-
- ///
- /// Gets the endpoint from which the handshake request is sent.
- ///
- ///
- /// A that represents the client
- /// IP address and port number.
- ///
- public abstract System.Net.IPEndPoint UserEndPoint { get; }
-
- ///
- /// Gets the WebSocket interface used for two-way communication between
- /// the client and server.
- ///
- ///
- /// A that represents the interface.
- ///
- public abstract WebSocket WebSocket { get; }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Opcode.cs b/websocket-sharp/Opcode.cs
deleted file mode 100644
index 06da1b5e1..000000000
--- a/websocket-sharp/Opcode.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-#region License
-/*
- * Opcode.cs
- *
- * The MIT License
- *
- * Copyright (c) 2012-2025 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-using System;
-
-namespace WebSocketSharp
-{
- ///
- /// Indicates the WebSocket frame type.
- ///
- ///
- /// The values of this enumeration are defined in
- ///
- /// Section 5.2 of RFC 6455.
- ///
- internal enum Opcode
- {
- ///
- /// Equivalent to numeric value 0. Indicates continuation frame.
- ///
- Cont = 0x0,
- ///
- /// Equivalent to numeric value 1. Indicates text frame.
- ///
- Text = 0x1,
- ///
- /// Equivalent to numeric value 2. Indicates binary frame.
- ///
- Binary = 0x2,
- ///
- /// Equivalent to numeric value 8. Indicates connection close frame.
- ///
- Close = 0x8,
- ///
- /// Equivalent to numeric value 9. Indicates ping frame.
- ///
- Ping = 0x9,
- ///
- /// Equivalent to numeric value 10. Indicates pong frame.
- ///
- Pong = 0xa
- }
-}
diff --git a/websocket-sharp/PayloadData.cs b/websocket-sharp/PayloadData.cs
deleted file mode 100644
index e01fcd27e..000000000
--- a/websocket-sharp/PayloadData.cs
+++ /dev/null
@@ -1,212 +0,0 @@
-#region License
-/*
- * PayloadData.cs
- *
- * The MIT License
- *
- * Copyright (c) 2012-2025 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-
-namespace WebSocketSharp
-{
- internal class PayloadData : IEnumerable
- {
- #region Private Fields
-
- private byte[] _data;
- private static readonly byte[] _emptyBytes;
- private long _extDataLength;
- private long _length;
-
- #endregion
-
- #region Public Fields
-
- ///
- /// Represents the empty payload data.
- ///
- public static readonly PayloadData Empty;
-
- ///
- /// Represents the allowable max length of payload data.
- ///
- ///
- ///
- /// A is thrown when the length of
- /// incoming payload data is greater than the value of this field.
- ///
- ///
- /// If you would like to change the value of this field, it must be
- /// a number between and
- /// inclusive.
- ///
- ///
- public static readonly ulong MaxLength;
-
- #endregion
-
- #region Static Constructor
-
- static PayloadData ()
- {
- _emptyBytes = new byte[0];
-
- Empty = new PayloadData (_emptyBytes, 0);
- MaxLength = Int64.MaxValue;
- }
-
- #endregion
-
- #region Internal Constructors
-
- internal PayloadData (byte[] data)
- : this (data, data.LongLength)
- {
- }
-
- internal PayloadData (byte[] data, long length)
- {
- _data = data;
- _length = length;
- }
-
- internal PayloadData (ushort code, string reason)
- {
- _data = code.Append (reason);
- _length = _data.LongLength;
- }
-
- #endregion
-
- #region Internal Properties
-
- internal ushort Code {
- get {
- return _length >= 2
- ? _data.SubArray (0, 2).ToUInt16 (ByteOrder.Big)
- : (ushort) 1005;
- }
- }
-
- internal long ExtensionDataLength {
- get {
- return _extDataLength;
- }
-
- set {
- _extDataLength = value;
- }
- }
-
- internal bool HasReservedCode {
- get {
- return _length >= 2 && Code.IsReservedStatusCode ();
- }
- }
-
- internal string Reason {
- get {
- if (_length <= 2)
- return String.Empty;
-
- var bytes = _data.SubArray (2, _length - 2);
-
- string reason;
-
- return bytes.TryGetUTF8DecodedString (out reason)
- ? reason
- : String.Empty;
- }
- }
-
- #endregion
-
- #region Public Properties
-
- public byte[] ApplicationData {
- get {
- return _extDataLength > 0
- ? _data.SubArray (_extDataLength, _length - _extDataLength)
- : _data;
- }
- }
-
- public byte[] ExtensionData {
- get {
- return _extDataLength > 0
- ? _data.SubArray (0, _extDataLength)
- : _emptyBytes;
- }
- }
-
- public ulong Length {
- get {
- return (ulong) _length;
- }
- }
-
- #endregion
-
- #region Internal Methods
-
- internal void Mask (byte[] key)
- {
- for (long i = 0; i < _length; i++)
- _data[i] = (byte) (_data[i] ^ key[i % 4]);
- }
-
- #endregion
-
- #region Public Methods
-
- public IEnumerator GetEnumerator ()
- {
- foreach (var b in _data)
- yield return b;
- }
-
- public byte[] ToArray ()
- {
- return _data;
- }
-
- public override string ToString ()
- {
- return BitConverter.ToString (_data);
- }
-
- #endregion
-
- #region Explicit Interface Implementations
-
- IEnumerator IEnumerable.GetEnumerator ()
- {
- return GetEnumerator ();
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Rsv.cs b/websocket-sharp/Rsv.cs
deleted file mode 100644
index c2a4dea7a..000000000
--- a/websocket-sharp/Rsv.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-#region License
-/*
- * Rsv.cs
- *
- * The MIT License
- *
- * Copyright (c) 2012-2025 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-using System;
-
-namespace WebSocketSharp
-{
- ///
- /// Indicates whether each RSV (RSV1, RSV2, and RSV3) of a WebSocket
- /// frame is non-zero.
- ///
- ///
- /// The values of this enumeration are defined in
- ///
- /// Section 5.2 of RFC 6455.
- ///
- internal enum Rsv
- {
- ///
- /// Equivalent to numeric value 0. Indicates zero.
- ///
- Off = 0x0,
- ///
- /// Equivalent to numeric value 1. Indicates non-zero.
- ///
- On = 0x1
- }
-}
diff --git a/websocket-sharp/Server/HttpRequestEventArgs.cs b/websocket-sharp/Server/HttpRequestEventArgs.cs
deleted file mode 100644
index 45af3c1ee..000000000
--- a/websocket-sharp/Server/HttpRequestEventArgs.cs
+++ /dev/null
@@ -1,266 +0,0 @@
-#region License
-/*
- * HttpRequestEventArgs.cs
- *
- * The MIT License
- *
- * Copyright (c) 2012-2024 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-using System;
-using System.IO;
-using System.Security.Principal;
-using System.Text;
-using WebSocketSharp.Net;
-
-namespace WebSocketSharp.Server
-{
- ///
- /// Represents the event data for the HTTP request events of the
- /// class.
- ///
- ///
- ///
- /// An HTTP request event occurs when the
- /// instance receives an HTTP request.
- ///
- ///
- /// You should access the property if you would
- /// like to get the request data sent from a client.
- ///
- ///
- /// And you should access the property if you
- /// would like to get the response data to return to the client.
- ///
- ///
- public class HttpRequestEventArgs : EventArgs
- {
- #region Private Fields
-
- private HttpListenerContext _context;
- private string _docRootPath;
-
- #endregion
-
- #region Internal Constructors
-
- internal HttpRequestEventArgs (
- HttpListenerContext context,
- string documentRootPath
- )
- {
- _context = context;
- _docRootPath = documentRootPath;
- }
-
- #endregion
-
- #region Public Properties
-
- ///
- /// Gets the request data sent from a client.
- ///
- ///
- /// A that provides the methods and
- /// properties for the request data.
- ///
- public HttpListenerRequest Request {
- get {
- return _context.Request;
- }
- }
-
- ///
- /// Gets the response data to return to the client.
- ///
- ///
- /// A that provides the methods and
- /// properties for the response data.
- ///
- public HttpListenerResponse Response {
- get {
- return _context.Response;
- }
- }
-
- ///
- /// Gets the information for the client.
- ///
- ///
- ///
- /// A instance that represents identity,
- /// authentication scheme, and security roles for the client.
- ///
- ///
- /// if the client is not authenticated.
- ///
- ///
- public IPrincipal User {
- get {
- return _context.User;
- }
- }
-
- #endregion
-
- #region Private Methods
-
- private string createFilePath (string childPath)
- {
- childPath = childPath.TrimStart ('/', '\\');
-
- return new StringBuilder (_docRootPath, 32)
- .AppendFormat ("/{0}", childPath)
- .ToString ()
- .Replace ('\\', '/');
- }
-
- private static bool tryReadFile (string path, out byte[] contents)
- {
- contents = null;
-
- if (!File.Exists (path))
- return false;
-
- try {
- contents = File.ReadAllBytes (path);
- }
- catch {
- return false;
- }
-
- return true;
- }
-
- #endregion
-
- #region Public Methods
-
- ///
- /// Reads the specified file from the document folder of the
- /// class.
- ///
- ///
- ///
- /// An array of that receives the contents of
- /// the file.
- ///
- ///
- /// if the read has failed.
- ///
- ///
- ///
- /// A that specifies a virtual path to find
- /// the file from the document folder.
- ///
- ///
- ///
- /// is an empty string.
- ///
- ///
- /// -or-
- ///
- ///
- /// contains "..".
- ///
- ///
- ///
- /// is .
- ///
- public byte[] ReadFile (string path)
- {
- if (path == null)
- throw new ArgumentNullException ("path");
-
- if (path.Length == 0)
- throw new ArgumentException ("An empty string.", "path");
-
- if (path.Contains ("..")) {
- var msg = "It contains \"..\".";
-
- throw new ArgumentException (msg, "path");
- }
-
- path = createFilePath (path);
- byte[] contents;
-
- tryReadFile (path, out contents);
-
- return contents;
- }
-
- ///
- /// Tries to read the specified file from the document folder of
- /// the class.
- ///
- ///
- /// true if the try has succeeded; otherwise, false.
- ///
- ///
- /// A that specifies a virtual path to find
- /// the file from the document folder.
- ///
- ///
- ///
- /// When this method returns, an array of that
- /// receives the contents of the file.
- ///
- ///
- /// if the read has failed.
- ///
- ///
- ///
- ///
- /// is an empty string.
- ///
- ///
- /// -or-
- ///
- ///
- /// contains "..".
- ///
- ///
- ///
- /// is .
- ///
- public bool TryReadFile (string path, out byte[] contents)
- {
- if (path == null)
- throw new ArgumentNullException ("path");
-
- if (path.Length == 0)
- throw new ArgumentException ("An empty string.", "path");
-
- if (path.Contains ("..")) {
- var msg = "It contains \"..\".";
-
- throw new ArgumentException (msg, "path");
- }
-
- path = createFilePath (path);
-
- return tryReadFile (path, out contents);
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Server/HttpServer.cs b/websocket-sharp/Server/HttpServer.cs
deleted file mode 100644
index d95c162e4..000000000
--- a/websocket-sharp/Server/HttpServer.cs
+++ /dev/null
@@ -1,1334 +0,0 @@
-#region License
-/*
- * HttpServer.cs
- *
- * The MIT License
- *
- * Copyright (c) 2012-2024 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-#region Contributors
-/*
- * Contributors:
- * - Juan Manuel Lallana
- * - Liryna
- * - Rohan Singh
- */
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Net.Sockets;
-using System.Security.Cryptography.X509Certificates;
-using System.Security.Principal;
-using System.Text;
-using System.Threading;
-using WebSocketSharp.Net;
-using WebSocketSharp.Net.WebSockets;
-
-namespace WebSocketSharp.Server
-{
- ///
- /// Provides a simple HTTP server.
- ///
- ///
- ///
- /// The server supports HTTP/1.1 version request and response.
- ///
- ///
- /// Also the server allows to accept WebSocket handshake requests.
- ///
- ///
- /// This class can provide multiple WebSocket services.
- ///
- ///
- public class HttpServer
- {
- #region Private Fields
-
- private System.Net.IPAddress _address;
- private string _docRootPath;
- private bool _isSecure;
- private HttpListener _listener;
- private Logger _log;
- private int _port;
- private Thread _receiveThread;
- private WebSocketServiceManager _services;
- private volatile ServerState _state;
- private object _sync;
-
- #endregion
-
- #region Public Constructors
-
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- /// The new instance listens for incoming requests on
- /// and port 80.
- ///
- public HttpServer ()
- {
- init ("*", System.Net.IPAddress.Any, 80, false);
- }
-
- ///
- /// Initializes a new instance of the class with
- /// the specified port.
- ///
- ///
- ///
- /// The new instance listens for incoming requests on
- /// and .
- ///
- ///
- /// It provides secure connections if is 443.
- ///
- ///
- ///
- /// An that specifies the number of the port on which
- /// to listen.
- ///
- ///
- /// is less than 1 or greater than 65535.
- ///
- public HttpServer (int port)
- : this (port, port == 443)
- {
- }
-
- ///
- /// Initializes a new instance of the class with
- /// the specified URL.
- ///
- ///
- ///
- /// The new instance listens for incoming requests on the IP address and
- /// port of .
- ///
- ///
- /// Either port 80 or 443 is used if includes
- /// no port. Port 443 is used if the scheme of
- /// is https; otherwise, port 80 is used.
- ///
- ///
- /// The new instance provides secure connections if the scheme of
- /// is https.
- ///
- ///
- ///
- /// A that specifies the HTTP URL of the server.
- ///
- ///
- ///
- /// is an empty string.
- ///
- ///
- /// -or-
- ///
- ///
- /// is invalid.
- ///
- ///
- ///
- /// is .
- ///
- public HttpServer (string url)
- {
- if (url == null)
- throw new ArgumentNullException ("url");
-
- if (url.Length == 0)
- throw new ArgumentException ("An empty string.", "url");
-
- Uri uri;
- string msg;
-
- if (!tryCreateUri (url, out uri, out msg))
- throw new ArgumentException (msg, "url");
-
- var host = uri.GetDnsSafeHost (true);
- var addr = host.ToIPAddress ();
-
- if (addr == null) {
- msg = "The host part could not be converted to an IP address.";
-
- throw new ArgumentException (msg, "url");
- }
-
- if (!addr.IsLocal ()) {
- msg = "The IP address of the host is not a local IP address.";
-
- throw new ArgumentException (msg, "url");
- }
-
- init (host, addr, uri.Port, uri.Scheme == "https");
- }
-
- ///
- /// Initializes a new instance of the class with
- /// the specified port and boolean if secure or not.
- ///
- ///
- /// The new instance listens for incoming requests on
- /// and .
- ///
- ///
- /// An that specifies the number of the port on which
- /// to listen.
- ///
- ///
- /// A : true if the new instance provides
- /// secure connections; otherwise, false.
- ///
- ///
- /// is less than 1 or greater than 65535.
- ///
- public HttpServer (int port, bool secure)
- {
- if (!port.IsPortNumber ()) {
- var msg = "Less than 1 or greater than 65535.";
-
- throw new ArgumentOutOfRangeException ("port", msg);
- }
-
- init ("*", System.Net.IPAddress.Any, port, secure);
- }
-
- ///
- /// Initializes a new instance of the class with
- /// the specified IP address and port.
- ///
- ///
- ///
- /// The new instance listens for incoming requests on
- /// and .
- ///
- ///
- /// It provides secure connections if is 443.
- ///
- ///
- ///
- /// A that specifies the local IP
- /// address on which to listen.
- ///
- ///
- /// An that specifies the number of the port on which
- /// to listen.
- ///
- ///
- /// is not a local IP address.
- ///
- ///
- /// is .
- ///
- ///
- /// is less than 1 or greater than 65535.
- ///
- public HttpServer (System.Net.IPAddress address, int port)
- : this (address, port, port == 443)
- {
- }
-
- ///
- /// Initializes a new instance of the class with
- /// the specified IP address, port, and boolean if secure or not.
- ///
- ///
- /// The new instance listens for incoming requests on
- /// and .
- ///
- ///
- /// A that specifies the local IP
- /// address on which to listen.
- ///
- ///
- /// An that specifies the number of the port on which
- /// to listen.
- ///
- ///
- /// A : true if the new instance provides
- /// secure connections; otherwise, false.
- ///
- ///
- /// is not a local IP address.
- ///
- ///
- /// is .
- ///
- ///
- /// is less than 1 or greater than 65535.
- ///
- public HttpServer (System.Net.IPAddress address, int port, bool secure)
- {
- if (address == null)
- throw new ArgumentNullException ("address");
-
- if (!address.IsLocal ()) {
- var msg = "Not a local IP address.";
-
- throw new ArgumentException (msg, "address");
- }
-
- if (!port.IsPortNumber ()) {
- var msg = "Less than 1 or greater than 65535.";
-
- throw new ArgumentOutOfRangeException ("port", msg);
- }
-
- init (address.ToString (true), address, port, secure);
- }
-
- #endregion
-
- #region Public Properties
-
- ///
- /// Gets the IP address of the server.
- ///
- ///
- /// A that represents the local IP
- /// address on which to listen for incoming requests.
- ///
- public System.Net.IPAddress Address {
- get {
- return _address;
- }
- }
-
- ///
- /// Gets or sets the scheme used to authenticate the clients.
- ///
- ///
- /// The set operation works if the current state of the server is
- /// Ready or Stop.
- ///
- ///
- ///
- /// One of the
- /// enum values.
- ///
- ///
- /// It represents the scheme used to authenticate the clients.
- ///
- ///
- /// The default value is
- /// .
- ///
- ///
- public AuthenticationSchemes AuthenticationSchemes {
- get {
- return _listener.AuthenticationSchemes;
- }
-
- set {
- lock (_sync) {
- if (!canSet ())
- return;
-
- _listener.AuthenticationSchemes = value;
- }
- }
- }
-
- ///
- /// Gets or sets the path to the document folder of the server.
- ///
- ///
- /// The set operation works if the current state of the server is
- /// Ready or Stop.
- ///
- ///
- ///
- /// A that represents a path to the folder
- /// from which to find the requested file.
- ///
- ///
- /// / or \ is trimmed from the end of the value if present.
- ///
- ///
- /// The default value is "./Public".
- ///
- ///
- ///
- ///
- /// The value specified for a set operation is an empty string.
- ///
- ///
- /// -or-
- ///
- ///
- /// The value specified for a set operation is an absolute root.
- ///
- ///
- /// -or-
- ///
- ///
- /// The value specified for a set operation is an invalid path string.
- ///
- ///
- ///
- /// The value specified for a set operation is .
- ///
- public string DocumentRootPath {
- get {
- return _docRootPath;
- }
-
- set {
- if (value == null)
- throw new ArgumentNullException ("value");
-
- if (value.Length == 0)
- throw new ArgumentException ("An empty string.", "value");
-
- value = value.TrimSlashOrBackslashFromEnd ();
-
- if (value == "/")
- throw new ArgumentException ("An absolute root.", "value");
-
- if (value == "\\")
- throw new ArgumentException ("An absolute root.", "value");
-
- if (value.Length == 2 && value[1] == ':')
- throw new ArgumentException ("An absolute root.", "value");
-
- string full = null;
-
- try {
- full = Path.GetFullPath (value);
- }
- catch (Exception ex) {
- throw new ArgumentException ("An invalid path string.", "value", ex);
- }
-
- if (full == "/")
- throw new ArgumentException ("An absolute root.", "value");
-
- full = full.TrimSlashOrBackslashFromEnd ();
-
- if (full.Length == 2 && full[1] == ':')
- throw new ArgumentException ("An absolute root.", "value");
-
- lock (_sync) {
- if (!canSet ())
- return;
-
- _docRootPath = value;
- }
- }
- }
-
- ///
- /// Gets a value indicating whether the server has started.
- ///
- ///
- /// true if the server has started; otherwise, false.
- ///
- public bool IsListening {
- get {
- return _state == ServerState.Start;
- }
- }
-
- ///
- /// Gets a value indicating whether the server provides secure connections.
- ///
- ///
- /// true if the server provides secure connections; otherwise,
- /// false.
- ///
- public bool IsSecure {
- get {
- return _isSecure;
- }
- }
-
- ///
- /// Gets or sets a value indicating whether the server cleans up
- /// the inactive sessions periodically.
- ///
- ///
- ///
- /// true if the server cleans up the inactive sessions
- /// every 60 seconds; otherwise, false.
- ///
- ///
- /// The default value is false.
- ///
- ///
- ///
- /// The set operation is not available when the current state of
- /// the server is neither Ready nor Stop.
- ///
- public bool KeepClean {
- get {
- return _services.KeepClean;
- }
-
- set {
- _services.KeepClean = value;
- }
- }
-
- ///
- /// Gets the logging function for the server.
- ///
- ///
- /// The default logging level is .
- ///
- ///
- /// A that provides the logging function.
- ///
- public Logger Log {
- get {
- return _log;
- }
- }
-
- ///
- /// Gets the port of the server.
- ///
- ///
- /// An that represents the number of the port on which
- /// to listen for incoming requests.
- ///
- public int Port {
- get {
- return _port;
- }
- }
-
- ///
- /// Gets or sets the name of the realm associated with the server.
- ///
- ///
- /// The set operation works if the current state of the server is
- /// Ready or Stop.
- ///
- ///
- ///
- /// A that represents the name of the realm.
- ///
- ///
- /// "SECRET AREA" is used as the name of the realm if the value is
- /// or an empty string.
- ///
- ///
- /// The default value is .
- ///
- ///
- public string Realm {
- get {
- return _listener.Realm;
- }
-
- set {
- lock (_sync) {
- if (!canSet ())
- return;
-
- _listener.Realm = value;
- }
- }
- }
-
- ///
- /// Gets or sets a value indicating whether the server is allowed to
- /// be bound to an address that is already in use.
- ///
- ///
- ///
- /// You should set this property to true if you would like to
- /// resolve to wait for socket in TIME_WAIT state.
- ///
- ///
- /// The set operation works if the current state of the server is
- /// Ready or Stop.
- ///
- ///
- ///
- ///
- /// true if the server is allowed to be bound to an address
- /// that is already in use; otherwise, false.
- ///
- ///
- /// The default value is false.
- ///
- ///
- public bool ReuseAddress {
- get {
- return _listener.ReuseAddress;
- }
-
- set {
- lock (_sync) {
- if (!canSet ())
- return;
-
- _listener.ReuseAddress = value;
- }
- }
- }
-
- ///
- /// Gets the configuration for secure connection.
- ///
- ///
- /// The configuration is used when the server attempts to start,
- /// so it must be configured before the start method is called.
- ///
- ///
- /// A that represents the
- /// configuration used to provide secure connections.
- ///
- ///
- /// The server does not provide secure connections.
- ///
- public ServerSslConfiguration SslConfiguration {
- get {
- if (!_isSecure) {
- var msg = "The server does not provide secure connections.";
-
- throw new InvalidOperationException (msg);
- }
-
- return _listener.SslConfiguration;
- }
- }
-
- ///
- /// Gets or sets the delegate called to find the credentials for
- /// an identity used to authenticate a client.
- ///
- ///
- /// The set operation works if the current state of the server is
- /// Ready or Stop.
- ///
- ///
- ///
- /// A
- /// delegate.
- ///
- ///
- /// It represents the delegate called when the server finds
- /// the credentials used to authenticate a client.
- ///
- ///
- /// It must return if the credentials
- /// are not found.
- ///
- ///
- /// if not necessary.
- ///
- ///
- /// The default value is .
- ///
- ///
- public Func UserCredentialsFinder {
- get {
- return _listener.UserCredentialsFinder;
- }
-
- set {
- lock (_sync) {
- if (!canSet ())
- return;
-
- _listener.UserCredentialsFinder = value;
- }
- }
- }
-
- ///
- /// Gets or sets the time to wait for the response to the WebSocket
- /// Ping or Close.
- ///
- ///
- ///
- /// A that represents the time to wait for
- /// the response.
- ///
- ///
- /// The default value is the same as 1 second.
- ///
- ///
- ///
- /// The value specified for a set operation is zero or less.
- ///
- ///
- /// The set operation is not available when the current state of
- /// the server is neither Ready nor Stop.
- ///
- public TimeSpan WaitTime {
- get {
- return _services.WaitTime;
- }
-
- set {
- _services.WaitTime = value;
- }
- }
-
- ///
- /// Gets the management function for the WebSocket services provided by
- /// the server.
- ///
- ///
- /// A that manages the WebSocket
- /// services provided by the server.
- ///
- public WebSocketServiceManager WebSocketServices {
- get {
- return _services;
- }
- }
-
- #endregion
-
- #region Public Events
-
- ///
- /// Occurs when the server receives an HTTP CONNECT request.
- ///
- public event EventHandler OnConnect;
-
- ///
- /// Occurs when the server receives an HTTP DELETE request.
- ///
- public event EventHandler OnDelete;
-
- ///
- /// Occurs when the server receives an HTTP GET request.
- ///
- public event EventHandler OnGet;
-
- ///
- /// Occurs when the server receives an HTTP HEAD request.
- ///
- public event EventHandler OnHead;
-
- ///
- /// Occurs when the server receives an HTTP OPTIONS request.
- ///
- public event EventHandler OnOptions;
-
- ///
- /// Occurs when the server receives an HTTP POST request.
- ///
- public event EventHandler OnPost;
-
- ///
- /// Occurs when the server receives an HTTP PUT request.
- ///
- public event EventHandler OnPut;
-
- ///
- /// Occurs when the server receives an HTTP TRACE request.
- ///
- public event EventHandler OnTrace;
-
- #endregion
-
- #region Private Methods
-
- private void abort ()
- {
- lock (_sync) {
- if (_state != ServerState.Start)
- return;
-
- _state = ServerState.ShuttingDown;
- }
-
- try {
- _services.Stop (1006, String.Empty);
- }
- catch (Exception ex) {
- _log.Fatal (ex.Message);
- _log.Debug (ex.ToString ());
- }
-
- try {
- _listener.Abort ();
- }
- catch (Exception ex) {
- _log.Fatal (ex.Message);
- _log.Debug (ex.ToString ());
- }
-
- _state = ServerState.Stop;
- }
-
- private bool canSet ()
- {
- return _state == ServerState.Ready || _state == ServerState.Stop;
- }
-
- private bool checkCertificate (out string message)
- {
- message = null;
-
- var byUser = _listener.SslConfiguration.ServerCertificate != null;
-
- var path = _listener.CertificateFolderPath;
- var withPort = EndPointListener.CertificateExists (_port, path);
-
- var either = byUser || withPort;
-
- if (!either) {
- message = "There is no server certificate for secure connection.";
-
- return false;
- }
-
- var both = byUser && withPort;
-
- if (both) {
- var msg = "The server certificate associated with the port is used.";
-
- _log.Warn (msg);
- }
-
- return true;
- }
-
- private static HttpListener createListener (
- string hostname,
- int port,
- bool secure
- )
- {
- var ret = new HttpListener ();
-
- var fmt = "{0}://{1}:{2}/";
- var schm = secure ? "https" : "http";
- var pref = String.Format (fmt, schm, hostname, port);
-
- ret.Prefixes.Add (pref);
-
- return ret;
- }
-
- private void init (
- string hostname,
- System.Net.IPAddress address,
- int port,
- bool secure
- )
- {
- _address = address;
- _port = port;
- _isSecure = secure;
-
- _docRootPath = "./Public";
- _listener = createListener (hostname, port, secure);
- _log = _listener.Log;
- _services = new WebSocketServiceManager (_log);
- _sync = new object ();
- }
-
- private void processRequest (HttpListenerContext context)
- {
- var method = context.Request.HttpMethod;
- var evt = method == "GET"
- ? OnGet
- : method == "HEAD"
- ? OnHead
- : method == "POST"
- ? OnPost
- : method == "PUT"
- ? OnPut
- : method == "DELETE"
- ? OnDelete
- : method == "CONNECT"
- ? OnConnect
- : method == "OPTIONS"
- ? OnOptions
- : method == "TRACE"
- ? OnTrace
- : null;
-
- if (evt == null) {
- context.ErrorStatusCode = 501;
-
- context.SendError ();
-
- return;
- }
-
- var e = new HttpRequestEventArgs (context, _docRootPath);
-
- evt (this, e);
-
- context.Response.Close ();
- }
-
- private void processRequest (HttpListenerWebSocketContext context)
- {
- var uri = context.RequestUri;
-
- if (uri == null) {
- context.Close (HttpStatusCode.BadRequest);
-
- return;
- }
-
- var path = uri.AbsolutePath;
-
- if (path.IndexOfAny (new[] { '%', '+' }) > -1)
- path = HttpUtility.UrlDecode (path, Encoding.UTF8);
-
- WebSocketServiceHost host;
-
- if (!_services.InternalTryGetServiceHost (path, out host)) {
- context.Close (HttpStatusCode.NotImplemented);
-
- return;
- }
-
- host.StartSession (context);
- }
-
- private void receiveRequest ()
- {
- while (true) {
- HttpListenerContext ctx = null;
-
- try {
- ctx = _listener.GetContext ();
-
- ThreadPool.QueueUserWorkItem (
- state => {
- try {
- if (ctx.Request.IsUpgradeRequest ("websocket")) {
- processRequest (ctx.GetWebSocketContext (null));
-
- return;
- }
-
- processRequest (ctx);
- }
- catch (Exception ex) {
- _log.Error (ex.Message);
- _log.Debug (ex.ToString ());
-
- ctx.Connection.Close (true);
- }
- }
- );
- }
- catch (HttpListenerException ex) {
- if (_state == ServerState.ShuttingDown)
- return;
-
- _log.Fatal (ex.Message);
- _log.Debug (ex.ToString ());
-
- break;
- }
- catch (InvalidOperationException ex) {
- if (_state == ServerState.ShuttingDown)
- return;
-
- _log.Fatal (ex.Message);
- _log.Debug (ex.ToString ());
-
- break;
- }
- catch (Exception ex) {
- _log.Fatal (ex.Message);
- _log.Debug (ex.ToString ());
-
- if (ctx != null)
- ctx.Connection.Close (true);
-
- if (_state == ServerState.ShuttingDown)
- return;
-
- break;
- }
- }
-
- abort ();
- }
-
- private void start ()
- {
- lock (_sync) {
- if (_state == ServerState.Start || _state == ServerState.ShuttingDown)
- return;
-
- if (_isSecure) {
- string msg;
-
- if (!checkCertificate (out msg))
- throw new InvalidOperationException (msg);
- }
-
- _services.Start ();
-
- try {
- startReceiving ();
- }
- catch {
- _services.Stop (1011, String.Empty);
-
- throw;
- }
-
- _state = ServerState.Start;
- }
- }
-
- private void startReceiving ()
- {
- try {
- _listener.Start ();
- }
- catch (Exception ex) {
- var msg = "The underlying listener has failed to start.";
-
- throw new InvalidOperationException (msg, ex);
- }
-
- var receiver = new ThreadStart (receiveRequest);
- _receiveThread = new Thread (receiver);
- _receiveThread.IsBackground = true;
-
- _receiveThread.Start ();
- }
-
- private void stop (ushort code, string reason)
- {
- lock (_sync) {
- if (_state != ServerState.Start)
- return;
-
- _state = ServerState.ShuttingDown;
- }
-
- try {
- _services.Stop (code, reason);
- }
- catch (Exception ex) {
- _log.Fatal (ex.Message);
- _log.Debug (ex.ToString ());
- }
-
- try {
- var timeout = 5000;
-
- stopReceiving (timeout);
- }
- catch (Exception ex) {
- _log.Fatal (ex.Message);
- _log.Debug (ex.ToString ());
- }
-
- _state = ServerState.Stop;
- }
-
- private void stopReceiving (int millisecondsTimeout)
- {
- _listener.Stop ();
- _receiveThread.Join (millisecondsTimeout);
- }
-
- private static bool tryCreateUri (
- string uriString,
- out Uri result,
- out string message
- )
- {
- result = null;
- message = null;
-
- var uri = uriString.ToUri ();
-
- if (uri == null) {
- message = "An invalid URI string.";
-
- return false;
- }
-
- if (!uri.IsAbsoluteUri) {
- message = "A relative URI.";
-
- return false;
- }
-
- var schm = uri.Scheme;
- var isHttpSchm = schm == "http" || schm == "https";
-
- if (!isHttpSchm) {
- message = "The scheme part is not 'http' or 'https'.";
-
- return false;
- }
-
- if (uri.PathAndQuery != "/") {
- message = "It includes either or both path and query components.";
-
- return false;
- }
-
- if (uri.Fragment.Length > 0) {
- message = "It includes the fragment component.";
-
- return false;
- }
-
- if (uri.Port == 0) {
- message = "The port part is zero.";
-
- return false;
- }
-
- result = uri;
-
- return true;
- }
-
- #endregion
-
- #region Public Methods
-
- ///
- /// Adds a WebSocket service with the specified behavior and path.
- ///
- ///
- ///
- /// A that specifies an absolute path to
- /// the service to add.
- ///
- ///
- /// / is trimmed from the end of the string if present.
- ///
- ///
- ///
- ///
- /// The type of the behavior for the service.
- ///
- ///
- /// It must inherit the class.
- ///
- ///
- /// Also it must have a public parameterless constructor.
- ///
- ///
- ///
- ///
- /// is an empty string.
- ///
- ///
- /// -or-
- ///
- ///
- /// is not an absolute path.
- ///
- ///
- /// -or-
- ///
- ///
- /// includes either or both
- /// query and fragment components.
- ///
- ///
- /// -or-
- ///
- ///
- /// is already in use.
- ///
- ///
- ///
- /// is .
- ///
- public void AddWebSocketService (string path)
- where TBehavior : WebSocketBehavior, new ()
- {
- _services.AddService (path, null);
- }
-
- ///
- /// Adds a WebSocket service with the specified behavior, path,
- /// and initializer.
- ///
- ///
- ///
- /// A that specifies an absolute path to
- /// the service to add.
- ///
- ///
- /// / is trimmed from the end of the string if present.
- ///
- ///
- ///
- ///
- /// An delegate.
- ///
- ///
- /// It specifies the delegate called when the service initializes
- /// a new session instance.
- ///
- ///
- /// if not necessary.
- ///
- ///
- ///
- ///
- /// The type of the behavior for the service.
- ///
- ///
- /// It must inherit the class.
- ///
- ///
- /// Also it must have a public parameterless constructor.
- ///
- ///
- ///
- ///
- /// is an empty string.
- ///
- ///
- /// -or-
- ///
- ///
- /// is not an absolute path.
- ///
- ///
- /// -or-
- ///
- ///
- /// includes either or both
- /// query and fragment components.
- ///
- ///
- /// -or-
- ///
- ///
- /// is already in use.
- ///
- ///
- ///
- /// is .
- ///
- public void AddWebSocketService (
- string path,
- Action initializer
- )
- where TBehavior : WebSocketBehavior, new ()
- {
- _services.AddService (path, initializer);
- }
-
- ///
- /// Removes a WebSocket service with the specified path.
- ///
- ///
- /// The service is stopped with close status 1001 (going away)
- /// if the current state of the service is Start.
- ///
- ///
- /// true if the service is successfully found and removed;
- /// otherwise, false.
- ///
- ///
- ///
- /// A that specifies an absolute path to
- /// the service to remove.
- ///
- ///
- /// / is trimmed from the end of the string if present.
- ///
- ///
- ///
- ///
- /// is an empty string.
- ///
- ///
- /// -or-
- ///
- ///
- /// is not an absolute path.
- ///
- ///
- /// -or-
- ///
- ///
- /// includes either or both
- /// query and fragment components.
- ///
- ///
- ///
- /// is .
- ///
- public bool RemoveWebSocketService (string path)
- {
- return _services.RemoveService (path);
- }
-
- ///
- /// Starts receiving incoming requests.
- ///
- ///
- /// This method works if the current state of the server is Ready or Stop.
- ///
- ///
- ///
- /// There is no server certificate for secure connection.
- ///
- ///
- /// -or-
- ///
- ///
- /// The underlying has failed to start.
- ///
- ///
- public void Start ()
- {
- if (_state == ServerState.Start || _state == ServerState.ShuttingDown)
- return;
-
- start ();
- }
-
- ///
- /// Stops receiving incoming requests.
- ///
- ///
- /// This method works if the current state of the server is Start.
- ///
- public void Stop ()
- {
- if (_state != ServerState.Start)
- return;
-
- stop (1001, String.Empty);
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Server/IWebSocketSession.cs b/websocket-sharp/Server/IWebSocketSession.cs
deleted file mode 100644
index 4ddc84aca..000000000
--- a/websocket-sharp/Server/IWebSocketSession.cs
+++ /dev/null
@@ -1,67 +0,0 @@
-#region License
-/*
- * IWebSocketSession.cs
- *
- * The MIT License
- *
- * Copyright (c) 2013-2022 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-using System;
-
-namespace WebSocketSharp.Server
-{
- ///
- /// Exposes the access to the information in a WebSocket session.
- ///
- public interface IWebSocketSession
- {
- #region Properties
-
- ///
- /// Gets the unique ID of the session.
- ///
- ///
- /// A that represents the unique ID of the session.
- ///
- string ID { get; }
-
- ///
- /// Gets the time that the session has started.
- ///
- ///
- /// A that represents the time that the session
- /// has started.
- ///
- DateTime StartTime { get; }
-
- ///
- /// Gets the WebSocket interface for the session.
- ///
- ///
- /// A that represents the interface.
- ///
- WebSocket WebSocket { get; }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Server/ServerState.cs b/websocket-sharp/Server/ServerState.cs
deleted file mode 100644
index 2d7582920..000000000
--- a/websocket-sharp/Server/ServerState.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-#region License
-/*
- * ServerState.cs
- *
- * The MIT License
- *
- * Copyright (c) 2013-2014 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-using System;
-
-namespace WebSocketSharp.Server
-{
- internal enum ServerState
- {
- Ready,
- Start,
- ShuttingDown,
- Stop
- }
-}
diff --git a/websocket-sharp/Server/WebSocketBehavior.cs b/websocket-sharp/Server/WebSocketBehavior.cs
deleted file mode 100644
index 8ecfa1bcf..000000000
--- a/websocket-sharp/Server/WebSocketBehavior.cs
+++ /dev/null
@@ -1,1622 +0,0 @@
-#region License
-/*
- * WebSocketBehavior.cs
- *
- * The MIT License
- *
- * Copyright (c) 2012-2026 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-using System;
-using System.Collections.Specialized;
-using System.IO;
-using System.Security.Principal;
-using WebSocketSharp.Net;
-using WebSocketSharp.Net.WebSockets;
-
-namespace WebSocketSharp.Server
-{
- ///
- /// Exposes a set of methods and properties used to define the behavior of
- /// a WebSocket service provided by the or
- /// class.
- ///
- ///
- /// This class is an abstract class.
- ///
- public abstract class WebSocketBehavior : IWebSocketSession
- {
- #region Private Fields
-
- private WebSocketContext _context;
- private Action _cookiesResponder;
- private bool _emitOnPing;
- private Func _hostValidator;
- private string _id;
- private bool _ignoreExtensions;
- private bool _noDelay;
- private Func _originValidator;
- private string _protocol;
- private bool _registered;
- private WebSocketSessionManager _sessions;
- private DateTime _startTime;
- private Action _userHeadersResponder;
- private WebSocket _websocket;
-
- #endregion
-
- #region Protected Constructors
-
- ///
- /// Initializes a new instance of the class.
- ///
- protected WebSocketBehavior ()
- {
- _startTime = DateTime.MaxValue;
- }
-
- #endregion
-
- #region Protected Properties
-
- ///
- /// Gets the HTTP headers for a session.
- ///
- ///
- /// A that contains the headers
- /// included in the WebSocket handshake request.
- ///
- ///
- /// The get operation is not available when the session has not started yet.
- ///
- protected NameValueCollection Headers {
- get {
- if (!_registered) {
- var msg = "The session has not started yet.";
-
- throw new InvalidOperationException (msg);
- }
-
- return _context.Headers;
- }
- }
-
- ///
- /// Gets a value indicating whether the communication is possible for
- /// a session.
- ///
- ///
- /// true if the communication is possible; otherwise, false.
- ///
- ///
- /// The get operation is not available when the session has not started yet.
- ///
- protected bool IsAlive {
- get {
- if (!_registered) {
- var msg = "The session has not started yet.";
-
- throw new InvalidOperationException (msg);
- }
-
- return _websocket.IsAlive;
- }
- }
-
- ///
- /// Gets the query string for a session.
- ///
- ///
- ///
- /// A that contains the query
- /// parameters included in the WebSocket handshake request.
- ///
- ///
- /// An empty collection if not included.
- ///
- ///
- ///
- /// The get operation is not available when the session has not started yet.
- ///
- protected NameValueCollection QueryString {
- get {
- if (!_registered) {
- var msg = "The session has not started yet.";
-
- throw new InvalidOperationException (msg);
- }
-
- return _context.QueryString;
- }
- }
-
- ///
- /// Gets the current state of the WebSocket interface for a session.
- ///
- ///
- ///
- /// One of the enum values.
- ///
- ///
- /// It indicates the current state of the interface.
- ///
- ///
- ///
- /// The get operation is not available when the session has not started yet.
- ///
- protected WebSocketState ReadyState {
- get {
- if (!_registered) {
- var msg = "The session has not started yet.";
-
- throw new InvalidOperationException (msg);
- }
-
- return _websocket.ReadyState;
- }
- }
-
- ///
- /// Gets the management function for the sessions in the service.
- ///
- ///
- /// A that manages the sessions in
- /// the service.
- ///
- ///
- /// The get operation is not available when the session has not started yet.
- ///
- protected WebSocketSessionManager Sessions {
- get {
- if (!_registered) {
- var msg = "The session has not started yet.";
-
- throw new InvalidOperationException (msg);
- }
-
- return _sessions;
- }
- }
-
- ///
- /// Gets the client information for a session.
- ///
- ///
- ///
- /// A instance that represents identity,
- /// authentication, and security roles for the client.
- ///
- ///
- /// if the client is not authenticated.
- ///
- ///
- ///
- /// The get operation is not available when the session has not started yet.
- ///
- protected IPrincipal User {
- get {
- if (!_registered) {
- var msg = "The session has not started yet.";
-
- throw new InvalidOperationException (msg);
- }
-
- return _context.User;
- }
- }
-
- ///
- /// Gets the client endpoint for a session.
- ///
- ///
- /// A that represents the client
- /// IP address and port number.
- ///
- ///
- /// The get operation is not available when the session has not started yet.
- ///
- protected System.Net.IPEndPoint UserEndPoint {
- get {
- if (!_registered) {
- var msg = "The session has not started yet.";
-
- throw new InvalidOperationException (msg);
- }
-
- return _context.UserEndPoint;
- }
- }
-
- #endregion
-
- #region Public Properties
-
- ///
- /// Gets or sets the delegate used to respond to the HTTP cookies.
- ///
- ///
- ///
- /// A
- /// delegate.
- ///
- ///
- /// It represents the delegate called when the WebSocket interface
- /// for a session respond to the handshake request.
- ///
- ///
- /// 1st parameter passed to the delegate
- /// contains the cookies included in the handshake request if any.
- ///
- ///
- /// 2nd parameter passed to the delegate
- /// holds the cookies to send to the client.
- ///
- ///
- /// if not necessary.
- ///
- ///
- /// The default value is .
- ///
- ///
- ///
- /// The set operation is not available when the session has already started.
- ///
- public Action CookiesResponder {
- get {
- return _cookiesResponder;
- }
-
- set {
- if (_registered) {
- var msg = "The session has already started.";
-
- throw new InvalidOperationException (msg);
- }
-
- _cookiesResponder = value;
- }
- }
-
- ///
- /// Gets or sets a value indicating whether the WebSocket interface for
- /// a session emits the message event when it receives a ping.
- ///
- ///
- ///
- /// true if the interface emits the message event when it receives
- /// a ping; otherwise, false.
- ///
- ///
- /// The default value is false.
- ///
- ///
- ///
- /// The set operation is not available when the session has already started.
- ///
- public bool EmitOnPing {
- get {
- return _emitOnPing;
- }
-
- set {
- if (_registered) {
- var msg = "The session has already started.";
-
- throw new InvalidOperationException (msg);
- }
-
- _emitOnPing = value;
- }
- }
-
- ///
- /// Gets or sets the delegate used to validate the Host header.
- ///
- ///
- ///
- /// A delegate.
- ///
- ///
- /// It represents the delegate called when the WebSocket interface
- /// for a session validates the handshake request.
- ///
- ///
- /// The parameter passed to the delegate is
- /// the value of the Host header.
- ///
- ///
- /// The method invoked by the delegate must return true
- /// if the header value is valid.
- ///
- ///
- /// if not necessary.
- ///
- ///
- /// The default value is .
- ///
- ///
- ///
- /// The set operation is not available when the session has already started.
- ///
- public Func HostValidator {
- get {
- return _hostValidator;
- }
-
- set {
- if (_registered) {
- var msg = "The session has already started.";
-
- throw new InvalidOperationException (msg);
- }
-
- _hostValidator = value;
- }
- }
-
- ///
- /// Gets the unique ID of a session.
- ///
- ///
- /// A that represents the unique ID of the session.
- ///
- public string ID {
- get {
- if (_id == null)
- _id = WebSocketSessionManager.CreateID ();
-
- return _id;
- }
- }
-
- ///
- /// Gets or sets a value indicating whether the WebSocket interface for
- /// a session ignores the Sec-WebSocket-Extensions header.
- ///
- ///
- ///
- /// true if the interface ignores the extensions requested
- /// from the client; otherwise, false.
- ///
- ///
- /// The default value is false.
- ///
- ///
- ///
- /// The set operation is not available when the session has already started.
- ///
- public bool IgnoreExtensions {
- get {
- return _ignoreExtensions;
- }
-
- set {
- if (_registered) {
- var msg = "The session has already started.";
-
- throw new InvalidOperationException (msg);
- }
-
- _ignoreExtensions = value;
- }
- }
-
- ///
- /// Gets or sets a value indicating whether the underlying TCP socket of
- /// the WebSocket interface for a session disables a delay when send or
- /// receive buffer is not full.
- ///
- ///
- ///
- /// true if the delay is disabled; otherwise, false.
- ///
- ///
- /// The default value is false.
- ///
- ///
- ///
- ///
- /// The set operation is not available when the session has already started.
- ///
- public bool NoDelay {
- get {
- return _noDelay;
- }
-
- set {
- if (_registered) {
- var msg = "The session has already started.";
-
- throw new InvalidOperationException (msg);
- }
-
- _noDelay = value;
- }
- }
-
- ///
- /// Gets or sets the delegate used to validate the Origin header.
- ///
- ///
- ///
- /// A delegate.
- ///
- ///
- /// It represents the delegate called when the WebSocket interface
- /// for a session validates the handshake request.
- ///
- ///
- /// The parameter passed to the delegate is
- /// the value of the Origin header or if
- /// the header is not present.
- ///
- ///
- /// The method invoked by the delegate must return true
- /// if the header value is valid.
- ///
- ///
- /// if not necessary.
- ///
- ///
- /// The default value is .
- ///
- ///
- ///
- /// The set operation is not available when the session has already started.
- ///
- public Func OriginValidator {
- get {
- return _originValidator;
- }
-
- set {
- if (_registered) {
- var msg = "The session has already started.";
-
- throw new InvalidOperationException (msg);
- }
-
- _originValidator = value;
- }
- }
-
- ///
- /// Gets or sets the name of the WebSocket subprotocol for a session.
- ///
- ///
- ///
- /// A that represents the name of the subprotocol.
- ///
- ///
- /// The value specified for a set operation must be a token defined in
- ///
- /// RFC 2616.
- ///
- ///
- /// The value is initialized if not requested.
- ///
- ///
- /// The default value is an empty string.
- ///
- ///
- ///
- /// The value specified for a set operation is not a token.
- ///
- ///
- /// The set operation is not available when the session has already started.
- ///
- public string Protocol {
- get {
- return _registered
- ? _websocket.Protocol
- : (_protocol ?? String.Empty);
- }
-
- set {
- if (_registered) {
- var msg = "The session has already started.";
-
- throw new InvalidOperationException (msg);
- }
-
- if (value.IsNullOrEmpty ()) {
- _protocol = null;
-
- return;
- }
-
- if (!value.IsToken ()) {
- var msg = "Not a token.";
-
- throw new ArgumentException (msg, "value");
- }
-
- _protocol = value;
- }
- }
-
- ///
- /// Gets the time that a session has started.
- ///
- ///
- ///
- /// A that represents the time that the session
- /// has started.
- ///
- ///
- /// when the session has not started yet.
- ///
- ///
- public DateTime StartTime {
- get {
- return _startTime;
- }
- }
-
- ///
- /// Gets or sets the delegate used to respond to the user headers.
- ///
- ///
- ///
- /// A
- /// delegate.
- ///
- ///
- /// It represents the delegate called when the WebSocket interface
- /// for a session respond to the handshake request.
- ///
- ///
- /// 1st parameter passed to the delegate
- /// contains the HTTP headers included in the handshake request.
- ///
- ///
- /// 2nd parameter passed to the delegate
- /// holds the user headers to send to the client.
- ///
- ///
- /// if not necessary.
- ///
- ///
- /// The default value is .
- ///
- ///
- ///
- /// The set operation is not available when the session has already started.
- ///
- public Action UserHeadersResponder {
- get {
- return _userHeadersResponder;
- }
-
- set {
- if (_registered) {
- var msg = "The session has already started.";
-
- throw new InvalidOperationException (msg);
- }
-
- _userHeadersResponder = value;
- }
- }
-
- #endregion
-
- #region Private Methods
-
- private string checkHandshakeRequest (WebSocketContext context)
- {
- if (_hostValidator != null) {
- if (!_hostValidator (context.Host)) {
- var msg = "The Host header is invalid.";
-
- return msg;
- }
- }
-
- if (_originValidator != null) {
- if (!_originValidator (context.Origin)) {
- var msg = "The Origin header is non-existent or invalid.";
-
- return msg;
- }
- }
-
- return null;
- }
-
- private bool executeBeforeClose ()
- {
- if (!_registered)
- return false;
-
- _sessions.Remove (_id);
-
- return true;
- }
-
- private bool executeBeforeOpen ()
- {
- _registered = _sessions.Add (this);
-
- if (!_registered) {
- _websocket.Close (CloseStatusCode.Away);
-
- return false;
- }
-
- _startTime = DateTime.Now;
-
- return true;
- }
-
- private void onClose (object sender, CloseEventArgs e)
- {
- OnClose (e);
- }
-
- private void onError (object sender, ErrorEventArgs e)
- {
- OnError (e);
- }
-
- private void onMessage (object sender, MessageEventArgs e)
- {
- OnMessage (e);
- }
-
- private void onOpen (object sender, EventArgs e)
- {
- OnOpen ();
- }
-
- private void respondToHandshakeRequest (WebSocketContext context)
- {
- if (_cookiesResponder != null) {
- var reqCookies = context.CookieCollection;
- var resCookies = context.WebSocket.Cookies;
-
- _cookiesResponder (reqCookies, resCookies);
- }
-
- if (_userHeadersResponder != null) {
- var reqHeaders = context.Headers;
- var userHeaders = context.WebSocket.UserHeaders;
-
- _userHeadersResponder (reqHeaders, userHeaders);
- }
- }
-
- #endregion
-
- #region Internal Methods
-
- internal void Start (
- WebSocketContext context,
- WebSocketSessionManager sessions
- )
- {
- _context = context;
- _sessions = sessions;
-
- _websocket = context.WebSocket;
-
- _websocket.CustomHandshakeRequestChecker = checkHandshakeRequest;
- _websocket.CustomHandshakeRequestResponder = respondToHandshakeRequest;
-
- _websocket.ExecutorBeforeClose = executeBeforeClose;
- _websocket.ExecutorBeforeOpen = executeBeforeOpen;
-
- if (_emitOnPing)
- _websocket.EmitOnPing = true;
-
- if (_ignoreExtensions)
- _websocket.IgnoreExtensions = true;
-
- if (_noDelay)
- _websocket.NoDelay = true;
-
- if (_protocol != null)
- _websocket.Protocol = _protocol;
-
- var waitTime = sessions.WaitTime;
-
- if (waitTime != _websocket.WaitTime)
- _websocket.WaitTime = waitTime;
-
- _websocket.OnClose += onClose;
- _websocket.OnError += onError;
- _websocket.OnMessage += onMessage;
- _websocket.OnOpen += onOpen;
-
- _websocket.Accept ();
- }
-
- #endregion
-
- #region Protected Methods
-
- ///
- /// Closes the WebSocket connection for a session.
- ///
- ///
- /// This method does nothing when the current state of the WebSocket
- /// interface is Closing or Closed.
- ///
- ///
- /// This method is not available when the session has not started yet.
- ///
- protected void Close ()
- {
- if (!_registered) {
- var msg = "The session has not started yet.";
-
- throw new InvalidOperationException (msg);
- }
-
- _websocket.Close ();
- }
-
- ///
- /// Closes the WebSocket connection for a session with the specified
- /// status code and reason.
- ///
- ///
- /// This method does nothing when the current state of the WebSocket
- /// interface is Closing or Closed.
- ///
- ///
- ///
- /// A that specifies the status code indicating
- /// the reason for the close.
- ///
- ///
- /// The status codes are defined in
- ///
- /// Section 7.4 of RFC 6455.
- ///
- ///
- ///
- ///
- /// A that specifies the reason for the close.
- ///
- ///
- /// Its size must be 123 bytes or less in UTF-8.
- ///
- ///
- ///
- ///
- /// is 1010 (mandatory extension).
- ///
- ///
- /// -or-
- ///
- ///
- /// is 1005 (no status) and
- /// is specified.
- ///
- ///
- /// -or-
- ///
- ///
- /// could not be UTF-8-encoded.
- ///
- ///
- ///
- ///
- /// is less than 1000 or greater than 4999.
- ///
- ///
- /// -or-
- ///
- ///
- /// The size of is greater than 123 bytes.
- ///
- ///
- ///
- /// This method is not available when the session has not started yet.
- ///
- protected void Close (ushort code, string reason)
- {
- if (!_registered) {
- var msg = "The session has not started yet.";
-
- throw new InvalidOperationException (msg);
- }
-
- _websocket.Close (code, reason);
- }
-
- ///
- /// Closes the WebSocket connection for a session with the specified
- /// status code and reason.
- ///
- ///
- /// This method does nothing when the current state of the WebSocket
- /// interface is Closing or Closed.
- ///
- ///
- ///
- /// One of the enum values.
- ///
- ///
- /// It specifies the status code indicating the reason for the close.
- ///
- ///
- ///
- ///
- /// A that specifies the reason for the close.
- ///
- ///
- /// Its size must be 123 bytes or less in UTF-8.
- ///
- ///
- ///
- ///
- /// is an undefined enum value.
- ///
- ///
- /// -or-
- ///
- ///
- /// is .
- ///
- ///
- /// -or-
- ///
- ///
- /// is and
- /// is specified.
- ///
- ///
- /// -or-
- ///
- ///
- /// could not be UTF-8-encoded.
- ///
- ///
- ///
- /// The size of is greater than 123 bytes.
- ///
- ///
- /// This method is not available when the session has not started yet.
- ///
- protected void Close (CloseStatusCode code, string reason)
- {
- if (!_registered) {
- var msg = "The session has not started yet.";
-
- throw new InvalidOperationException (msg);
- }
-
- _websocket.Close (code, reason);
- }
-
- ///
- /// Closes the WebSocket connection for a session asynchronously.
- ///
- ///
- ///
- /// This method does not wait for the close to be complete.
- ///
- ///
- /// This method does nothing when the current state of the WebSocket
- /// interface is Closing or Closed.
- ///
- ///
- ///
- /// This method is not available when the session has not started yet.
- ///
- protected void CloseAsync ()
- {
- if (!_registered) {
- var msg = "The session has not started yet.";
-
- throw new InvalidOperationException (msg);
- }
-
- _websocket.CloseAsync ();
- }
-
- ///
- /// Closes the WebSocket connection for a session asynchronously with
- /// the specified status code and reason.
- ///
- ///
- ///
- /// This method does not wait for the close to be complete.
- ///
- ///
- /// This method does nothing when the current state of the WebSocket
- /// interface is Closing or Closed.
- ///
- ///
- ///
- ///
- /// A that specifies the status code indicating
- /// the reason for the close.
- ///
- ///
- /// The status codes are defined in
- ///
- /// Section 7.4 of RFC 6455.
- ///
- ///
- ///
- ///
- /// A that specifies the reason for the close.
- ///
- ///
- /// Its size must be 123 bytes or less in UTF-8.
- ///
- ///
- ///
- ///
- /// is 1010 (mandatory extension).
- ///
- ///
- /// -or-
- ///
- ///
- /// is 1005 (no status) and
- /// is specified.
- ///
- ///
- /// -or-
- ///
- ///
- /// could not be UTF-8-encoded.
- ///
- ///
- ///
- ///
- /// is less than 1000 or greater than 4999.
- ///
- ///
- /// -or-
- ///
- ///
- /// The size of is greater than 123 bytes.
- ///
- ///
- ///
- /// This method is not available when the session has not started yet.
- ///
- protected void CloseAsync (ushort code, string reason)
- {
- if (!_registered) {
- var msg = "The session has not started yet.";
-
- throw new InvalidOperationException (msg);
- }
-
- _websocket.CloseAsync (code, reason);
- }
-
- ///
- /// Closes the WebSocket connection for a session asynchronously with
- /// the specified status code and reason.
- ///
- ///
- ///
- /// This method does not wait for the close to be complete.
- ///
- ///
- /// This method does nothing when the current state of the WebSocket
- /// interface is Closing or Closed.
- ///
- ///
- ///
- ///
- /// One of the enum values.
- ///
- ///
- /// It specifies the status code indicating the reason for the close.
- ///
- ///
- ///
- ///
- /// A that specifies the reason for the close.
- ///
- ///
- /// Its size must be 123 bytes or less in UTF-8.
- ///
- ///
- ///
- ///
- /// is an undefined enum value.
- ///
- ///
- /// -or-
- ///
- ///
- /// is .
- ///
- ///
- /// -or-
- ///
- ///
- /// is and
- /// is specified.
- ///
- ///
- /// -or-
- ///
- ///
- /// could not be UTF-8-encoded.
- ///
- ///
- ///
- /// The size of is greater than 123 bytes.
- ///
- ///
- /// This method is not available when the session has not started yet.
- ///
- protected void CloseAsync (CloseStatusCode code, string reason)
- {
- if (!_registered) {
- var msg = "The session has not started yet.";
-
- throw new InvalidOperationException (msg);
- }
-
- _websocket.CloseAsync (code, reason);
- }
-
- ///
- /// Called when the WebSocket connection for a session has been closed.
- ///
- ///
- /// A that represents the close event data
- /// passed from the WebSocket interface.
- ///
- protected virtual void OnClose (CloseEventArgs e)
- {
- }
-
- ///
- /// Called when the WebSocket interface for a session gets an error.
- ///
- ///
- /// A that represents the error event data
- /// passed from the interface.
- ///
- protected virtual void OnError (ErrorEventArgs e)
- {
- }
-
- ///
- /// Called when the WebSocket interface for a session receives a message.
- ///
- ///
- /// A that represents the message event data
- /// passed from the interface.
- ///
- protected virtual void OnMessage (MessageEventArgs e)
- {
- }
-
- ///
- /// Called when the WebSocket connection for a session has been established.
- ///
- protected virtual void OnOpen ()
- {
- }
-
- ///
- /// Sends a ping to the client for a session.
- ///
- ///
- /// true if the send has successfully done and a pong has been
- /// received within a time; otherwise, false.
- ///
- ///
- /// This method is not available when the session has not started yet.
- ///
- protected bool Ping ()
- {
- if (!_registered) {
- var msg = "The session has not started yet.";
-
- throw new InvalidOperationException (msg);
- }
-
- return _websocket.Ping ();
- }
-
- ///
- /// Sends a ping with the specified message to the client for a session.
- ///
- ///
- /// true if the send has successfully done and a pong has been
- /// received within a time; otherwise, false.
- ///
- ///
- ///
- /// A that specifies the message to send.
- ///
- ///
- /// Its size must be 125 bytes or less in UTF-8.
- ///
- ///
- ///
- /// could not be UTF-8-encoded.
- ///
- ///
- /// The size of is greater than 125 bytes.
- ///
- ///
- /// This method is not available when the session has not started yet.
- ///
- protected bool Ping (string message)
- {
- if (!_registered) {
- var msg = "The session has not started yet.";
-
- throw new InvalidOperationException (msg);
- }
-
- return _websocket.Ping (message);
- }
-
- ///
- /// Sends the specified data to the client for a session.
- ///
- ///
- /// An array of that specifies the binary data to send.
- ///
- ///
- /// is .
- ///
- ///
- ///
- /// This method is not available when the session has not started yet.
- ///
- ///
- /// -or-
- ///
- ///
- /// This method is not available when the current state of the WebSocket
- /// interface is not Open.
- ///
- ///
- protected void Send (byte[] data)
- {
- if (!_registered) {
- var msg = "The session has not started yet.";
-
- throw new InvalidOperationException (msg);
- }
-
- _websocket.Send (data);
- }
-
- ///
- /// Sends the specified file to the client for a session.
- ///
- ///
- ///
- /// A that specifies the file to send.
- ///
- ///
- /// The file is sent as the binary data.
- ///
- ///
- ///
- ///
- /// The file does not exist.
- ///
- ///
- /// -or-
- ///
- ///
- /// The file could not be opened.
- ///
- ///
- ///
- /// is .
- ///
- ///
- ///
- /// This method is not available when the session has not started yet.
- ///
- ///
- /// -or-
- ///
- ///
- /// This method is not available when the current state of the WebSocket
- /// interface is not Open.
- ///
- ///
- protected void Send (FileInfo fileInfo)
- {
- if (!_registered) {
- var msg = "The session has not started yet.";
-
- throw new InvalidOperationException (msg);
- }
-
- _websocket.Send (fileInfo);
- }
-
- ///
- /// Sends the specified data to the client for a session.
- ///
- ///
- /// A that specifies the text data to send.
- ///
- ///
- /// could not be UTF-8-encoded.
- ///
- ///
- /// is .
- ///
- ///
- ///
- /// This method is not available when the session has not started yet.
- ///
- ///
- /// -or-
- ///
- ///
- /// This method is not available when the current state of the WebSocket
- /// interface is not Open.
- ///
- ///
- protected void Send (string data)
- {
- if (!_registered) {
- var msg = "The session has not started yet.";
-
- throw new InvalidOperationException (msg);
- }
-
- _websocket.Send (data);
- }
-
- ///
- /// Sends the data from the specified stream instance to the client for
- /// a session.
- ///
- ///
- ///
- /// A instance from which to read the data to send.
- ///
- ///
- /// The data is sent as the binary data.
- ///
- ///
- ///
- /// An that specifies the number of bytes to send.
- ///
- ///
- ///
- /// cannot be read.
- ///
- ///
- /// -or-
- ///
- ///
- /// is less than 1.
- ///
- ///
- /// -or-
- ///
- ///
- /// No data could be read from .
- ///
- ///
- ///
- /// is .
- ///
- ///
- ///
- /// This method is not available when the session has not started yet.
- ///
- ///
- /// -or-
- ///
- ///
- /// This method is not available when the current state of the WebSocket
- /// interface is not Open.
- ///
- ///
- protected void Send (Stream stream, int length)
- {
- if (!_registered) {
- var msg = "The session has not started yet.";
-
- throw new InvalidOperationException (msg);
- }
-
- _websocket.Send (stream, length);
- }
-
- ///
- /// Sends the specified data to the client for a session asynchronously.
- ///
- ///
- /// This method does not wait for the send to be complete.
- ///
- ///
- /// An array of that specifies the binary data to send.
- ///
- ///
- ///
- /// An delegate.
- ///
- ///
- /// It specifies the delegate called when the send is complete.
- ///
- ///
- /// The parameter passed to the delegate is true
- /// if the send has successfully done; otherwise, false.
- ///
- ///
- /// if not necessary.
- ///
- ///
- ///
- /// is .
- ///
- ///
- ///
- /// This method is not available when the session has not started yet.
- ///
- ///
- /// -or-
- ///
- ///
- /// This method is not available when the current state of the WebSocket
- /// interface is not Open.
- ///
- ///
- protected void SendAsync (byte[] data, Action completed)
- {
- if (!_registered) {
- var msg = "The session has not started yet.";
-
- throw new InvalidOperationException (msg);
- }
-
- _websocket.SendAsync (data, completed);
- }
-
- ///
- /// Sends the specified file to the client for a session asynchronously.
- ///
- ///
- /// This method does not wait for the send to be complete.
- ///
- ///
- ///
- /// A that specifies the file to send.
- ///
- ///
- /// The file is sent as the binary data.
- ///
- ///
- ///
- ///
- /// An delegate.
- ///
- ///
- /// It specifies the delegate called when the send is complete.
- ///
- ///
- /// The parameter passed to the delegate is true
- /// if the send has successfully done; otherwise, false.
- ///
- ///
- /// if not necessary.
- ///
- ///
- ///
- ///
- /// The file does not exist.
- ///
- ///
- /// -or-
- ///
- ///
- /// The file could not be opened.
- ///
- ///
- ///
- /// is .
- ///
- ///
- ///
- /// This method is not available when the session has not started yet.
- ///
- ///
- /// -or-
- ///
- ///
- /// This method is not available when the current state of the WebSocket
- /// interface is not Open.
- ///
- ///
- protected void SendAsync (FileInfo fileInfo, Action completed)
- {
- if (!_registered) {
- var msg = "The session has not started yet.";
-
- throw new InvalidOperationException (msg);
- }
-
- _websocket.SendAsync (fileInfo, completed);
- }
-
- ///
- /// Sends the specified data to the client for a session asynchronously.
- ///
- ///
- /// This method does not wait for the send to be complete.
- ///
- ///
- /// A that specifies the text data to send.
- ///
- ///
- ///
- /// An delegate.
- ///
- ///
- /// It specifies the delegate called when the send is complete.
- ///
- ///
- /// The parameter passed to the delegate is true
- /// if the send has successfully done; otherwise, false.
- ///
- ///
- /// if not necessary.
- ///
- ///
- ///
- /// could not be UTF-8-encoded.
- ///
- ///
- /// is .
- ///
- ///
- ///
- /// This method is not available when the session has not started yet.
- ///
- ///
- /// -or-
- ///
- ///
- /// This method is not available when the current state of the WebSocket
- /// interface is not Open.
- ///
- ///
- protected void SendAsync (string data, Action completed)
- {
- if (!_registered) {
- var msg = "The session has not started yet.";
-
- throw new InvalidOperationException (msg);
- }
-
- _websocket.SendAsync (data, completed);
- }
-
- ///
- /// Sends the data from the specified stream instance to the client for
- /// a session asynchronously.
- ///
- ///
- /// This method does not wait for the send to be complete.
- ///
- ///
- ///
- /// A instance from which to read the data to send.
- ///
- ///
- /// The data is sent as the binary data.
- ///
- ///
- ///
- /// An that specifies the number of bytes to send.
- ///
- ///
- ///
- /// An delegate.
- ///
- ///
- /// It specifies the delegate called when the send is complete.
- ///
- ///
- /// The parameter passed to the delegate is true
- /// if the send has successfully done; otherwise, false.
- ///
- ///
- /// if not necessary.
- ///
- ///
- ///
- ///
- /// cannot be read.
- ///
- ///
- /// -or-
- ///
- ///
- /// is less than 1.
- ///
- ///
- /// -or-
- ///
- ///
- /// No data could be read from .
- ///
- ///
- ///
- /// is .
- ///
- ///
- ///
- /// This method is not available when the session has not started yet.
- ///
- ///
- /// -or-
- ///
- ///
- /// This method is not available when the current state of the WebSocket
- /// interface is not Open.
- ///
- ///
- protected void SendAsync (Stream stream, int length, Action completed)
- {
- if (!_registered) {
- var msg = "The session has not started yet.";
-
- throw new InvalidOperationException (msg);
- }
-
- _websocket.SendAsync (stream, length, completed);
- }
-
- #endregion
-
- #region Explicit Interface Implementations
-
- ///
- /// Gets the WebSocket interface for a session.
- ///
- ///
- ///
- /// A that represents
- /// the WebSocket interface.
- ///
- ///
- /// when the session has not started yet.
- ///
- ///
- WebSocket IWebSocketSession.WebSocket {
- get {
- return _websocket;
- }
- }
-
- #endregion
- }
-}
diff --git a/websocket-sharp/Server/WebSocketServer.cs b/websocket-sharp/Server/WebSocketServer.cs
deleted file mode 100644
index fc997ad83..000000000
--- a/websocket-sharp/Server/WebSocketServer.cs
+++ /dev/null
@@ -1,1185 +0,0 @@
-#region License
-/*
- * WebSocketServer.cs
- *
- * The MIT License
- *
- * Copyright (c) 2012-2024 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#endregion
-
-#region Contributors
-/*
- * Contributors:
- * - Juan Manuel Lallana
- * - Jonas Hovgaard
- * - Liryna
- * - Rohan Singh
- */
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Net.Sockets;
-using System.Security.Cryptography.X509Certificates;
-using System.Security.Principal;
-using System.Text;
-using System.Threading;
-using WebSocketSharp.Net;
-using WebSocketSharp.Net.WebSockets;
-
-namespace WebSocketSharp.Server
-{
- ///
- /// Provides a WebSocket protocol server.
- ///
- ///
- /// This class can provide multiple WebSocket services.
- ///
- public class WebSocketServer
- {
- #region Private Fields
-
- private System.Net.IPAddress _address;
- private AuthenticationSchemes _authSchemes;
- private static readonly string _defaultRealm;
- private string _hostname;
- private bool _isDnsStyle;
- private bool _isSecure;
- private TcpListener _listener;
- private Logger _log;
- private int _port;
- private string _realm;
- private string _realmInUse;
- private Thread _receiveThread;
- private bool _reuseAddress;
- private WebSocketServiceManager _services;
- private ServerSslConfiguration _sslConfig;
- private ServerSslConfiguration _sslConfigInUse;
- private volatile ServerState _state;
- private object _sync;
- private Func _userCredFinder;
-
- #endregion
-
- #region Static Constructor
-
- static WebSocketServer ()
- {
- _defaultRealm = "SECRET AREA";
- }
-
- #endregion
-
- #region Public Constructors
-
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- /// The new instance listens for incoming handshake requests on
- /// and port 80.
- ///
- public WebSocketServer ()
- {
- var addr = System.Net.IPAddress.Any;
-
- init (addr.ToString (), addr, 80, false);
- }
-
- ///
- /// Initializes a new instance of the class
- /// with the specified port.
- ///
- ///
- ///
- /// The new instance listens for incoming handshake requests on
- /// and .
- ///
- ///
- /// It provides secure connections if is 443.
- ///
- ///
- ///
- /// An that specifies the number of the port on which
- /// to listen.
- ///
- ///
- /// is less than 1 or greater than 65535.
- ///
- public WebSocketServer (int port)
- : this (port, port == 443)
- {
- }
-
- ///
- /// Initializes a new instance of the class
- /// with the specified URL.
- ///
- ///
- ///
- /// The new instance listens for incoming handshake requests on
- /// the IP address and port of .
- ///
- ///
- /// Either port 80 or 443 is used if includes
- /// no port. Port 443 is used if the scheme of
- /// is wss; otherwise, port 80 is used.
- ///
- ///
- /// The new instance provides secure connections if the scheme of
- /// is wss.
- ///
- ///
- ///
- /// A that specifies the WebSocket URL of the server.
- ///
- ///
- ///
- /// is an empty string.
- ///
- ///
- /// -or-
- ///
- ///
- /// is invalid.
- ///
- ///
- ///
- /// is .
- ///
- public WebSocketServer (string url)
- {
- if (url == null)
- throw new ArgumentNullException ("url");
-
- if (url.Length == 0)
- throw new ArgumentException ("An empty string.", "url");
-
- Uri uri;
- string msg;
-
- if (!tryCreateUri (url, out uri, out msg))
- throw new ArgumentException (msg, "url");
-
- var host = uri.DnsSafeHost;
- var addr = host.ToIPAddress ();
-
- if (addr == null) {
- msg = "The host part could not be converted to an IP address.";
-
- throw new ArgumentException (msg, "url");
- }
-
- if (!addr.IsLocal ()) {
- msg = "The IP address of the host is not a local IP address.";
-
- throw new ArgumentException (msg, "url");
- }
-
- init (host, addr, uri.Port, uri.Scheme == "wss");
- }
-
- ///
- /// Initializes a new instance of the class
- /// with the specified port and boolean if secure or not.
- ///
- ///
- /// The new instance listens for incoming handshake requests on
- /// and .
- ///
- ///
- /// An that specifies the number of the port on which
- /// to listen.
- ///
- ///
- /// A : true if the new instance provides
- /// secure connections; otherwise, false.
- ///
- ///
- /// is less than 1 or greater than 65535.
- ///
- public WebSocketServer (int port, bool secure)
- {
- if (!port.IsPortNumber ()) {
- var msg = "Less than 1 or greater than 65535.";
-
- throw new ArgumentOutOfRangeException ("port", msg);
- }
-
- var addr = System.Net.IPAddress.Any;
-
- init (addr.ToString (), addr, port, secure);
- }
-
- ///
- /// Initializes a new instance of the class
- /// with the specified IP address and port.
- ///
- ///
- ///
- /// The new instance listens for incoming handshake requests on
- /// and .
- ///
- ///
- /// It provides secure connections if is 443.
- ///
- ///
- ///
- /// A that specifies the local IP
- /// address on which to listen.
- ///
- ///
- /// An that specifies the number of the port on which
- /// to listen.
- ///
- ///
- /// is not a local IP address.
- ///
- ///
- /// is .
- ///
- ///
- /// is less than 1 or greater than 65535.
- ///
- public WebSocketServer (System.Net.IPAddress address, int port)
- : this (address, port, port == 443)
- {
- }
-
- ///
- /// Initializes a new instance of the class
- /// with the specified IP address, port, and boolean if secure or not.
- ///
- ///
- /// The new instance listens for incoming handshake requests on
- /// and .
- ///
- ///
- /// A that specifies the local IP
- /// address on which to listen.
- ///
- ///
- /// An that specifies the number of the port on which
- /// to listen.
- ///
- ///
- /// A : true if the new instance provides
- /// secure connections; otherwise, false.
- ///
- ///
- /// is not a local IP address.
- ///
- ///
- /// is .
- ///
- ///
- /// is less than 1 or greater than 65535.
- ///
- public WebSocketServer (System.Net.IPAddress address, int port, bool secure)
- {
- if (address == null)
- throw new ArgumentNullException ("address");
-
- if (!address.IsLocal ()) {
- var msg = "Not a local IP address.";
-
- throw new ArgumentException (msg, "address");
- }
-
- if (!port.IsPortNumber ()) {
- var msg = "Less than 1 or greater than 65535.";
-
- throw new ArgumentOutOfRangeException ("port", msg);
- }
-
- init (address.ToString (), address, port, secure);
- }
-
- #endregion
-
- #region Public Properties
-
- ///
- /// Gets the IP address of the server.
- ///
- ///
- /// A that represents the local IP
- /// address on which to listen for incoming handshake requests.
- ///
- public System.Net.IPAddress Address {
- get {
- return _address;
- }
- }
-
- ///
- /// Gets or sets the scheme used to authenticate the clients.
- ///
- ///
- /// The set operation works if the current state of the server is
- /// Ready or Stop.
- ///
- ///
- ///
- /// One of the
- /// enum values.
- ///
- ///
- /// It represents the scheme used to authenticate the clients.
- ///
- ///
- /// The default value is
- /// .
- ///
- ///
- public AuthenticationSchemes AuthenticationSchemes {
- get {
- return _authSchemes;
- }
-
- set {
- lock (_sync) {
- if (!canSet ())
- return;
-
- _authSchemes = value;
- }
- }
- }
-
- ///
- /// Gets a value indicating whether the server has started.
- ///
- ///
- /// true if the server has started; otherwise, false.
- ///
- public bool IsListening {
- get {
- return _state == ServerState.Start;
- }
- }
-
- ///
- /// Gets a value indicating whether the server provides secure connections.
- ///
- ///
- /// true if the server provides secure connections; otherwise,
- /// false.
- ///
- public bool IsSecure {
- get {
- return _isSecure;
- }
- }
-
- ///
- /// Gets or sets a value indicating whether the server cleans up
- /// the inactive sessions periodically.
- ///
- ///
- ///
- /// true if the server cleans up the inactive sessions
- /// every 60 seconds; otherwise, false.
- ///
- ///
- /// The default value is false.
- ///
- ///
- ///
- /// The set operation is not available when the current state of
- /// the server is neither Ready nor Stop.
- ///
- public bool KeepClean {
- get {
- return _services.KeepClean;
- }
-
- set {
- _services.KeepClean = value;
- }
- }
-
- ///
- /// Gets the logging function for the server.
- ///
- ///
- /// The default logging level is .
- ///
- ///
- /// A that provides the logging function.
- ///
- public Logger Log {
- get {
- return _log;
- }
- }
-
- ///
- /// Gets the port of the server.
- ///
- ///
- /// An that represents the number of the port on which
- /// to listen for incoming handshake requests.
- ///
- public int Port {
- get {
- return _port;
- }
- }
-
- ///
- /// Gets or sets the name of the realm associated with the server.
- ///
- ///
- /// The set operation works if the current state of the server is
- /// Ready or Stop.
- ///
- ///
- ///
- /// A that represents the name of the realm.
- ///
- ///
- /// "SECRET AREA" is used as the name of the realm if the value is
- /// or an empty string.
- ///
- ///
- /// The default value is .
- ///
- ///
- public string Realm {
- get {
- return _realm;
- }
-
- set {
- lock (_sync) {
- if (!canSet ())
- return;
-
- _realm = value;
- }
- }
- }
-
- ///
- /// Gets or sets a value indicating whether the server is allowed to
- /// be bound to an address that is already in use.
- ///
- ///
- ///
- /// You should set this property to true if you would like to
- /// resolve to wait for socket in TIME_WAIT state.
- ///
- ///
- /// The set operation works if the current state of the server is
- /// Ready or Stop.
- ///
- ///
- ///
- ///
- /// true if the server is allowed to be bound to an address
- /// that is already in use; otherwise, false.
- ///
- ///
- /// The default value is false.
- ///
- ///
- public bool ReuseAddress {
- get {
- return _reuseAddress;
- }
-
- set {
- lock (_sync) {
- if (!canSet ())
- return;
-
- _reuseAddress = value;
- }
- }
- }
-
- ///
- /// Gets the configuration for secure connection.
- ///
- ///
- /// The configuration is used when the server attempts to start,
- /// so it must be configured before the start method is called.
- ///
- ///
- /// A that represents the
- /// configuration used to provide secure connections.
- ///
- ///
- /// The server does not provide secure connections.
- ///
- public ServerSslConfiguration SslConfiguration {
- get {
- if (!_isSecure) {
- var msg = "The server does not provide secure connections.";
-
- throw new InvalidOperationException (msg);
- }
-
- return getSslConfiguration ();
- }
- }
-
- ///
- /// Gets or sets the delegate called to find the credentials for
- /// an identity used to authenticate a client.
- ///
- ///
- /// The set operation works if the current state of the server is
- /// Ready or Stop.
- ///
- ///
- ///
- /// A
- /// delegate.
- ///
- ///
- /// It represents the delegate called when the server finds
- /// the credentials used to authenticate a client.
- ///
- ///
- /// It must return if the credentials
- /// are not found.
- ///
- ///
- /// if not necessary.
- ///
- ///
- /// The default value is .
- ///
- ///
- public Func UserCredentialsFinder {
- get {
- return _userCredFinder;
- }
-
- set {
- lock (_sync) {
- if (!canSet ())
- return;
-
- _userCredFinder = value;
- }
- }
- }
-
- ///
- /// Gets or sets the time to wait for the response to the WebSocket
- /// Ping or Close.
- ///
- ///
- ///
- /// A that represents the time to wait for
- /// the response.
- ///
- ///
- /// The default value is the same as 1 second.
- ///
- ///
- ///
- /// The value specified for a set operation is zero or less.
- ///
- ///
- /// The set operation is not available when the current state of
- /// the server is neither Ready nor Stop.
- ///
- public TimeSpan WaitTime {
- get {
- return _services.WaitTime;
- }
-
- set {
- _services.WaitTime = value;
- }
- }
-
- ///
- /// Gets the management function for the WebSocket services provided by
- /// the server.
- ///
- ///
- /// A that manages the WebSocket
- /// services provided by the server.
- ///
- public WebSocketServiceManager WebSocketServices {
- get {
- return _services;
- }
- }
-
- #endregion
-
- #region Private Methods
-
- private void abort ()
- {
- lock (_sync) {
- if (_state != ServerState.Start)
- return;
-
- _state = ServerState.ShuttingDown;
- }
-
- try {
- _listener.Stop ();
- }
- catch (Exception ex) {
- _log.Fatal (ex.Message);
- _log.Debug (ex.ToString ());
- }
-
- try {
- _services.Stop (1006, String.Empty);
- }
- catch (Exception ex) {
- _log.Fatal (ex.Message);
- _log.Debug (ex.ToString ());
- }
-
- _state = ServerState.Stop;
- }
-
- private bool authenticateClient (TcpListenerWebSocketContext context)
- {
- if (_authSchemes == AuthenticationSchemes.Anonymous)
- return true;
-
- if (_authSchemes == AuthenticationSchemes.None)
- return false;
-
- var chal = new AuthenticationChallenge (_authSchemes, _realmInUse)
- .ToString ();
-
- var retry = -1;
- Func auth = null;
- auth =
- () => {
- retry++;
-
- if (retry > 99)
- return false;
-
- if (context.SetUser (_authSchemes, _realmInUse, _userCredFinder))
- return true;
-
- context.SendAuthenticationChallenge (chal);
-
- return auth ();
- };
-
- return auth ();
- }
-
- private bool canSet ()
- {
- return _state == ServerState.Ready || _state == ServerState.Stop;
- }
-
- private bool checkHostNameForRequest (string name)
- {
- return !_isDnsStyle
- || Uri.CheckHostName (name) != UriHostNameType.Dns
- || name == _hostname;
- }
-
- private string getRealm ()
- {
- var realm = _realm;
-
- return realm != null && realm.Length > 0 ? realm : _defaultRealm;
- }
-
- private ServerSslConfiguration getSslConfiguration ()
- {
- if (_sslConfig == null)
- _sslConfig = new ServerSslConfiguration ();
-
- return _sslConfig;
- }
-
- private void init (
- string hostname,
- System.Net.IPAddress address,
- int port,
- bool secure
- )
- {
- _hostname = hostname;
- _address = address;
- _port = port;
- _isSecure = secure;
-
- _authSchemes = AuthenticationSchemes.Anonymous;
- _isDnsStyle = Uri.CheckHostName (hostname) == UriHostNameType.Dns;
- _listener = new TcpListener (address, port);
- _log = new Logger ();
- _services = new WebSocketServiceManager (_log);
- _sync = new object ();
- }
-
- private void processRequest (TcpListenerWebSocketContext context)
- {
- if (!authenticateClient (context)) {
- context.Close (HttpStatusCode.Forbidden);
-
- return;
- }
-
- var uri = context.RequestUri;
-
- if (uri == null) {
- context.Close (HttpStatusCode.BadRequest);
-
- return;
- }
-
- var name = uri.DnsSafeHost;
-
- if (!checkHostNameForRequest (name)) {
- context.Close (HttpStatusCode.NotFound);
-
- return;
- }
-
- var path = uri.AbsolutePath;
-
- if (path.IndexOfAny (new[] { '%', '+' }) > -1)
- path = HttpUtility.UrlDecode (path, Encoding.UTF8);
-
- WebSocketServiceHost host;
-
- if (!_services.InternalTryGetServiceHost (path, out host)) {
- context.Close (HttpStatusCode.NotImplemented);
-
- return;
- }
-
- host.StartSession (context);
- }
-
- private void receiveRequest ()
- {
- while (true) {
- TcpClient cl = null;
-
- try {
- cl = _listener.AcceptTcpClient ();
-
- ThreadPool.QueueUserWorkItem (
- state => {
- try {
- var ctx = new TcpListenerWebSocketContext (
- cl,
- null,
- _isSecure,
- _sslConfigInUse,
- _log
- );
-
- processRequest (ctx);
- }
- catch (Exception ex) {
- _log.Error (ex.Message);
- _log.Debug (ex.ToString ());
-
- cl.Close ();
- }
- }
- );
- }
- catch (SocketException ex) {
- if (_state == ServerState.ShuttingDown)
- return;
-
- _log.Fatal (ex.Message);
- _log.Debug (ex.ToString ());
-
- break;
- }
- catch (InvalidOperationException ex) {
- if (_state == ServerState.ShuttingDown)
- return;
-
- _log.Fatal (ex.Message);
- _log.Debug (ex.ToString ());
-
- break;
- }
- catch (Exception ex) {
- _log.Fatal (ex.Message);
- _log.Debug (ex.ToString ());
-
- if (cl != null)
- cl.Close ();
-
- if (_state == ServerState.ShuttingDown)
- return;
-
- break;
- }
- }
-
- abort ();
- }
-
- private void start ()
- {
- lock (_sync) {
- if (_state == ServerState.Start || _state == ServerState.ShuttingDown)
- return;
-
- if (_isSecure) {
- var src = getSslConfiguration ();
- var conf = new ServerSslConfiguration (src);
-
- if (conf.ServerCertificate == null) {
- var msg = "There is no server certificate for secure connection.";
-
- throw new InvalidOperationException (msg);
- }
-
- _sslConfigInUse = conf;
- }
-
- _realmInUse = getRealm ();
-
- _services.Start ();
-
- try {
- startReceiving ();
- }
- catch {
- _services.Stop (1011, String.Empty);
-
- throw;
- }
-
- _state = ServerState.Start;
- }
- }
-
- private void startReceiving ()
- {
- if (_reuseAddress) {
- _listener.Server.SetSocketOption (
- SocketOptionLevel.Socket,
- SocketOptionName.ReuseAddress,
- true
- );
- }
-
- try {
- _listener.Start ();
- }
- catch (Exception ex) {
- var msg = "The underlying listener has failed to start.";
-
- throw new InvalidOperationException (msg, ex);
- }
-
- var receiver = new ThreadStart (receiveRequest);
- _receiveThread = new Thread (receiver);
- _receiveThread.IsBackground = true;
-
- _receiveThread.Start ();
- }
-
- private void stop (ushort code, string reason)
- {
- lock (_sync) {
- if (_state != ServerState.Start)
- return;
-
- _state = ServerState.ShuttingDown;
- }
-
- try {
- var timeout = 5000;
-
- stopReceiving (timeout);
- }
- catch (Exception ex) {
- _log.Fatal (ex.Message);
- _log.Debug (ex.ToString ());
- }
-
- try {
- _services.Stop (code, reason);
- }
- catch (Exception ex) {
- _log.Fatal (ex.Message);
- _log.Debug (ex.ToString ());
- }
-
- _state = ServerState.Stop;
- }
-
- private void stopReceiving (int millisecondsTimeout)
- {
- _listener.Stop ();
- _receiveThread.Join (millisecondsTimeout);
- }
-
- private static bool tryCreateUri (
- string uriString,
- out Uri result,
- out string message
- )
- {
- if (!uriString.TryCreateWebSocketUri (out result, out message))
- return false;
-
- if (result.PathAndQuery != "/") {
- result = null;
- message = "It includes either or both path and query components.";
-
- return false;
- }
-
- return true;
- }
-
- #endregion
-
- #region Public Methods
-
- ///
- /// Adds a WebSocket service with the specified behavior and path.
- ///
- ///
- ///
- /// A that specifies an absolute path to
- /// the service to add.
- ///
- ///
- /// / is trimmed from the end of the string if present.
- ///
- ///
- ///
- ///
- /// The type of the behavior for the service.
- ///
- ///
- /// It must inherit the class.
- ///
- ///
- /// Also it must have a public parameterless constructor.
- ///
- ///
- ///
- ///
- /// is an empty string.
- ///
- ///
- /// -or-
- ///
- ///
- /// is not an absolute path.
- ///
- ///
- /// -or-
- ///
- ///
- /// includes either or both
- /// query and fragment components.
- ///
- ///
- /// -or-
- ///
- ///
- /// is already in use.
- ///
- ///
- ///
- /// is .
- ///
- public void AddWebSocketService (string path)
- where TBehavior : WebSocketBehavior, new ()
- {
- _services.AddService (path, null);
- }
-
- ///
- /// Adds a WebSocket service with the specified behavior, path,
- /// and initializer.
- ///
- ///
- ///
- /// A that specifies an absolute path to
- /// the service to add.
- ///
- ///
- /// / is trimmed from the end of the string if present.
- ///
- ///
- ///
- ///
- /// An delegate.
- ///
- ///
- /// It specifies the delegate called when the service initializes
- /// a new session instance.
- ///
- ///
- /// if not necessary.
- ///
- ///
- ///
- ///
- /// The type of the behavior for the service.
- ///
- ///
- /// It must inherit the