Fix for the secure connection
This commit is contained in:
parent
49dc8800d3
commit
3e6c589953
@ -8,17 +8,17 @@ using System.Threading;
|
|||||||
using WebSocketSharp;
|
using WebSocketSharp;
|
||||||
using WebSocketSharp.Net;
|
using WebSocketSharp.Net;
|
||||||
|
|
||||||
namespace Example
|
namespace Example {
|
||||||
{
|
|
||||||
public struct NfMessage
|
public struct NfMessage {
|
||||||
{
|
|
||||||
public string Summary;
|
public string Summary;
|
||||||
public string Body;
|
public string Body;
|
||||||
public string Icon;
|
public string Icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ThreadState
|
public class ThreadState {
|
||||||
{
|
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
public AutoResetEvent Notification { get; private set; }
|
public AutoResetEvent Notification { get; private set; }
|
||||||
|
|
||||||
@ -29,8 +29,8 @@ namespace Example
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Program
|
public class Program {
|
||||||
{
|
|
||||||
private static Queue _msgQ = Queue.Synchronized(new Queue());
|
private static Queue _msgQ = Queue.Synchronized(new Queue());
|
||||||
|
|
||||||
private static void enNfMessage(string summary, string body, string icon)
|
private static void enNfMessage(string summary, string body, string icon)
|
||||||
@ -47,7 +47,7 @@ namespace Example
|
|||||||
|
|
||||||
public static void Main(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
ThreadState ts = new ThreadState();
|
var ts = new ThreadState();
|
||||||
|
|
||||||
WaitCallback notifyMsg = state =>
|
WaitCallback notifyMsg = state =>
|
||||||
{
|
{
|
||||||
@ -57,11 +57,9 @@ namespace Example
|
|||||||
|
|
||||||
if (_msgQ.Count > 0)
|
if (_msgQ.Count > 0)
|
||||||
{
|
{
|
||||||
NfMessage msg = (NfMessage)_msgQ.Dequeue();
|
var msg = (NfMessage)_msgQ.Dequeue();
|
||||||
#if NOTIFY
|
#if NOTIFY
|
||||||
Notification nf = new Notification(msg.Summary,
|
var nf = new Notification(msg.Summary, msg.Body, msg.Icon);
|
||||||
msg.Body,
|
|
||||||
msg.Icon);
|
|
||||||
nf.AddHint("append", "allowed");
|
nf.AddHint("append", "allowed");
|
||||||
nf.Show();
|
nf.Show();
|
||||||
#else
|
#else
|
||||||
@ -75,15 +73,16 @@ namespace Example
|
|||||||
|
|
||||||
ThreadPool.QueueUserWorkItem(notifyMsg);
|
ThreadPool.QueueUserWorkItem(notifyMsg);
|
||||||
|
|
||||||
using (WebSocket ws = new WebSocket("ws://echo.websocket.org", "echo"))
|
using (var ws = new WebSocket("ws://echo.websocket.org", "echo"))
|
||||||
//using (WebSocket ws = new WebSocket("wss://echo.websocket.org", "echo"))
|
//using (var ws = new WebSocket("wss://echo.websocket.org", "echo"))
|
||||||
//using (WebSocket ws = new WebSocket("ws://localhost:4649"))
|
//using (var ws = new WebSocket("ws://localhost:4649"))
|
||||||
//using (WebSocket ws = new WebSocket("ws://localhost:4649/Echo"))
|
//using (var ws = new WebSocket("ws://localhost:4649/Echo"))
|
||||||
//using (WebSocket ws = new WebSocket("ws://localhost:4649/Echo?name=nobita"))
|
//using (var ws = new WebSocket("wss://localhost:4649/Echo"))
|
||||||
//using (WebSocket ws = new WebSocket("ws://localhost:4649/エコー?name=のび太"))
|
//using (var ws = new WebSocket("ws://localhost:4649/Echo?name=nobita"))
|
||||||
//using (WebSocket ws = new WebSocket("ws://localhost:4649/Chat"))
|
//using (var ws = new WebSocket("ws://localhost:4649/エコー?name=のび太"))
|
||||||
//using (WebSocket ws = new WebSocket("ws://localhost:4649/Chat?name=nobita"))
|
//using (var ws = new WebSocket("ws://localhost:4649/Chat"))
|
||||||
//using (WebSocket ws = new WebSocket("ws://localhost:4649/チャット?name=のび太"))
|
//using (var ws = new WebSocket("ws://localhost:4649/Chat?name=nobita"))
|
||||||
|
//using (var ws = new WebSocket("ws://localhost:4649/チャット?name=のび太"))
|
||||||
{
|
{
|
||||||
ws.OnOpen += (sender, e) =>
|
ws.OnOpen += (sender, e) =>
|
||||||
{
|
{
|
||||||
@ -111,11 +110,16 @@ namespace Example
|
|||||||
"notification-message-im");
|
"notification-message-im");
|
||||||
};
|
};
|
||||||
|
|
||||||
//ws.Origin = "http://echo.websocket.org";
|
|
||||||
//ws.Compression = CompressionMethod.DEFLATE;
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
ws.Log.Level = LogLevel.TRACE;
|
ws.Log.Level = LogLevel.TRACE;
|
||||||
#endif
|
#endif
|
||||||
|
//ws.Compression = CompressionMethod.DEFLATE;
|
||||||
|
//ws.Origin = "http://echo.websocket.org";
|
||||||
|
//ws.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) =>
|
||||||
|
//{
|
||||||
|
// ws.Log.Debug(String.Format("\n{0}\n{1}", certificate.Issuer, certificate.Subject));
|
||||||
|
// return true;
|
||||||
|
//};
|
||||||
//ws.SetCookie(new Cookie("nobita", "\"idiot, gunfighter\""));
|
//ws.SetCookie(new Cookie("nobita", "\"idiot, gunfighter\""));
|
||||||
//ws.SetCookie(new Cookie("dora", "tanuki"));
|
//ws.SetCookie(new Cookie("dora", "tanuki"));
|
||||||
ws.Connect();
|
ws.Connect();
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<appSettings>
|
<appSettings>
|
||||||
<add key="ServerCertPath" value="/path/to/server.cer" />
|
<add key="ServerCertFile" value="/path/to/cert.pfx"/>
|
||||||
|
<add key="CertFilePassword" value="password"/>
|
||||||
</appSettings>
|
</appSettings>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Configuration" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="AssemblyInfo.cs" />
|
<Compile Include="AssemblyInfo.cs" />
|
||||||
|
@ -1,16 +1,18 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Configuration;
|
||||||
|
using System.Security.Cryptography.X509Certificates;
|
||||||
using WebSocketSharp;
|
using WebSocketSharp;
|
||||||
using WebSocketSharp.Server;
|
using WebSocketSharp.Server;
|
||||||
|
|
||||||
namespace Example2
|
namespace Example2 {
|
||||||
{
|
|
||||||
public class Program
|
public class Program {
|
||||||
{
|
|
||||||
public static void Main (string [] args)
|
public static void Main (string [] args)
|
||||||
{
|
{
|
||||||
/* Single service server
|
/* Single service server
|
||||||
//var wssv = new WebSocketServiceHost<Echo>("ws://localhost:4649");
|
var wssv = new WebSocketServiceHost<Echo> ("ws://localhost:4649");
|
||||||
var wssv = new WebSocketServiceHost<Echo>("ws://localhost:4649/Echo");
|
//var wssv = new WebSocketServiceHost<Echo> ("ws://localhost:4649/Echo");
|
||||||
//var wssv = new WebSocketServiceHost<Echo> ("ws://localhost:4649/エコー");
|
//var wssv = new WebSocketServiceHost<Echo> ("ws://localhost:4649/エコー");
|
||||||
//var wssv = new WebSocketServiceHost<Echo> (4649);
|
//var wssv = new WebSocketServiceHost<Echo> (4649);
|
||||||
//var wssv = new WebSocketServiceHost<Echo> (4649, "/Echo");
|
//var wssv = new WebSocketServiceHost<Echo> (4649, "/Echo");
|
||||||
@ -21,7 +23,10 @@ namespace Example2
|
|||||||
//var wssv = new WebSocketServiceHost<Chat> (4649);
|
//var wssv = new WebSocketServiceHost<Chat> (4649);
|
||||||
//var wssv = new WebSocketServiceHost<Chat> (4649, "/Chat");
|
//var wssv = new WebSocketServiceHost<Chat> (4649, "/Chat");
|
||||||
//var wssv = new WebSocketServiceHost<Chat> (4649, "/チャット");
|
//var wssv = new WebSocketServiceHost<Chat> (4649, "/チャット");
|
||||||
//wssv.Sweeping = false; // Stop the sweep inactive session timer.
|
#if DEBUG
|
||||||
|
wssv.Log.Level = LogLevel.TRACE;
|
||||||
|
#endif
|
||||||
|
//wssv.Sweeping = false;
|
||||||
|
|
||||||
wssv.Start ();
|
wssv.Start ();
|
||||||
Console.WriteLine (
|
Console.WriteLine (
|
||||||
@ -29,13 +34,18 @@ namespace Example2
|
|||||||
wssv.Uri, wssv.Address, wssv.Port);
|
wssv.Uri, wssv.Address, wssv.Port);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Multi services server
|
/* Multi services server */
|
||||||
var wssv = new WebSocketServer (4649);
|
var wssv = new WebSocketServer (4649);
|
||||||
|
//var wssv = new WebSocketServer (4649, true);
|
||||||
//var wssv = new WebSocketServer ("ws://localhost:4649");
|
//var wssv = new WebSocketServer ("ws://localhost:4649");
|
||||||
|
//var wssv = new WebSocketServer ("wss://localhost:4649");
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
wssv.Log.Level = LogLevel.TRACE;
|
wssv.Log.Level = LogLevel.TRACE;
|
||||||
#endif
|
#endif
|
||||||
//wssv.Sweeping = false; // Stop the sweep inactive session timer.
|
//var file = ConfigurationManager.AppSettings ["ServerCertFile"];
|
||||||
|
//var password = ConfigurationManager.AppSettings ["CertFilePassword"];
|
||||||
|
//wssv.Certificate = new X509Certificate2 (file, password);
|
||||||
|
//wssv.Sweeping = false;
|
||||||
wssv.AddWebSocketService<Echo> ("/Echo");
|
wssv.AddWebSocketService<Echo> ("/Echo");
|
||||||
wssv.AddWebSocketService<Chat> ("/Chat");
|
wssv.AddWebSocketService<Chat> ("/Chat");
|
||||||
//wssv.AddWebSocketService<Echo> ("/エコー");
|
//wssv.AddWebSocketService<Echo> ("/エコー");
|
||||||
@ -46,10 +56,9 @@ namespace Example2
|
|||||||
"WebSocket Server listening on port: {0} service path:", wssv.Port);
|
"WebSocket Server listening on port: {0} service path:", wssv.Port);
|
||||||
foreach (var path in wssv.ServicePaths)
|
foreach (var path in wssv.ServicePaths)
|
||||||
Console.WriteLine (" {0}", path);
|
Console.WriteLine (" {0}", path);
|
||||||
|
|
||||||
Console.WriteLine ();
|
Console.WriteLine ();
|
||||||
|
Console.WriteLine ("Press enter key to stop server...");
|
||||||
|
|
||||||
Console.WriteLine("Press any key to stop server...");
|
|
||||||
Console.ReadLine ();
|
Console.ReadLine ();
|
||||||
|
|
||||||
wssv.Stop ();
|
wssv.Stop ();
|
||||||
|
62
README.md
62
README.md
@ -71,7 +71,7 @@ ws.OnOpen += (sender, e) =>
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
`e` has come across as `EventArgs.Empty`, so there is no operation on `e`.
|
`e` has come across as `EventArgs.Empty`, so you don't use `e`.
|
||||||
|
|
||||||
##### WebSocket.OnMessage event #####
|
##### WebSocket.OnMessage event #####
|
||||||
|
|
||||||
@ -84,7 +84,11 @@ ws.OnMessage += (sender, e) =>
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
`e.Type` (`WebSocketSharp.MessageEventArgs.Type`, the type of this property is `WebSocketSharp.Opcode`) indicates the **Frame type** of a WebSocket frame, so by checking this property, you determine which item you should operate.
|
`e.Type` (`WebSocketSharp.MessageEventArgs.Type`, the type of this property is `WebSocketSharp.Opcode`) indicates the **Frame Type** of a WebSocket frame, so by checking this property, you determine which item you should use.
|
||||||
|
|
||||||
|
If `e.Type` equals `Opcode.TEXT`, you use `e.Data` (`WebSocketSharp.MessageEventArgs.Data`, the type of this property is `string`) that contains the received data.
|
||||||
|
|
||||||
|
If `e.Type` equals `Opcode.BINARY`, you use `e.RawData` (`WebSocketSharp.MessageEventArgs.RawData`, the type of this property is `byte[]`) that contains the received data.
|
||||||
|
|
||||||
```cs
|
```cs
|
||||||
if (e.Type == Opcode.TEXT)
|
if (e.Type == Opcode.TEXT)
|
||||||
@ -100,10 +104,6 @@ if (e.Type == Opcode.BINARY)
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
If `e.Type` equaled `Opcode.TEXT`, you would operate `e.Data` (`WebSocketSharp.MessageEventArgs.Data`, the type of this property is `string`).
|
|
||||||
|
|
||||||
If `e.Type` equaled `Opcode.BINARY`, you would operate `e.RawData` (`WebSocketSharp.MessageEventArgs.RawData`, the type of this property is `byte[]`).
|
|
||||||
|
|
||||||
##### WebSocket.OnError event #####
|
##### WebSocket.OnError event #####
|
||||||
|
|
||||||
A `WebSocket.OnError` event occurs when the `WebSocket` gets an error.
|
A `WebSocket.OnError` event occurs when the `WebSocket` gets an error.
|
||||||
@ -114,7 +114,7 @@ ws.OnError += (sender, e) =>
|
|||||||
...
|
...
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
`e.Message` (`WebSocketSharp.ErrorEventArgs.Message`, the type of this property is `string`) contains an error message, so you operate this.
|
`e.Message` (`WebSocketSharp.ErrorEventArgs.Message`, the type of this property is `string`) contains an error message, so you use this.
|
||||||
|
|
||||||
##### WebSocket.OnClose event #####
|
##### WebSocket.OnClose event #####
|
||||||
|
|
||||||
@ -127,7 +127,7 @@ ws.OnClose += (sender, e) =>
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
`e.Code` (`WebSocketSharp.CloseEventArgs.Code`, the type of this property is `ushort`) contains a status code indicating the reason for closure and `e.Reason` (`WebSocketSharp.CloseEventArgs.Reason`, the type of this property is `string`) contains the reason for closure, so you operate these.
|
`e.Code` (`WebSocketSharp.CloseEventArgs.Code`, the type of this property is `ushort`) contains a status code indicating the reason for closure and `e.Reason` (`WebSocketSharp.CloseEventArgs.Reason`, the type of this property is `string`) contains the reason for closure, so you use these.
|
||||||
|
|
||||||
#### Step 4 ####
|
#### Step 4 ####
|
||||||
|
|
||||||
@ -157,7 +157,7 @@ Closing the WebSocket connection.
|
|||||||
ws.Close(code, reason);
|
ws.Close(code, reason);
|
||||||
```
|
```
|
||||||
|
|
||||||
If you wanted to close the WebSocket connection explicitly, you would use the `Close` method.
|
If you want to close the WebSocket connection explicitly, you can use the `Close` method.
|
||||||
|
|
||||||
And the `Close` method is overloaded. The types of `code` are `WebSocketSharp.CloseStatusCode` and `ushort`, the type of `reason` is `string`.
|
And the `Close` method is overloaded. The types of `code` are `WebSocketSharp.CloseStatusCode` and `ushort`, the type of `reason` is `string`.
|
||||||
|
|
||||||
@ -176,7 +176,7 @@ namespace Example {
|
|||||||
{
|
{
|
||||||
protected override void OnMessage(MessageEventArgs e)
|
protected override void OnMessage(MessageEventArgs e)
|
||||||
{
|
{
|
||||||
var msg = e.Data.ToLower().Equals("balus")
|
var msg = e.Data.ToLower() == "balus"
|
||||||
? "I've been balused already..."
|
? "I've been balused already..."
|
||||||
: "I'm not available now.";
|
: "I'm not available now.";
|
||||||
Send(msg);
|
Send(msg);
|
||||||
@ -266,7 +266,7 @@ You can add any WebSocket service with a specified path to the service to your `
|
|||||||
|
|
||||||
The type of `T` inherits `WebSocketService` class, so you can use a class that was created in **Step 2**.
|
The type of `T` inherits `WebSocketService` class, so you can use a class that was created in **Step 2**.
|
||||||
|
|
||||||
If you created a instance of the `WebSocketServer` class without the port number, the `WebSocketServer` would set the port number to **80** automatically. So it is necessary to run with root permission.
|
If you create a instance of the `WebSocketServer` class without the port number, the `WebSocketServer` set the port number to **80** automatically. So it is necessary to run with root permission.
|
||||||
|
|
||||||
$ sudo mono example2.exe
|
$ sudo mono example2.exe
|
||||||
|
|
||||||
@ -285,7 +285,7 @@ wssv.OnError += (sender, e) =>
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
`e.Message` (`WebSocketSharp.ErrorEventArgs.Message`, the type of this property is `string`) contains an error message, so you operate this.
|
`e.Message` (`WebSocketSharp.ErrorEventArgs.Message`, the type of this property is `string`) contains an error message, so you use this.
|
||||||
|
|
||||||
##### WebSocketServer.OnError event #####
|
##### WebSocketServer.OnError event #####
|
||||||
|
|
||||||
@ -320,21 +320,51 @@ httpsv.AddWebSocketService<Echo>("/");
|
|||||||
|
|
||||||
For more information, could you see **[Example3]**?
|
For more information, could you see **[Example3]**?
|
||||||
|
|
||||||
|
### Secure Connection ###
|
||||||
|
|
||||||
|
As a **WebSocket Client**, creating a instance of the `WebSocket` class with the WebSocket URL with the **wss** scheme.
|
||||||
|
|
||||||
|
```cs
|
||||||
|
using (var ws = new WebSocket("wss://example.com"))
|
||||||
|
{
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If you want to set the custom validation for the server certificate, you can use the `WebSocket.ServerCertificateValidationCallback` property.
|
||||||
|
|
||||||
|
```cs
|
||||||
|
ws.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) =>
|
||||||
|
{
|
||||||
|
// Do something to validate the server certificate.
|
||||||
|
return true; // The server certificate is valid.
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
If you set this property to nothing, the validation does nothing with the server certificate, always returns valid.
|
||||||
|
|
||||||
|
As a **WebSocket Server**, creating and setting a instance of the WebSocket server with some settings for the secure connection.
|
||||||
|
|
||||||
|
```cs
|
||||||
|
var wssv = new WebSocketServer(4649, true);
|
||||||
|
wssv.Certificate = new X509Certificate2("/path/to/cert.pfx", "password for cert.pfx");
|
||||||
|
```
|
||||||
|
|
||||||
### Logging ###
|
### Logging ###
|
||||||
|
|
||||||
The `WebSocket` class includes own logging functions.
|
The `WebSocket` class includes own logging functions.
|
||||||
|
|
||||||
The `WebSocket.Log` property provides the logging functions.
|
The `WebSocket.Log` property provides the logging functions.
|
||||||
|
|
||||||
If you wanted to change the current logging level (the default is the `LogLevel.ERROR`), you would operate the `WebSocket.Log.Level` property.
|
If you want to change the current logging level (the default is `LogLevel.ERROR`), you can use the `WebSocket.Log.Level` property.
|
||||||
|
|
||||||
```cs
|
```cs
|
||||||
ws.Log.Level = LogLevel.DEBUG;
|
ws.Log.Level = LogLevel.DEBUG;
|
||||||
```
|
```
|
||||||
|
|
||||||
This setting means that the logging outputs with a less than the `LogLevel.DEBUG` are not outputted.
|
This setting means that the logging outputs with a less than `LogLevel.DEBUG` are not outputted.
|
||||||
|
|
||||||
And if you wanted to output a log, you would use some output methods. The following outputs a log with the `LogLevel.DEBUG`.
|
And if you want to output a log, you can use some output methods. The following outputs a log with `LogLevel.DEBUG`.
|
||||||
|
|
||||||
```cs
|
```cs
|
||||||
ws.Log.Debug("This is a debug message.");
|
ws.Log.Debug("This is a debug message.");
|
||||||
@ -354,7 +384,7 @@ Examples of using **websocket-sharp**.
|
|||||||
|
|
||||||
[Example1] connects to the [Audio Data delivery server] using the WebSocket ([Example1] is only implemented the chat feature, still unfinished).
|
[Example1] connects to the [Audio Data delivery server] using the WebSocket ([Example1] is only implemented the chat feature, still unfinished).
|
||||||
|
|
||||||
And [Example1] uses the [Json.NET].
|
And [Example1] uses [Json.NET].
|
||||||
|
|
||||||
### Example2 ###
|
### Example2 ###
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ using System.Runtime.CompilerServices;
|
|||||||
// Change them to the values specific to your project.
|
// Change them to the values specific to your project.
|
||||||
|
|
||||||
[assembly: AssemblyTitle("websocket-sharp")]
|
[assembly: AssemblyTitle("websocket-sharp")]
|
||||||
[assembly: AssemblyDescription("A C# implementation of the WebSocket protocol client & server")]
|
[assembly: AssemblyDescription("A C# implementation of the WebSocket protocol client and server")]
|
||||||
[assembly: AssemblyConfiguration("")]
|
[assembly: AssemblyConfiguration("")]
|
||||||
[assembly: AssemblyCompany("")]
|
[assembly: AssemblyCompany("")]
|
||||||
[assembly: AssemblyProduct("websocket-sharp.dll")]
|
[assembly: AssemblyProduct("websocket-sharp.dll")]
|
||||||
|
@ -45,6 +45,7 @@ using System.IO;
|
|||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
|
using System.Security.Cryptography.X509Certificates;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using WebSocketSharp.Net;
|
using WebSocketSharp.Net;
|
||||||
using WebSocketSharp.Net.WebSockets;
|
using WebSocketSharp.Net.WebSockets;
|
||||||
@ -282,6 +283,12 @@ namespace WebSocketSharp {
|
|||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static TcpListenerWebSocketContext GetWebSocketContext(
|
||||||
|
this TcpClient client, bool secure, X509Certificate cert)
|
||||||
|
{
|
||||||
|
return new TcpListenerWebSocketContext(client, secure, cert);
|
||||||
|
}
|
||||||
|
|
||||||
// <summary>
|
// <summary>
|
||||||
// Determines whether the specified object is <see langword="null"/>.
|
// Determines whether the specified object is <see langword="null"/>.
|
||||||
// </summary>
|
// </summary>
|
||||||
@ -532,60 +539,6 @@ namespace WebSocketSharp {
|
|||||||
|
|
||||||
#region Public Methods
|
#region Public Methods
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Accepts a WebSocket connection by the <see cref="TcpListener"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>
|
|
||||||
/// A <see cref="TcpListenerWebSocketContext"/> that contains a WebSocket connection.
|
|
||||||
/// </returns>
|
|
||||||
/// <param name="listener">
|
|
||||||
/// A <see cref="TcpListener"/> that provides a TCP connection to accept a WebSocket connection.
|
|
||||||
/// </param>
|
|
||||||
/// <param name="secure">
|
|
||||||
/// A <see cref="bool"/> that indicates a secure connection or not. (<c>true</c> indicates a secure connection.)
|
|
||||||
/// </param>
|
|
||||||
/// <exception cref="ArgumentNullException">
|
|
||||||
/// <paramref name="listener"/> is <see langword="null"/>.
|
|
||||||
/// </exception>
|
|
||||||
public static TcpListenerWebSocketContext AcceptWebSocket(this TcpListener listener, bool secure)
|
|
||||||
{
|
|
||||||
if (listener == null)
|
|
||||||
throw new ArgumentNullException("listener");
|
|
||||||
|
|
||||||
var client = listener.AcceptTcpClient();
|
|
||||||
return new TcpListenerWebSocketContext(client, secure);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Accepts a WebSocket connection asynchronously by the <see cref="TcpListener"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="listener">
|
|
||||||
/// A <see cref="TcpListener"/> that provides a TCP connection to accept a WebSocket connection.
|
|
||||||
/// </param>
|
|
||||||
/// <param name="secure">
|
|
||||||
/// A <see cref="bool"/> that indicates a secure connection or not. (<c>true</c> indicates a secure connection.)
|
|
||||||
/// </param>
|
|
||||||
/// <param name="completed">
|
|
||||||
/// An Action<TcpListenerWebSocketContext> delegate that contains the method(s) that is called when an asynchronous operation completes.
|
|
||||||
/// </param>
|
|
||||||
/// <exception cref="ArgumentNullException">
|
|
||||||
/// <paramref name="listener"/> is <see langword="null"/>.
|
|
||||||
/// </exception>
|
|
||||||
public static void AcceptWebSocketAsync(this TcpListener listener, bool secure, Action<TcpListenerWebSocketContext> completed)
|
|
||||||
{
|
|
||||||
if (listener == null)
|
|
||||||
throw new ArgumentNullException("listener");
|
|
||||||
|
|
||||||
AsyncCallback callback = (ar) =>
|
|
||||||
{
|
|
||||||
var client = listener.EndAcceptTcpClient(ar);
|
|
||||||
var context = new TcpListenerWebSocketContext(client, secure);
|
|
||||||
completed(context);
|
|
||||||
};
|
|
||||||
|
|
||||||
listener.BeginAcceptTcpClient(callback, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether the specified <see cref="string"/> contains any of characters
|
/// Determines whether the specified <see cref="string"/> contains any of characters
|
||||||
/// in the specified array of <see cref="char"/>.
|
/// in the specified array of <see cref="char"/>.
|
||||||
|
@ -30,12 +30,13 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
|
using System.Security.Cryptography.X509Certificates;
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
|
|
||||||
namespace WebSocketSharp.Net.WebSockets {
|
namespace WebSocketSharp.Net.WebSockets {
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Provides access to the WebSocket connection request objects received by the <see cref="TcpListener"/> class.
|
/// Provides access to the WebSocket connection request objects received by the <see cref="TcpListener"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
@ -44,22 +45,22 @@ namespace WebSocketSharp.Net.WebSockets {
|
|||||||
#region Private Fields
|
#region Private Fields
|
||||||
|
|
||||||
private CookieCollection _cookies;
|
private CookieCollection _cookies;
|
||||||
private TcpClient _tcpClient;
|
private TcpClient _client;
|
||||||
private bool _isSecure;
|
|
||||||
private RequestHandshake _request;
|
private RequestHandshake _request;
|
||||||
|
private bool _secure;
|
||||||
|
private WsStream _stream;
|
||||||
private WebSocket _websocket;
|
private WebSocket _websocket;
|
||||||
private WsStream _wsStream;
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Internal Constructors
|
#region Internal Constructors
|
||||||
|
|
||||||
internal TcpListenerWebSocketContext(TcpClient tcpClient, bool secure)
|
internal TcpListenerWebSocketContext(TcpClient client, bool secure, X509Certificate cert)
|
||||||
{
|
{
|
||||||
_tcpClient = tcpClient;
|
_client = client;
|
||||||
_isSecure = secure;
|
_secure = secure;
|
||||||
_wsStream = WsStream.CreateServerStream(tcpClient, secure);
|
_stream = WsStream.CreateServerStream(client, secure, cert);
|
||||||
_request = RequestHandshake.Parse(_wsStream.ReadHandshake());
|
_request = RequestHandshake.Parse(_stream.ReadHandshake());
|
||||||
_websocket = new WebSocket(this);
|
_websocket = new WebSocket(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +70,7 @@ namespace WebSocketSharp.Net.WebSockets {
|
|||||||
|
|
||||||
internal WsStream Stream {
|
internal WsStream Stream {
|
||||||
get {
|
get {
|
||||||
return _wsStream;
|
return _stream;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,7 +86,7 @@ namespace WebSocketSharp.Net.WebSockets {
|
|||||||
/// </value>
|
/// </value>
|
||||||
public override CookieCollection CookieCollection {
|
public override CookieCollection CookieCollection {
|
||||||
get {
|
get {
|
||||||
if (_cookies.IsNull())
|
if (_cookies == null)
|
||||||
_cookies = _request.Cookies;
|
_cookies = _request.Cookies;
|
||||||
|
|
||||||
return _cookies;
|
return _cookies;
|
||||||
@ -139,7 +140,7 @@ namespace WebSocketSharp.Net.WebSockets {
|
|||||||
/// </value>
|
/// </value>
|
||||||
public override bool IsSecureConnection {
|
public override bool IsSecureConnection {
|
||||||
get {
|
get {
|
||||||
return _isSecure;
|
return _secure;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -260,7 +261,7 @@ namespace WebSocketSharp.Net.WebSockets {
|
|||||||
/// </value>
|
/// </value>
|
||||||
public virtual System.Net.IPEndPoint ServerEndPoint {
|
public virtual System.Net.IPEndPoint ServerEndPoint {
|
||||||
get {
|
get {
|
||||||
return (System.Net.IPEndPoint)_tcpClient.Client.LocalEndPoint;
|
return (System.Net.IPEndPoint)_client.Client.LocalEndPoint;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,7 +288,7 @@ namespace WebSocketSharp.Net.WebSockets {
|
|||||||
/// </value>
|
/// </value>
|
||||||
public virtual System.Net.IPEndPoint UserEndPoint {
|
public virtual System.Net.IPEndPoint UserEndPoint {
|
||||||
get {
|
get {
|
||||||
return (System.Net.IPEndPoint)_tcpClient.Client.RemoteEndPoint;
|
return (System.Net.IPEndPoint)_client.Client.RemoteEndPoint;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,8 +310,8 @@ namespace WebSocketSharp.Net.WebSockets {
|
|||||||
|
|
||||||
internal void Close()
|
internal void Close()
|
||||||
{
|
{
|
||||||
_wsStream.Close();
|
_stream.Close();
|
||||||
_tcpClient.Close();
|
_client.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -30,6 +30,7 @@ using System;
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
|
using System.Security.Cryptography.X509Certificates;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using WebSocketSharp.Net.WebSockets;
|
using WebSocketSharp.Net.WebSockets;
|
||||||
|
|
||||||
@ -46,13 +47,14 @@ namespace WebSocketSharp.Server {
|
|||||||
#region Private Fields
|
#region Private Fields
|
||||||
|
|
||||||
private IPAddress _address;
|
private IPAddress _address;
|
||||||
|
private X509Certificate2 _cert;
|
||||||
private bool _listening;
|
private bool _listening;
|
||||||
private Logger _logger;
|
private Logger _logger;
|
||||||
private int _port;
|
private int _port;
|
||||||
private Thread _receiveRequestThread;
|
private Thread _receiveRequestThread;
|
||||||
private bool _secure;
|
private bool _secure;
|
||||||
private bool _selfHost;
|
private bool _selfHost;
|
||||||
private TcpListener _tcpListener;
|
private TcpListener _listener;
|
||||||
private Uri _uri;
|
private Uri _uri;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@ -63,7 +65,7 @@ namespace WebSocketSharp.Server {
|
|||||||
/// Initializes a new instance of the <see cref="WebSocketServerBase"/> class.
|
/// Initializes a new instance of the <see cref="WebSocketServerBase"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// This constructor initializes a new instance of this class as non self host.
|
/// This constructor initializes a new instance of this class as non self hosted server.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
protected WebSocketServerBase()
|
protected WebSocketServerBase()
|
||||||
: this(new Logger())
|
: this(new Logger())
|
||||||
@ -75,7 +77,7 @@ namespace WebSocketSharp.Server {
|
|||||||
/// with the specified <paramref name="logger"/>.
|
/// with the specified <paramref name="logger"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// This constructor initializes a new instance of this class as non self host.
|
/// This constructor initializes a new instance of this class as non self hosted server.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <param name="logger">
|
/// <param name="logger">
|
||||||
/// A <see cref="Logger"/> that provides the logging functions.
|
/// A <see cref="Logger"/> that provides the logging functions.
|
||||||
@ -208,6 +210,25 @@ namespace WebSocketSharp.Server {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the certificate used to authenticate the server on the secure connection.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// A <see cref="X509Certificate2"/> used to authenticate the server.
|
||||||
|
/// </value>
|
||||||
|
public X509Certificate2 Certificate {
|
||||||
|
get {
|
||||||
|
return _cert;
|
||||||
|
}
|
||||||
|
|
||||||
|
set {
|
||||||
|
if (_listening)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_cert = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a value indicating whether the server has been started.
|
/// Gets a value indicating whether the server has been started.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -303,7 +324,7 @@ namespace WebSocketSharp.Server {
|
|||||||
_listening = false;
|
_listening = false;
|
||||||
_logger = new Logger();
|
_logger = new Logger();
|
||||||
_selfHost = true;
|
_selfHost = true;
|
||||||
_tcpListener = new TcpListener(_address, _port);
|
_listener = new TcpListener(_address, _port);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void init(Uri uri)
|
private void init(Uri uri)
|
||||||
@ -320,13 +341,13 @@ namespace WebSocketSharp.Server {
|
|||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processRequestAsync(TcpListenerWebSocketContext context)
|
private void processRequestAsync(TcpClient client)
|
||||||
{
|
{
|
||||||
WaitCallback callback = (state) =>
|
WaitCallback callback = state =>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
AcceptWebSocket(context);
|
AcceptWebSocket(client.GetWebSocketContext(_secure, _cert));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -344,11 +365,11 @@ namespace WebSocketSharp.Server {
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
processRequestAsync(_tcpListener.AcceptWebSocket(_secure));
|
processRequestAsync(_listener.AcceptTcpClient());
|
||||||
}
|
}
|
||||||
catch (SocketException)
|
catch (SocketException)
|
||||||
{
|
{
|
||||||
// TcpListener has been stopped.
|
_logger.Info("TcpListener has been stopped.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -368,7 +389,7 @@ namespace WebSocketSharp.Server {
|
|||||||
_receiveRequestThread.Start();
|
_receiveRequestThread.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool tryCreateUri(string uriString, out Uri result, out string message)
|
private static bool tryCreateUri(string uriString, out Uri result, out string message)
|
||||||
{
|
{
|
||||||
if (!uriString.TryCreateWebSocketUri(out result, out message))
|
if (!uriString.TryCreateWebSocketUri(out result, out message))
|
||||||
return false;
|
return false;
|
||||||
@ -422,7 +443,16 @@ namespace WebSocketSharp.Server {
|
|||||||
if (!_selfHost || _listening)
|
if (!_selfHost || _listening)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_tcpListener.Start();
|
if (_secure && _cert == null)
|
||||||
|
{
|
||||||
|
var msg = "Secure connection requires a server certificate.";
|
||||||
|
_logger.Error(msg);
|
||||||
|
error(msg);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_listener.Start();
|
||||||
startReceiveRequestThread();
|
startReceiveRequestThread();
|
||||||
_listening = true;
|
_listening = true;
|
||||||
}
|
}
|
||||||
@ -435,7 +465,7 @@ namespace WebSocketSharp.Server {
|
|||||||
if (!_selfHost || !_listening)
|
if (!_selfHost || !_listening)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_tcpListener.Stop();
|
_listener.Stop();
|
||||||
_receiveRequestThread.Join(5 * 1000);
|
_receiveRequestThread.Join(5 * 1000);
|
||||||
_listening = false;
|
_listening = false;
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,7 @@ using System.Diagnostics;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
|
using System.Net.Security;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
@ -66,6 +67,8 @@ namespace WebSocketSharp {
|
|||||||
#region Private Fields
|
#region Private Fields
|
||||||
|
|
||||||
private string _base64key;
|
private string _base64key;
|
||||||
|
private RemoteCertificateValidationCallback
|
||||||
|
_certValidationCallback;
|
||||||
private bool _client;
|
private bool _client;
|
||||||
private Action _closeContext;
|
private Action _closeContext;
|
||||||
private CookieCollection _cookies;
|
private CookieCollection _cookies;
|
||||||
@ -162,9 +165,8 @@ namespace WebSocketSharp {
|
|||||||
_uri = uri;
|
_uri = uri;
|
||||||
_protocols = protocols.ToString(", ");
|
_protocols = protocols.ToString(", ");
|
||||||
_client = true;
|
_client = true;
|
||||||
_secure = uri.Scheme == "wss"
|
_secure = uri.Scheme == "wss" ? true : false;
|
||||||
? true
|
_base64key = createBase64Key();
|
||||||
: false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -226,6 +228,12 @@ namespace WebSocketSharp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal bool IsOpened {
|
||||||
|
get {
|
||||||
|
return _readyState == WsState.OPEN || _readyState == WsState.CLOSING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Public Properties
|
#region Public Properties
|
||||||
@ -243,8 +251,14 @@ namespace WebSocketSharp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
set {
|
set {
|
||||||
if (isOpened(true))
|
if (IsOpened)
|
||||||
|
{
|
||||||
|
var msg = "The WebSocket connection has already been established.";
|
||||||
|
_logger.Error(msg);
|
||||||
|
error(msg);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_compression = value;
|
_compression = value;
|
||||||
}
|
}
|
||||||
@ -363,19 +377,25 @@ namespace WebSocketSharp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
set {
|
set {
|
||||||
if (isOpened(true))
|
string msg = null;
|
||||||
return;
|
if (IsOpened)
|
||||||
|
{
|
||||||
if (value.IsNullOrEmpty())
|
msg = "The WebSocket connection has already been established.";
|
||||||
|
}
|
||||||
|
else if (value.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
_origin = String.Empty;
|
_origin = String.Empty;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
var origin = new Uri(value);
|
var origin = new Uri(value);
|
||||||
if (!origin.IsAbsoluteUri || origin.Segments.Length > 1)
|
if (!origin.IsAbsoluteUri || origin.Segments.Length > 1)
|
||||||
|
msg = "The syntax of value of Origin must be '<scheme>://<host>[:<port>]'.";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg != null)
|
||||||
{
|
{
|
||||||
var msg = "The syntax of value of Origin must be '<scheme>://<host>[:<port>]'.";
|
|
||||||
_logger.Error(msg);
|
_logger.Error(msg);
|
||||||
error(msg);
|
error(msg);
|
||||||
|
|
||||||
@ -410,6 +430,27 @@ namespace WebSocketSharp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the callback used to validate the certificate supplied by the server.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// If the value of this property is <see langword="null"/>, the validation does nothing
|
||||||
|
/// with the server certificate, always returns valid.
|
||||||
|
/// </remarks>
|
||||||
|
/// <value>
|
||||||
|
/// A <see cref="RemoteCertificateValidationCallback"/> delegate that references the method(s)
|
||||||
|
/// used to validate the server certificate. The default is <see langword="null"/>.
|
||||||
|
/// </value>
|
||||||
|
public RemoteCertificateValidationCallback ServerCertificateValidationCallback {
|
||||||
|
get {
|
||||||
|
return _certValidationCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
set {
|
||||||
|
_certValidationCallback = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the WebSocket URL to connect.
|
/// Gets the WebSocket URL to connect.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -777,7 +818,7 @@ namespace WebSocketSharp {
|
|||||||
// As client
|
// As client
|
||||||
private bool doHandshake()
|
private bool doHandshake()
|
||||||
{
|
{
|
||||||
init();
|
setWsStream();
|
||||||
return processResponseHandshake(sendRequestHandshake());
|
return processResponseHandshake(sendRequestHandshake());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -799,17 +840,6 @@ namespace WebSocketSharp {
|
|||||||
return CompressionMethod.NONE;
|
return CompressionMethod.NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// As client
|
|
||||||
private void init()
|
|
||||||
{
|
|
||||||
_base64key = createBase64Key();
|
|
||||||
|
|
||||||
var host = _uri.DnsSafeHost;
|
|
||||||
var port = _uri.Port;
|
|
||||||
_tcpClient = new TcpClient(host, port);
|
|
||||||
_wsStream = WsStream.CreateClientStream(_tcpClient, host, _secure);
|
|
||||||
}
|
|
||||||
|
|
||||||
// As server
|
// As server
|
||||||
private void init(WebSocketContext context)
|
private void init(WebSocketContext context)
|
||||||
{
|
{
|
||||||
@ -832,21 +862,6 @@ namespace WebSocketSharp {
|
|||||||
: false;
|
: false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool isOpened(bool errorIfOpened)
|
|
||||||
{
|
|
||||||
if (_readyState != WsState.OPEN && _readyState != WsState.CLOSING)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (errorIfOpened)
|
|
||||||
{
|
|
||||||
var msg = "The WebSocket connection has been established already.";
|
|
||||||
_logger.Error(msg);
|
|
||||||
error(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// As server
|
// As server
|
||||||
private bool isValidHostHeader()
|
private bool isValidHostHeader()
|
||||||
{
|
{
|
||||||
@ -1351,6 +1366,15 @@ namespace WebSocketSharp {
|
|||||||
send(res);
|
send(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// As client
|
||||||
|
private void setWsStream()
|
||||||
|
{
|
||||||
|
var host = _uri.DnsSafeHost;
|
||||||
|
var port = _uri.Port;
|
||||||
|
_tcpClient = new TcpClient(host, port);
|
||||||
|
_wsStream = WsStream.CreateClientStream(_tcpClient, _secure, host, _certValidationCallback);
|
||||||
|
}
|
||||||
|
|
||||||
private void startReceiving()
|
private void startReceiving()
|
||||||
{
|
{
|
||||||
_exitReceiving = new AutoResetEvent(false);
|
_exitReceiving = new AutoResetEvent(false);
|
||||||
@ -1480,8 +1504,14 @@ namespace WebSocketSharp {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void Connect()
|
public void Connect()
|
||||||
{
|
{
|
||||||
if (isOpened(true))
|
if (IsOpened)
|
||||||
|
{
|
||||||
|
var msg = "The WebSocket connection has already been established.";
|
||||||
|
_logger.Error(msg);
|
||||||
|
error(msg);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -1690,12 +1720,14 @@ namespace WebSocketSharp {
|
|||||||
/// </param>
|
/// </param>
|
||||||
public void SetCookie(Cookie cookie)
|
public void SetCookie(Cookie cookie)
|
||||||
{
|
{
|
||||||
if (isOpened(true))
|
var msg = IsOpened
|
||||||
return;
|
? "The WebSocket connection has already been established."
|
||||||
|
: cookie == null
|
||||||
|
? "'cookie' must not be null."
|
||||||
|
: null;
|
||||||
|
|
||||||
if (cookie == null)
|
if (msg != null)
|
||||||
{
|
{
|
||||||
var msg = "'cookie' must not be null.";
|
|
||||||
_logger.Error(msg);
|
_logger.Error(msg);
|
||||||
error(msg);
|
error(msg);
|
||||||
|
|
||||||
@ -1723,24 +1755,28 @@ namespace WebSocketSharp {
|
|||||||
/// </param>
|
/// </param>
|
||||||
public void SetCredentials(string userName, string password, bool preAuth)
|
public void SetCredentials(string userName, string password, bool preAuth)
|
||||||
{
|
{
|
||||||
if (isOpened(true))
|
string msg = null;
|
||||||
return;
|
if (IsOpened)
|
||||||
|
{
|
||||||
if (userName == null)
|
msg = "The WebSocket connection has already been established.";
|
||||||
|
}
|
||||||
|
else if (userName == null)
|
||||||
{
|
{
|
||||||
_credentials = null;
|
_credentials = null;
|
||||||
_preAuth = false;
|
_preAuth = false;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
var msg = userName.Length > 0 && (userName.Contains(':') || !userName.IsText())
|
{
|
||||||
|
msg = userName.Length > 0 && (userName.Contains(':') || !userName.IsText())
|
||||||
? "'userName' contains an invalid character."
|
? "'userName' contains an invalid character."
|
||||||
: !password.IsNullOrEmpty() && !password.IsText()
|
: !password.IsNullOrEmpty() && !password.IsText()
|
||||||
? "'password' contains an invalid character."
|
? "'password' contains an invalid character."
|
||||||
: String.Empty;
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
if (msg.Length > 0)
|
if (msg != null)
|
||||||
{
|
{
|
||||||
_logger.Error(msg);
|
_logger.Error(msg);
|
||||||
error(msg);
|
error(msg);
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Configuration;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Security.Cryptography.X509Certificates;
|
using System.Security.Cryptography.X509Certificates;
|
||||||
@ -119,18 +118,20 @@ namespace WebSocketSharp {
|
|||||||
|
|
||||||
#region Internal Methods
|
#region Internal Methods
|
||||||
|
|
||||||
internal static WsStream CreateClientStream(TcpClient tcpClient, string host, bool secure)
|
internal static WsStream CreateClientStream(
|
||||||
|
TcpClient client,
|
||||||
|
bool secure,
|
||||||
|
string host,
|
||||||
|
System.Net.Security.RemoteCertificateValidationCallback validationCallback
|
||||||
|
)
|
||||||
{
|
{
|
||||||
var netStream = tcpClient.GetStream();
|
var netStream = client.GetStream();
|
||||||
if (secure)
|
if (secure)
|
||||||
{
|
{
|
||||||
System.Net.Security.RemoteCertificateValidationCallback callback = (sender, certificate, chain, sslPolicyErrors) =>
|
if (validationCallback == null)
|
||||||
{
|
validationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
|
||||||
// FIXME: Always returns true
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
var sslStream = new SslStream(netStream, false, callback);
|
var sslStream = new SslStream(netStream, false, validationCallback);
|
||||||
sslStream.AuthenticateAsClient(host);
|
sslStream.AuthenticateAsClient(host);
|
||||||
|
|
||||||
return new WsStream(sslStream);
|
return new WsStream(sslStream);
|
||||||
@ -139,14 +140,13 @@ namespace WebSocketSharp {
|
|||||||
return new WsStream(netStream);
|
return new WsStream(netStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static WsStream CreateServerStream(TcpClient tcpClient, bool secure)
|
internal static WsStream CreateServerStream(TcpClient client, bool secure, X509Certificate cert)
|
||||||
{
|
{
|
||||||
var netStream = tcpClient.GetStream();
|
var netStream = client.GetStream();
|
||||||
if (secure)
|
if (secure)
|
||||||
{
|
{
|
||||||
var sslStream = new SslStream(netStream, false);
|
var sslStream = new SslStream(netStream, false);
|
||||||
var certPath = ConfigurationManager.AppSettings["ServerCertPath"];
|
sslStream.AuthenticateAsServer(cert);
|
||||||
sslStream.AuthenticateAsServer(new X509Certificate2(certPath));
|
|
||||||
|
|
||||||
return new WsStream(sslStream);
|
return new WsStream(sslStream);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user