diff --git a/Example/bin/Debug/example.exe b/Example/bin/Debug/example.exe index 42cfaa6c..06a5eb1e 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 8c71abf1..ded191cf 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 666378fb..274194fa 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 7da189e8..334c331d 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 91b086b8..697d85ce 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 2a1eec19..c22a7357 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 ef36b94e..5993ee69 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 c418da3e..0cf18085 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 4753627f..8e68ab47 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 f1007de6..f9220eb0 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 daaa5b67..f5bbecbc 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 4e8a4675..51c796ed 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 0b8fc268..73046743 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 06d04df1..9096bac8 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 666378fb..274194fa 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 7da189e8..334c331d 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 04f37d5c..562c82b9 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 fd797b8d..cda3bf6b 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 ef36b94e..5993ee69 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 c418da3e..0cf18085 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 1be7e1f8..e9b9e8c1 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 f1007de6..f9220eb0 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 b17176b7..19dc036a 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 4e8a4675..51c796ed 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/bin/Debug/example2.exe b/Example2/bin/Debug/example2.exe index 9bb54108..b8f2e9d6 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 6d9f9c07..c016e425 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 666378fb..274194fa 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 7da189e8..334c331d 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 5cbd8f98..9a29b01e 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 bf5aee8a..30dc6f54 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 ef36b94e..5993ee69 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 c418da3e..0cf18085 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 cbebc39b..c83adcdc 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 f1007de6..f9220eb0 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 34de4687..2f35306d 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 4e8a4675..51c796ed 100755 Binary files a/Example2/bin/Release_Ubuntu/websocket-sharp.dll and b/Example2/bin/Release_Ubuntu/websocket-sharp.dll differ diff --git a/Example3/bin/Debug/Example3.exe b/Example3/bin/Debug/Example3.exe index a0e2b1df..80206bec 100755 Binary files a/Example3/bin/Debug/Example3.exe and b/Example3/bin/Debug/Example3.exe differ diff --git a/Example3/bin/Debug/Example3.exe.mdb b/Example3/bin/Debug/Example3.exe.mdb index e8e2ffdc..5ce0e558 100644 Binary files a/Example3/bin/Debug/Example3.exe.mdb and b/Example3/bin/Debug/Example3.exe.mdb differ diff --git a/Example3/bin/Debug/websocket-sharp.dll b/Example3/bin/Debug/websocket-sharp.dll index 666378fb..274194fa 100755 Binary files a/Example3/bin/Debug/websocket-sharp.dll and b/Example3/bin/Debug/websocket-sharp.dll differ diff --git a/Example3/bin/Debug/websocket-sharp.dll.mdb b/Example3/bin/Debug/websocket-sharp.dll.mdb index 7da189e8..334c331d 100644 Binary files a/Example3/bin/Debug/websocket-sharp.dll.mdb and b/Example3/bin/Debug/websocket-sharp.dll.mdb differ diff --git a/Example3/bin/Debug_Ubuntu/Example3.exe b/Example3/bin/Debug_Ubuntu/Example3.exe index 91feb82b..327ca32c 100755 Binary files a/Example3/bin/Debug_Ubuntu/Example3.exe and b/Example3/bin/Debug_Ubuntu/Example3.exe differ diff --git a/Example3/bin/Debug_Ubuntu/Example3.exe.mdb b/Example3/bin/Debug_Ubuntu/Example3.exe.mdb index 2e69e813..fe76e568 100644 Binary files a/Example3/bin/Debug_Ubuntu/Example3.exe.mdb and b/Example3/bin/Debug_Ubuntu/Example3.exe.mdb differ diff --git a/Example3/bin/Debug_Ubuntu/websocket-sharp.dll b/Example3/bin/Debug_Ubuntu/websocket-sharp.dll index ef36b94e..5993ee69 100755 Binary files a/Example3/bin/Debug_Ubuntu/websocket-sharp.dll and b/Example3/bin/Debug_Ubuntu/websocket-sharp.dll differ diff --git a/Example3/bin/Debug_Ubuntu/websocket-sharp.dll.mdb b/Example3/bin/Debug_Ubuntu/websocket-sharp.dll.mdb index c418da3e..0cf18085 100644 Binary files a/Example3/bin/Debug_Ubuntu/websocket-sharp.dll.mdb and b/Example3/bin/Debug_Ubuntu/websocket-sharp.dll.mdb differ diff --git a/Example3/bin/Release/Example3.exe b/Example3/bin/Release/Example3.exe index b7fd472c..fd129f26 100755 Binary files a/Example3/bin/Release/Example3.exe and b/Example3/bin/Release/Example3.exe differ diff --git a/Example3/bin/Release/websocket-sharp.dll b/Example3/bin/Release/websocket-sharp.dll index f1007de6..f9220eb0 100755 Binary files a/Example3/bin/Release/websocket-sharp.dll and b/Example3/bin/Release/websocket-sharp.dll differ diff --git a/Example3/bin/Release_Ubuntu/Example3.exe b/Example3/bin/Release_Ubuntu/Example3.exe index 39b6d1dd..b54bd250 100755 Binary files a/Example3/bin/Release_Ubuntu/Example3.exe and b/Example3/bin/Release_Ubuntu/Example3.exe differ diff --git a/Example3/bin/Release_Ubuntu/websocket-sharp.dll b/Example3/bin/Release_Ubuntu/websocket-sharp.dll index 4e8a4675..51c796ed 100755 Binary files a/Example3/bin/Release_Ubuntu/websocket-sharp.dll and b/Example3/bin/Release_Ubuntu/websocket-sharp.dll differ diff --git a/websocket-sharp/WebSocket.cs b/websocket-sharp/WebSocket.cs index 4f6480d3..ed54c587 100644 --- a/websocket-sharp/WebSocket.cs +++ b/websocket-sharp/WebSocket.cs @@ -69,7 +69,7 @@ namespace WebSocketSharp { private Action _closeContext; private WebSocketContext _context; private string _extensions; - private AutoResetEvent _exitMessageLoop; + private AutoResetEvent _exitReceiving; private Object _forClose; private Object _forSend; private string _protocol; @@ -101,7 +101,7 @@ namespace WebSocketSharp { internal WebSocket(HttpListenerWebSocketContext context) : this() { - _wsStream = context.Stream; + _wsStream = context.Stream; _closeContext = () => context.Close(); init(context); } @@ -109,7 +109,7 @@ namespace WebSocketSharp { internal WebSocket(TcpListenerWebSocketContext context) : this() { - _wsStream = context.Stream; + _wsStream = context.Stream; _closeContext = () => context.Close(); init(context); } @@ -142,18 +142,17 @@ namespace WebSocketSharp { if (url.IsNull()) throw new ArgumentNullException("url"); - Uri uri; + Uri uri; string msg; if (!url.TryCreateWebSocketUri(out uri, out msg)) throw new ArgumentException(msg, "url"); - _uri = uri; + _uri = uri; _protocols = protocols.ToString(", "); - _base64key = createBase64Key(); - _client = true; - _secure = uri.Scheme == "wss" - ? true - : false; + _client = true; + _secure = uri.Scheme == "wss" + ? true + : false; } /// @@ -317,69 +316,16 @@ namespace WebSocketSharp { #region Private Methods - // As Server + // As server private bool acceptHandshake() { - if (!receiveOpeningHandshake()) + if (!processRequestHandshake()) return false; sendResponseHandshake(); return true; } - private bool checkFrameIsValid(WsFrame frame) - { - if (frame.IsNull()) - { - var msg = "The WebSocket frame can not be read from the network stream."; - close(CloseStatusCode.ABNORMAL, msg); - - return false; - } - - return true; - } - - // As Server - private bool checkRequestIsValid() - { - return !_context.IsValid - ? false - : !checkRequestHostHeaderIsValid() - ? false - : _context.Headers.Exists("Sec-WebSocket-Version", _version); - } - - // As Server - private bool checkRequestHostHeaderIsValid() - { - var authority = _context.Headers["Host"]; - if (authority.IsNullOrEmpty() || !_uri.IsAbsoluteUri) - return true; - - var i = authority.IndexOf(':'); - var host = i > 0 - ? authority.Substring(0, i) - : authority; - var type = Uri.CheckHostName(host); - - return type != UriHostNameType.Dns - ? true - : Uri.CheckHostName(_uri.DnsSafeHost) != UriHostNameType.Dns - ? true - : host == _uri.DnsSafeHost; - } - - // As Client - private bool checkResponseIsValid(ResponseHandshake response) - { - return !response.IsWebSocketResponse - ? false - : !response.HeaderExists("Sec-WebSocket-Accept", createResponseKey()) - ? false - : !response.HeaderExists("Sec-WebSocket-Version") || response.HeaderExists("Sec-WebSocket-Version", _version); - } - private void close(HttpStatusCode code) { if (_readyState != WsState.CONNECTING || _client) @@ -392,7 +338,7 @@ namespace WebSocketSharp { private void close(PayloadData data) { #if DEBUG - Console.WriteLine("WS: Info@close: Current thread IsBackground ?: {0}", Thread.CurrentThread.IsBackground); + Console.WriteLine("WS: Info@close: Current thread IsBackground?: {0}", Thread.CurrentThread.IsBackground); #endif lock(_forClose) { @@ -422,7 +368,7 @@ namespace WebSocketSharp { closeHandshake(data); #if DEBUG - Console.WriteLine("WS: Info@close: Exits close method."); + Console.WriteLine("WS: Info@close: Exit close method."); #endif } @@ -481,7 +427,7 @@ namespace WebSocketSharp { } } - // As Client + // As client private void closeResourcesAsClient() { if (!_wsStream.IsNull()) @@ -497,7 +443,7 @@ namespace WebSocketSharp { } } - // As Server + // As server private void closeResourcesAsServer() { if (!_context.IsNull() && !_closeContext.IsNull()) @@ -515,7 +461,7 @@ namespace WebSocketSharp { : acceptHandshake(); } - // As Client + // As client private string createBase64Key() { var src = new byte[16]; @@ -532,8 +478,8 @@ namespace WebSocketSharp { : new WsFrame(fin, opcode, Mask.UNMASK, payloadData); } - // As Client - private RequestHandshake createOpeningHandshake() + // As client + private RequestHandshake createRequestHandshake() { var path = _uri.PathAndQuery; var host = _uri.Port == 80 @@ -550,7 +496,7 @@ namespace WebSocketSharp { return req; } - // As Server + // As server private ResponseHandshake createResponseHandshake() { var res = new ResponseHandshake(); @@ -559,7 +505,7 @@ namespace WebSocketSharp { return res; } - // As Server + // As server private ResponseHandshake createResponseHandshake(HttpStatusCode code) { var res = ResponseHandshake.CreateCloseResponse(code); @@ -578,14 +524,26 @@ namespace WebSocketSharp { return Convert.ToBase64String(src); } - // As Client + // As client private bool doHandshake() { - sendOpeningHandshake(); - return receiveResponseHandshake(); + init(); + sendRequestHandshake(); + return processResponseHandshake(); } - // As Server + // 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 private void init(WebSocketContext context) { _context = context; @@ -594,11 +552,52 @@ namespace WebSocketSharp { _client = false; } + // As client + private bool isValid(ResponseHandshake response) + { + return !response.IsWebSocketResponse + ? false + : !response.HeaderExists("Sec-WebSocket-Accept", createResponseKey()) + ? false + : !response.HeaderExists("Sec-WebSocket-Version") || + response.HeaderExists("Sec-WebSocket-Version", _version); + } + + // As server + private bool isValidHostHeader() + { + var authority = _context.Headers["Host"]; + if (authority.IsNullOrEmpty() || !_uri.IsAbsoluteUri) + return true; + + var i = authority.IndexOf(':'); + var host = i > 0 + ? authority.Substring(0, i) + : authority; + var type = Uri.CheckHostName(host); + + return type != UriHostNameType.Dns + ? true + : Uri.CheckHostName(_uri.DnsSafeHost) != UriHostNameType.Dns + ? true + : host == _uri.DnsSafeHost; + } + + // As server + private bool isValidRequesHandshake() + { + return !_context.IsValid + ? false + : !isValidHostHeader() + ? false + : _context.Headers.Exists("Sec-WebSocket-Version", _version); + } + private void onClose(CloseEventArgs eventArgs) { if (!Thread.CurrentThread.IsBackground) - if (!_exitMessageLoop.IsNull()) - _exitMessageLoop.WaitOne(5 * 1000); + if (!_exitReceiving.IsNull()) + _exitReceiving.WaitOne(5 * 1000); if (!closeResources()) eventArgs.WasClean = false; @@ -625,7 +624,7 @@ namespace WebSocketSharp { private void onOpen() { _readyState = WsState.OPEN; - startMessageLoop(); + startReceiving(); OnOpen.Emit(this, EventArgs.Empty); } @@ -657,143 +656,168 @@ namespace WebSocketSharp { pong(payloadData); } - private WsFrame readFrame() + private void process(WsFrame frame) { - var frame = _wsStream.ReadFrame(); - return checkFrameIsValid(frame) ? frame : null; + bool processed = processAbnormal(frame) || + processFragmented(frame) || + processData(frame) || + processPing(frame) || + processPong(frame) || + processClose(frame); + + if (!processed) + processIncorrectFrame(); } - private string[] readHandshake() + private bool processAbnormal(WsFrame frame) { - return _wsStream.ReadHandshake(); + if (!frame.IsNull()) + return false; + + #if DEBUG + Console.WriteLine("WS: Info@processAbnormal: Start closing handshake."); + #endif + var msg = "What we've got here is a failure to communicate in the WebSocket protocol."; + close(CloseStatusCode.ABNORMAL, msg); + + return true; } - private MessageEventArgs receive(WsFrame frame) + private bool processClose(WsFrame frame) { - if (!checkFrameIsValid(frame)) - return null; + if (frame.Opcode != Opcode.CLOSE) + return false; - if ((frame.Fin == Fin.FINAL && frame.Opcode == Opcode.CONT) || - (frame.Fin == Fin.MORE && frame.Opcode == Opcode.CONT)) - return null; + #if DEBUG + Console.WriteLine("WS: Info@processClose: Start closing handshake."); + #endif + close(frame.PayloadData); - if (frame.Fin == Fin.MORE) - {// MORE - var merged = receiveFragmented(frame); - return !merged.IsNull() - ? new MessageEventArgs(frame.Opcode, new PayloadData(merged)) - : null; - } + return true; + } - if (frame.Opcode == Opcode.CLOSE) - {// FINAL & CLOSE - #if DEBUG - Console.WriteLine("WS: Info@receive: Starts closing handshake."); - #endif - close(frame.PayloadData); - return null; - } + private bool processData(WsFrame frame) + { + if (!frame.IsData) + return false; - if (frame.Opcode == Opcode.PING) - {// FINAL & PING - #if DEBUG - Console.WriteLine("WS: Info@receive: Returns Pong."); - #endif - pong(frame.PayloadData); - return null; - } + onMessage(new MessageEventArgs(frame.Opcode, frame.PayloadData)); + return true; + } - if (frame.Opcode == Opcode.PONG) - {// FINAL & PONG - #if DEBUG - Console.WriteLine("WS: Info@receive: Receives Pong."); - #endif - _receivePong.Set(); - return null; - } + private bool processFragmented(WsFrame frame) + { + // Not first fragment + if (frame.Opcode == Opcode.CONT) + return true; + + // Not fragmented + if (frame.Fin == Fin.FINAL) + return false; + + // First fragment + if (frame.IsData) + processFragments(frame); + else + processIncorrectFrame(); - // FINAL & (TEXT | BINARY) - return new MessageEventArgs(frame.Opcode, frame.PayloadData); + return true; } - private byte[] receiveFragmented(WsFrame firstFrame) + private void processFragments(WsFrame first) { - var buffer = new List(firstFrame.PayloadData.ToBytes()); - + var buffer = new List(first.PayloadData.ToBytes()); while (true) { var frame = readFrame(); - if (frame.IsNull()) - return null; + if (processAbnormal(frame)) + return; + // MORE if (frame.Fin == Fin.MORE) { + // MORE & CONT if (frame.Opcode == Opcode.CONT) - {// MORE & CONT + { buffer.AddRange(frame.PayloadData.ToBytes()); continue; } - #if DEBUG - Console.WriteLine("WS: Info@receiveFragmented: Starts closing handshake."); - #endif - close(CloseStatusCode.INCORRECT_DATA, String.Empty); - return null; + // MORE & ? + processIncorrectFrame(); + return; } + // FINAL & CONT if (frame.Opcode == Opcode.CONT) - {// FINAL & CONT + { buffer.AddRange(frame.PayloadData.ToBytes()); break; } - if (frame.Opcode == Opcode.CLOSE) - {// FINAL & CLOSE - #if DEBUG - Console.WriteLine("WS: Info@receiveFragmented: Starts closing handshake."); - #endif - close(frame.PayloadData); - return null; - } - - if (frame.Opcode == Opcode.PING) - {// FINAL & PING - #if DEBUG - Console.WriteLine("WS: Info@receiveFragmented: Returns Pong."); - #endif - pong(frame.PayloadData); + // FINAL & PING + if (processPing(frame)) continue; - } - if (frame.Opcode == Opcode.PONG) - {// FINAL & PONG - #if DEBUG - Console.WriteLine("WS: Info@receiveFragmented: Receives Pong."); - #endif - _receivePong.Set(); + // FINAL & PONG + if (processPong(frame)) continue; - } - // FINAL & (TEXT | BINARY) - #if DEBUG - Console.WriteLine("WS: Info@receiveFragmented: Starts closing handshake."); - #endif - close(CloseStatusCode.INCORRECT_DATA, String.Empty); - return null; + // FINAL & CLOSE + if (processClose(frame)) + return; + + // FINAL & ? + processIncorrectFrame(); + return; } - return buffer.ToArray(); + onMessage(new MessageEventArgs(first.Opcode, new PayloadData(buffer.ToArray()))); } - // As Server - private bool receiveOpeningHandshake() + private void processIncorrectFrame() + { + #if DEBUG + Console.WriteLine("WS: Info@processIncorrectFrame: Start closing handshake."); + #endif + close(CloseStatusCode.INCORRECT_DATA, String.Empty); + } + + private bool processPing(WsFrame frame) + { + if (frame.Opcode != Opcode.PING) + return false; + + #if DEBUG + Console.WriteLine("WS: Info@processPing: Return Pong."); + #endif + pong(frame.PayloadData); + + return true; + } + + private bool processPong(WsFrame frame) + { + if (frame.Opcode != Opcode.PONG) + return false; + + #if DEBUG + Console.WriteLine("WS: Info@processPong: Receive Pong."); + #endif + _receivePong.Set(); + + return true; + } + + // As server + private bool processRequestHandshake() { #if DEBUG var req = RequestHandshake.Parse(_context); - Console.WriteLine("WS: Info@receiveOpeningHandshake: Opening handshake from client:\n"); + Console.WriteLine("WS: Info@processRequestHandshake: Request handshake from client:\n"); Console.WriteLine(req.ToString()); #endif - if (!checkRequestIsValid()) + if (!isValidRequesHandshake()) { onError("Invalid WebSocket connection request."); close(HttpStatusCode.BadRequest); @@ -810,17 +834,13 @@ namespace WebSocketSharp { return true; } - // As Client - private bool receiveResponseHandshake() + // As client + private bool processResponseHandshake() { - var res = ResponseHandshake.Parse(readHandshake()); - #if DEBUG - Console.WriteLine("WS: Info@receiveResponseHandshake: Response handshake from server:\n"); - Console.WriteLine(res.ToString()); - #endif - if (!checkResponseIsValid(res)) + var res = receiveResponseHandshake(); + if (!isValid(res)) { - var msg = "Invalid response to the WebSocket connection request."; + var msg = "Invalid response to this WebSocket connection request."; onError(msg); close(CloseStatusCode.ABNORMAL, msg); return false; @@ -835,6 +855,47 @@ namespace WebSocketSharp { return true; } + private WsFrame readFrame() + { + return _wsStream.ReadFrame(); + } + + private string[] readHandshake() + { + return _wsStream.ReadHandshake(); + } + + // As client + private ResponseHandshake receiveResponseHandshake() + { + var res = ResponseHandshake.Parse(readHandshake()); + #if DEBUG + Console.WriteLine("WS: Info@receiveResponseHandshake: Response handshake from server:\n"); + Console.WriteLine(res.ToString()); + #endif + return res; + } + + // As client + private void send(RequestHandshake request) + { + #if DEBUG + Console.WriteLine("WS: Info@send: Request handshake to server:\n"); + Console.WriteLine(request.ToString()); + #endif + _wsStream.Write(request); + } + + // As server + private void send(ResponseHandshake response) + { + #if DEBUG + Console.WriteLine("WS: Info@send: Response handshake to client:\n"); + Console.WriteLine(response.ToString()); + #endif + _wsStream.Write(response); + } + private bool send(WsFrame frame) { if (_readyState == WsState.CONNECTING || @@ -849,7 +910,7 @@ namespace WebSocketSharp { if (_wsStream.IsNull()) return false; - _wsStream.WriteFrame(frame); + _wsStream.Write(frame); return true; } catch (Exception ex) @@ -966,72 +1027,42 @@ namespace WebSocketSharp { return readLen; } - // As Client - private void sendOpeningHandshake() + // As client + private void sendRequestHandshake() { - setClientStream(); - var req = createOpeningHandshake(); - sendRequestHandshake(req); + var req = createRequestHandshake(); + send(req); } - // As Client - private void sendRequestHandshake(RequestHandshake request) - { - #if DEBUG - Console.WriteLine("WS: Info@sendRequestHandshake: Request handshake from client:\n"); - Console.WriteLine(request.ToString()); - #endif - writeHandshake(request); - } - - // As Server + // As server private void sendResponseHandshake() { var res = createResponseHandshake(); - sendResponseHandshake(res); + send(res); } - // As Server + // As server private void sendResponseHandshake(HttpStatusCode code) { var res = createResponseHandshake(code); - sendResponseHandshake(res); + send(res); } - // As Server - private void sendResponseHandshake(ResponseHandshake response) + private void startReceiving() { - #if DEBUG - Console.WriteLine("WS: Info@sendResponseHandshake: Response handshake from server:\n"); - Console.WriteLine(response.ToString()); - #endif - writeHandshake(response); - } - - // As Client - private void setClientStream() - { - var host = _uri.DnsSafeHost; - var port = _uri.Port; - _tcpClient = new TcpClient(host, port); - _wsStream = WsStream.CreateClientStream(_tcpClient, host, _secure); - } - - private void startMessageLoop() - { - _exitMessageLoop = new AutoResetEvent(false); - _receivePong = new AutoResetEvent(false); + _exitReceiving = new AutoResetEvent(false); + _receivePong = new AutoResetEvent(false); Action completed = null; completed = (frame) => { try { - onMessage(receive(frame)); + process(frame); if (_readyState == WsState.OPEN) _wsStream.ReadFrameAsync(completed); else - _exitMessageLoop.Set(); + _exitReceiving.Set(); } catch (WsReceivedTooBigMessageException ex) { @@ -1046,11 +1077,6 @@ namespace WebSocketSharp { _wsStream.ReadFrameAsync(completed); } - private void writeHandshake(Handshake handshake) - { - _wsStream.WriteHandshake(handshake); - } - #endregion #region Internal Method @@ -1099,7 +1125,7 @@ namespace WebSocketSharp { /// public void Close(CloseStatusCode code) { - Close(code, String.Empty); + close(code, String.Empty); } /// @@ -1140,7 +1166,7 @@ namespace WebSocketSharp { /// public void Close(CloseStatusCode code, string reason) { - Close((ushort)code, reason); + close(code, reason); } /// diff --git a/websocket-sharp/WsFrame.cs b/websocket-sharp/WsFrame.cs index 8beefeb6..10dd6175 100644 --- a/websocket-sharp/WsFrame.cs +++ b/websocket-sharp/WsFrame.cs @@ -93,15 +93,20 @@ namespace WebSocketSharp { public byte[] MaskingKey { get; private set; } public PayloadData PayloadData { get; private set; } - public ulong Length - { + public bool IsData { + get { + Opcode data = Opcode.TEXT | Opcode.BINARY; + return (data & Opcode) == Opcode; + } + } + + public ulong Length { get { return 2 + (ulong)(ExtPayloadLen.Length + MaskingKey.Length) + PayloadLength; } } - public ulong PayloadLength - { + public ulong PayloadLength { get { return PayloadData.Length; } diff --git a/websocket-sharp/WsStream.cs b/websocket-sharp/WsStream.cs index ae999a1d..9111ec59 100644 --- a/websocket-sharp/WsStream.cs +++ b/websocket-sharp/WsStream.cs @@ -137,14 +137,18 @@ namespace WebSocketSharp { .Split('\n'); } - private void write(byte[] buffer, int offset, int count) + private bool write(byte[] data) { - _innerStream.Write(buffer, offset, count); - } - - private void writeByte(byte value) - { - _innerStream.WriteByte(value); + lock (_forWrite) + { + try { + _innerStream.Write(data, 0, data.Length); + return true; + } + catch { + return false; + } + } } #endregion @@ -245,40 +249,14 @@ namespace WebSocketSharp { } } - public bool WriteFrame(WsFrame frame) + public bool Write(WsFrame frame) { - lock (_forWrite) - { - try - { - var buffer = frame.ToBytes(); - write(buffer, 0, buffer.Length); - - return true; - } - catch - { - return false; - } - } + return write(frame.ToBytes()); } - public bool WriteHandshake(Handshake handshake) + public bool Write(Handshake handshake) { - lock (_forWrite) - { - try - { - var buffer = handshake.ToBytes(); - write(buffer, 0, buffer.Length); - - return true; - } - catch - { - return false; - } - } + return write(handshake.ToBytes()); } #endregion diff --git a/websocket-sharp/bin/Debug/websocket-sharp.dll b/websocket-sharp/bin/Debug/websocket-sharp.dll index 666378fb..274194fa 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 7da189e8..334c331d 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 ef36b94e..5993ee69 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 c418da3e..0cf18085 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 f1007de6..f9220eb0 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 ea9a3734..51c796ed 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/doc/mdoc/index.xml b/websocket-sharp/doc/mdoc/index.xml index 4d91bfdb..1a1f199b 100644 --- a/websocket-sharp/doc/mdoc/index.xml +++ b/websocket-sharp/doc/mdoc/index.xml @@ -1,6 +1,6 @@ - + [00 24 00 00 04 80 00 00 94 00 00 00 06 02 00 00 00 24 00 00 52 53 41 31 00 04 00 00 11 00 00 00 29 17 fb 89 fe c3 91 f7 2b cb 8b e2 61 d2 3f 05 93 6d 65 a8 9e 63 72 a6 f5 d5 2c f2 9d 20 fa 0b c0 70 6a f6 88 7e 8b 90 3f 39 f5 76 c8 48 e0 bb 7b b2 7b ed d3 10 a7 1a 0f 70 98 0f 7f f4 4b 53 09 d2 a5 ef 36 c3 56 b4 aa f0 91 72 63 25 07 89 e0 93 3e 3f 2e f2 b9 73 0e 12 15 5d 43 56 c3 f4 70 a5 89 fe f7 f6 ac 3e 77 c2 d8 d0 84 91 f4 0c d1 f3 8e dc c3 c3 b8 38 3d 0c bf 17 de 20 78 c1 ] diff --git a/websocket-sharp/websocket-sharp.pidb b/websocket-sharp/websocket-sharp.pidb index 628afcbf..95e8fc03 100644 Binary files a/websocket-sharp/websocket-sharp.pidb and b/websocket-sharp/websocket-sharp.pidb differ