diff --git a/Example/Example.pidb b/Example/Example.pidb index 9ce30c3b..e0dc4a16 100644 Binary files a/Example/Example.pidb and b/Example/Example.pidb differ diff --git a/Example/bin/Debug/example.exe b/Example/bin/Debug/example.exe index e590502e..ef30e8ca 100755 Binary files a/Example/bin/Debug/example.exe and b/Example/bin/Debug/example.exe differ diff --git a/Example/bin/Debug/example.exe.mdb b/Example/bin/Debug/example.exe.mdb index 8f902d8e..043dfc2b 100644 Binary files a/Example/bin/Debug/example.exe.mdb and b/Example/bin/Debug/example.exe.mdb differ diff --git a/Example/bin/Debug/websocket-sharp.dll b/Example/bin/Debug/websocket-sharp.dll index e4a7eb7a..615a2c62 100755 Binary files a/Example/bin/Debug/websocket-sharp.dll and b/Example/bin/Debug/websocket-sharp.dll differ diff --git a/Example/bin/Debug/websocket-sharp.dll.mdb b/Example/bin/Debug/websocket-sharp.dll.mdb index c2e47021..c4c850c1 100644 Binary files a/Example/bin/Debug/websocket-sharp.dll.mdb and b/Example/bin/Debug/websocket-sharp.dll.mdb differ diff --git a/Example/bin/Debug_Ubuntu/example.exe b/Example/bin/Debug_Ubuntu/example.exe index ef701c07..39c29468 100755 Binary files a/Example/bin/Debug_Ubuntu/example.exe and b/Example/bin/Debug_Ubuntu/example.exe differ diff --git a/Example/bin/Debug_Ubuntu/example.exe.mdb b/Example/bin/Debug_Ubuntu/example.exe.mdb index 9577f935..6222a2ec 100644 Binary files a/Example/bin/Debug_Ubuntu/example.exe.mdb and b/Example/bin/Debug_Ubuntu/example.exe.mdb differ diff --git a/Example/bin/Debug_Ubuntu/websocket-sharp.dll b/Example/bin/Debug_Ubuntu/websocket-sharp.dll index 2dc0f9c0..7d6a7a5d 100755 Binary files a/Example/bin/Debug_Ubuntu/websocket-sharp.dll and b/Example/bin/Debug_Ubuntu/websocket-sharp.dll differ diff --git a/Example/bin/Debug_Ubuntu/websocket-sharp.dll.mdb b/Example/bin/Debug_Ubuntu/websocket-sharp.dll.mdb index 8b8f1b37..0eba2896 100644 Binary files a/Example/bin/Debug_Ubuntu/websocket-sharp.dll.mdb and b/Example/bin/Debug_Ubuntu/websocket-sharp.dll.mdb differ diff --git a/Example/bin/Release/example.exe b/Example/bin/Release/example.exe index d36f19d8..1a78014f 100755 Binary files a/Example/bin/Release/example.exe and b/Example/bin/Release/example.exe differ diff --git a/Example/bin/Release/websocket-sharp.dll b/Example/bin/Release/websocket-sharp.dll index ee0b391f..0de3f814 100755 Binary files a/Example/bin/Release/websocket-sharp.dll and b/Example/bin/Release/websocket-sharp.dll differ diff --git a/Example/bin/Release_Ubuntu/example.exe b/Example/bin/Release_Ubuntu/example.exe index cf466973..8be14f93 100755 Binary files a/Example/bin/Release_Ubuntu/example.exe and b/Example/bin/Release_Ubuntu/example.exe differ diff --git a/Example/bin/Release_Ubuntu/websocket-sharp.dll b/Example/bin/Release_Ubuntu/websocket-sharp.dll index 7785a46d..271bdcc5 100755 Binary files a/Example/bin/Release_Ubuntu/websocket-sharp.dll and b/Example/bin/Release_Ubuntu/websocket-sharp.dll differ diff --git a/Example1/bin/Debug/example1.exe b/Example1/bin/Debug/example1.exe index bed10692..db9115d4 100755 Binary files a/Example1/bin/Debug/example1.exe and b/Example1/bin/Debug/example1.exe differ diff --git a/Example1/bin/Debug/example1.exe.mdb b/Example1/bin/Debug/example1.exe.mdb index f18af1db..dd867ddb 100644 Binary files a/Example1/bin/Debug/example1.exe.mdb and b/Example1/bin/Debug/example1.exe.mdb differ diff --git a/Example1/bin/Debug/websocket-sharp.dll b/Example1/bin/Debug/websocket-sharp.dll index e4a7eb7a..615a2c62 100755 Binary files a/Example1/bin/Debug/websocket-sharp.dll and b/Example1/bin/Debug/websocket-sharp.dll differ diff --git a/Example1/bin/Debug/websocket-sharp.dll.mdb b/Example1/bin/Debug/websocket-sharp.dll.mdb index c2e47021..c4c850c1 100644 Binary files a/Example1/bin/Debug/websocket-sharp.dll.mdb and b/Example1/bin/Debug/websocket-sharp.dll.mdb differ diff --git a/Example1/bin/Debug_Ubuntu/example1.exe b/Example1/bin/Debug_Ubuntu/example1.exe index 77b06f0c..bf5dd950 100755 Binary files a/Example1/bin/Debug_Ubuntu/example1.exe and b/Example1/bin/Debug_Ubuntu/example1.exe differ diff --git a/Example1/bin/Debug_Ubuntu/example1.exe.mdb b/Example1/bin/Debug_Ubuntu/example1.exe.mdb index ddbfc197..a5abf751 100644 Binary files a/Example1/bin/Debug_Ubuntu/example1.exe.mdb and b/Example1/bin/Debug_Ubuntu/example1.exe.mdb differ diff --git a/Example1/bin/Debug_Ubuntu/websocket-sharp.dll b/Example1/bin/Debug_Ubuntu/websocket-sharp.dll index 2dc0f9c0..7d6a7a5d 100755 Binary files a/Example1/bin/Debug_Ubuntu/websocket-sharp.dll and b/Example1/bin/Debug_Ubuntu/websocket-sharp.dll differ diff --git a/Example1/bin/Debug_Ubuntu/websocket-sharp.dll.mdb b/Example1/bin/Debug_Ubuntu/websocket-sharp.dll.mdb index 8b8f1b37..0eba2896 100644 Binary files a/Example1/bin/Debug_Ubuntu/websocket-sharp.dll.mdb and b/Example1/bin/Debug_Ubuntu/websocket-sharp.dll.mdb differ diff --git a/Example1/bin/Release/example1.exe b/Example1/bin/Release/example1.exe index 84e13041..bbd1e4bf 100755 Binary files a/Example1/bin/Release/example1.exe and b/Example1/bin/Release/example1.exe differ diff --git a/Example1/bin/Release/websocket-sharp.dll b/Example1/bin/Release/websocket-sharp.dll index ee0b391f..0de3f814 100755 Binary files a/Example1/bin/Release/websocket-sharp.dll and b/Example1/bin/Release/websocket-sharp.dll differ diff --git a/Example1/bin/Release_Ubuntu/example1.exe b/Example1/bin/Release_Ubuntu/example1.exe index d2f708fc..a6ab5310 100755 Binary files a/Example1/bin/Release_Ubuntu/example1.exe and b/Example1/bin/Release_Ubuntu/example1.exe differ diff --git a/Example1/bin/Release_Ubuntu/websocket-sharp.dll b/Example1/bin/Release_Ubuntu/websocket-sharp.dll index 7785a46d..271bdcc5 100755 Binary files a/Example1/bin/Release_Ubuntu/websocket-sharp.dll and b/Example1/bin/Release_Ubuntu/websocket-sharp.dll differ diff --git a/Example2/Example2.pidb b/Example2/Example2.pidb index 1955e7c7..1a7ea415 100644 Binary files a/Example2/Example2.pidb and b/Example2/Example2.pidb differ diff --git a/Example2/Program.cs b/Example2/Program.cs index 351c9d3c..aa659658 100644 --- a/Example2/Program.cs +++ b/Example2/Program.cs @@ -7,13 +7,14 @@ namespace Example2 { public static void Main(string[] args) { - var wssv = new WebSocketServer("ws://localhost:4649"); + //var wssv = new WebSocketServer("ws://localhost:4649"); //var wssv = new WebSocketServer("ws://localhost:4649"); + var wssv = new WebSocketServer("/", 4649); wssv.Start(); Console.WriteLine( - "WebSocket Server (url: {0}) listening on port: {1}\n", - wssv.Url, wssv.Port); + "WebSocket Server (url: {0})\n listening on address: {1} port: {2}\n", + wssv.Url, wssv.Address, wssv.Port); Console.WriteLine("Press any key to stop server..."); Console.ReadLine(); diff --git a/Example2/bin/Debug/example2.exe b/Example2/bin/Debug/example2.exe index 6af7008c..36d05d35 100755 Binary files a/Example2/bin/Debug/example2.exe and b/Example2/bin/Debug/example2.exe differ diff --git a/Example2/bin/Debug/example2.exe.mdb b/Example2/bin/Debug/example2.exe.mdb index 5c1e89d1..c2fc78bd 100644 Binary files a/Example2/bin/Debug/example2.exe.mdb and b/Example2/bin/Debug/example2.exe.mdb differ diff --git a/Example2/bin/Debug/websocket-sharp.dll b/Example2/bin/Debug/websocket-sharp.dll index e4a7eb7a..615a2c62 100755 Binary files a/Example2/bin/Debug/websocket-sharp.dll and b/Example2/bin/Debug/websocket-sharp.dll differ diff --git a/Example2/bin/Debug/websocket-sharp.dll.mdb b/Example2/bin/Debug/websocket-sharp.dll.mdb index c2e47021..c4c850c1 100644 Binary files a/Example2/bin/Debug/websocket-sharp.dll.mdb and b/Example2/bin/Debug/websocket-sharp.dll.mdb differ diff --git a/Example2/bin/Debug_Ubuntu/example2.exe b/Example2/bin/Debug_Ubuntu/example2.exe index bc09e04a..915409c8 100755 Binary files a/Example2/bin/Debug_Ubuntu/example2.exe and b/Example2/bin/Debug_Ubuntu/example2.exe differ diff --git a/Example2/bin/Debug_Ubuntu/example2.exe.mdb b/Example2/bin/Debug_Ubuntu/example2.exe.mdb index 179e5bfa..cff75eaa 100644 Binary files a/Example2/bin/Debug_Ubuntu/example2.exe.mdb and b/Example2/bin/Debug_Ubuntu/example2.exe.mdb differ diff --git a/Example2/bin/Debug_Ubuntu/websocket-sharp.dll b/Example2/bin/Debug_Ubuntu/websocket-sharp.dll index 2dc0f9c0..7d6a7a5d 100755 Binary files a/Example2/bin/Debug_Ubuntu/websocket-sharp.dll and b/Example2/bin/Debug_Ubuntu/websocket-sharp.dll differ diff --git a/Example2/bin/Debug_Ubuntu/websocket-sharp.dll.mdb b/Example2/bin/Debug_Ubuntu/websocket-sharp.dll.mdb index 8b8f1b37..0eba2896 100644 Binary files a/Example2/bin/Debug_Ubuntu/websocket-sharp.dll.mdb and b/Example2/bin/Debug_Ubuntu/websocket-sharp.dll.mdb differ diff --git a/Example2/bin/Release/example2.exe b/Example2/bin/Release/example2.exe index f3d5d642..d9a96bd7 100755 Binary files a/Example2/bin/Release/example2.exe and b/Example2/bin/Release/example2.exe differ diff --git a/Example2/bin/Release/websocket-sharp.dll b/Example2/bin/Release/websocket-sharp.dll index ee0b391f..0de3f814 100755 Binary files a/Example2/bin/Release/websocket-sharp.dll and b/Example2/bin/Release/websocket-sharp.dll differ diff --git a/Example2/bin/Release_Ubuntu/example2.exe b/Example2/bin/Release_Ubuntu/example2.exe index 8bf435cf..57b99921 100755 Binary files a/Example2/bin/Release_Ubuntu/example2.exe and b/Example2/bin/Release_Ubuntu/example2.exe differ diff --git a/Example2/bin/Release_Ubuntu/websocket-sharp.dll b/Example2/bin/Release_Ubuntu/websocket-sharp.dll index 7785a46d..271bdcc5 100755 Binary files a/Example2/bin/Release_Ubuntu/websocket-sharp.dll and b/Example2/bin/Release_Ubuntu/websocket-sharp.dll differ diff --git a/websocket-sharp/Ext.cs b/websocket-sharp/Ext.cs index 3b82ca7b..e71b67c9 100644 --- a/websocket-sharp/Ext.cs +++ b/websocket-sharp/Ext.cs @@ -57,6 +57,8 @@ namespace WebSocketSharp public static bool EqualsAndSaveTo(this int value, char c, List dest) { + if (value < 0) + throw new ArgumentOutOfRangeException("value"); byte b = (byte)value; dest.Add(b); return b == Convert.ToByte(c); diff --git a/websocket-sharp/Server/WebSocketServer.cs b/websocket-sharp/Server/WebSocketServer.cs index 3793fc82..f9f5d525 100644 --- a/websocket-sharp/Server/WebSocketServer.cs +++ b/websocket-sharp/Server/WebSocketServer.cs @@ -37,19 +37,65 @@ using System.Net.Sockets; using System.Threading; using WebSocketSharp.Frame; -namespace WebSocketSharp.Server -{ +namespace WebSocketSharp.Server { + public class WebSocketServer where T : WebSocketService, new() { #region Private Fields + private Thread _acceptClientThread; private Dictionary _services; private TcpListener _tcpListener; private Uri _uri; #endregion + #region Constructor + + public WebSocketServer(string url) + { + _uri = new Uri(url); + if (!isValidScheme(_uri)) + { + var msg = "Unsupported WebSocket URI scheme: " + _uri.Scheme; + throw new ArgumentException(msg); + } + + var host = _uri.DnsSafeHost; + var ips = Dns.GetHostAddresses(host); + if (ips.Length == 0) + { + var msg = "Invalid WebSocket URI host: " + host; + throw new ArgumentException(msg); + } + + var scheme = _uri.Scheme; + var port = _uri.Port; + if (port <= 0) + { + port = 80; + if (scheme == "wss") + port = 443; + } + + _tcpListener = new TcpListener(ips[0], port); + _services = new Dictionary(); + } + + public WebSocketServer(string absPath, int port) + { + _uri = new Uri(absPath, UriKind.Relative); + + if (port <= 0) + port = 80; + + _tcpListener = new TcpListener(IPAddress.Any, port); + _services = new Dictionary(); + } + + #endregion + #region Properties public IPAddress Address @@ -80,69 +126,27 @@ namespace WebSocketSharp.Server #endregion - #region Public Constructor - - public WebSocketServer(string url) - { - _uri = new Uri(url); - - if (!isValidScheme(_uri)) - { - var msg = "Unsupported WebSocket URI scheme: " + _uri.Scheme; - throw new ArgumentException(msg); - } - - string scheme = _uri.Scheme; - int port = _uri.Port; - - if (port <= 0) - { - if (scheme == "wss") - { - port = 443; - } - else - { - port = 80; - } - } - - _tcpListener = new TcpListener(IPAddress.Any, port); - _services = new Dictionary(); - } - - #endregion - #region Private Methods - private void acceptClient(IAsyncResult ar) + private void acceptClient() { - TcpListener listener = (TcpListener)ar.AsyncState; - - if (listener.Server == null || !listener.Server.IsBound) + while (true) { - return; + try { + var client = _tcpListener.AcceptTcpClient(); + startService(client); + } + catch (SocketException) + { + // TcpListener has been stopped. + break; + } + catch (Exception ex) + { + error(ex.Message); + break; + } } - - try - { - TcpClient client = listener.EndAcceptTcpClient(ar); - WebSocket socket = new WebSocket(_uri, client); - T service = new T(); - service.Bind(socket, _services); - service.Start(); - } - catch (ObjectDisposedException) - { - // TcpListener has been stopped. - return; - } - catch (Exception ex) - { - error(ex.Message); - } - - listener.BeginAcceptTcpClient(acceptClient, listener); } private void error(string message) @@ -157,28 +161,57 @@ namespace WebSocketSharp.Server private bool isValidScheme(Uri uri) { - string scheme = uri.Scheme; + var scheme = uri.Scheme; if (scheme == "ws" || scheme == "wss") - { return true; - } return false; } + private void startAcceptClientThread() + { + _acceptClientThread = new Thread(new ThreadStart(acceptClient)); + _acceptClientThread.IsBackground = true; + _acceptClientThread.Start(); + } + + private void startService(TcpClient client) + { + WaitCallback startCb = (state) => + { + try { + var socket = new WebSocket(_uri, client); + BindWebSocket(socket); + } + catch (Exception ex) + { + error(ex.Message); + } + }; + ThreadPool.QueueUserWorkItem(startCb); + } + #endregion #region Public Methods + public void BindWebSocket(WebSocket socket) + { + T service = new T(); + service.Bind(socket, _services); + service.Start(); + } + public void Start() { _tcpListener.Start(); - _tcpListener.BeginAcceptTcpClient(acceptClient, _tcpListener); + startAcceptClientThread(); } public void Stop() { _tcpListener.Stop(); + _acceptClientThread.Join(5 * 1000); StopServices(); } @@ -192,9 +225,7 @@ namespace WebSocketSharp.Server lock (((ICollection)_services).SyncRoot) { foreach (WebSocketService service in _services.Values) - { service.Stop(code, reason); - } } } diff --git a/websocket-sharp/WebSocket.cs b/websocket-sharp/WebSocket.cs index 5b54249f..598c21d4 100644 --- a/websocket-sharp/WebSocket.cs +++ b/websocket-sharp/WebSocket.cs @@ -62,6 +62,7 @@ namespace WebSocketSharp private string _base64key; private string _binaryType; + private IPEndPoint _endPoint; private AutoResetEvent _exitedMessageLoop; private string _extensions; private Object _forClose; @@ -106,6 +107,7 @@ namespace WebSocketSharp { _uri = uri; _tcpClient = tcpClient; + _endPoint = (IPEndPoint)_tcpClient.Client.LocalEndPoint; _isClient = false; } @@ -177,15 +179,24 @@ namespace WebSocketSharp get { return _extensions; } } - public bool IsConnected - { - get - { - if (_readyState != WsState.OPEN) return false; + public bool IsConnected { + get { + if (_readyState != WsState.OPEN) + return false; + return Ping(); } } + public bool IsSecure { + get { + if (_endPoint.Port == 443) + return true; + + return false; + } + } + public string Protocol { get { return _protocol; } @@ -447,7 +458,7 @@ namespace WebSocketSharp { _netStream = _tcpClient.GetStream(); - if (_uri.Scheme == "wss") + if (IsSecure) { _sslStream = new SslStream(_netStream); @@ -507,16 +518,18 @@ namespace WebSocketSharp }; }; - string expectedHost = _uri.DnsSafeHost; - int port = ((IPEndPoint)_tcpClient.Client.LocalEndPoint).Port; - if (port != 80) - expectedHost += ":" + port; + if (_uri.IsAbsoluteUri) + { + if (_uri.PathAndQuery.NotEqualsDo(request.Uri, func("Request URI"), out message, false)) + return false; - if (_uri.PathAndQuery.NotEqualsDo(request.Uri, func("Request URI"), out message, false)) - return false; + if (!isValidRequestHost(request.GetHeaderValues("Host")[0], func("Host"), out message)) + return false; + } - if (expectedHost.NotEqualsDo(request.GetHeaderValues("Host")[0], func("Host"), out message, false)) - return false; + if (!_uri.IsAbsoluteUri) + if (_uri.ToString().NotEqualsDo(request.Uri, func("Request URI"), out message, false)) + return false; if (!request.HeaderExists("Sec-WebSocket-Version", _version)) { @@ -536,6 +549,27 @@ namespace WebSocketSharp return true; } + private bool isValidRequestHost(string value, Func func, out string message) + { + var address = _endPoint.Address; + var port = _endPoint.Port; + + var expectedHost1 = _uri.DnsSafeHost; + var expectedHost2 = address.ToString(); + if (port != 80) + { + expectedHost1 += ":" + port; + expectedHost2 += ":" + port; + } + + if (expectedHost1.NotEqualsDo(value, func, out message, false)) + if (expectedHost2.NotEqualsDo(value, func, out message, false)) + return false; + + message = String.Empty; + return true; + } + private bool isValidResponse(ResponseHandshake response, out string message) { if (!response.IsWebSocketResponse) diff --git a/websocket-sharp/bin/Debug/websocket-sharp.dll b/websocket-sharp/bin/Debug/websocket-sharp.dll index e4a7eb7a..615a2c62 100755 Binary files a/websocket-sharp/bin/Debug/websocket-sharp.dll and b/websocket-sharp/bin/Debug/websocket-sharp.dll differ diff --git a/websocket-sharp/bin/Debug/websocket-sharp.dll.mdb b/websocket-sharp/bin/Debug/websocket-sharp.dll.mdb index c2e47021..c4c850c1 100644 Binary files a/websocket-sharp/bin/Debug/websocket-sharp.dll.mdb and b/websocket-sharp/bin/Debug/websocket-sharp.dll.mdb differ diff --git a/websocket-sharp/bin/Debug_Ubuntu/websocket-sharp.dll b/websocket-sharp/bin/Debug_Ubuntu/websocket-sharp.dll index 2dc0f9c0..7d6a7a5d 100755 Binary files a/websocket-sharp/bin/Debug_Ubuntu/websocket-sharp.dll and b/websocket-sharp/bin/Debug_Ubuntu/websocket-sharp.dll differ diff --git a/websocket-sharp/bin/Debug_Ubuntu/websocket-sharp.dll.mdb b/websocket-sharp/bin/Debug_Ubuntu/websocket-sharp.dll.mdb index 8b8f1b37..0eba2896 100644 Binary files a/websocket-sharp/bin/Debug_Ubuntu/websocket-sharp.dll.mdb and b/websocket-sharp/bin/Debug_Ubuntu/websocket-sharp.dll.mdb differ diff --git a/websocket-sharp/bin/Release/websocket-sharp.dll b/websocket-sharp/bin/Release/websocket-sharp.dll index ee0b391f..0de3f814 100755 Binary files a/websocket-sharp/bin/Release/websocket-sharp.dll and b/websocket-sharp/bin/Release/websocket-sharp.dll differ diff --git a/websocket-sharp/bin/Release_Ubuntu/websocket-sharp.dll b/websocket-sharp/bin/Release_Ubuntu/websocket-sharp.dll index 7785a46d..271bdcc5 100755 Binary files a/websocket-sharp/bin/Release_Ubuntu/websocket-sharp.dll and b/websocket-sharp/bin/Release_Ubuntu/websocket-sharp.dll differ diff --git a/websocket-sharp/websocket-sharp.pidb b/websocket-sharp/websocket-sharp.pidb index f3548356..82ca1a28 100644 Binary files a/websocket-sharp/websocket-sharp.pidb and b/websocket-sharp/websocket-sharp.pidb differ