diff --git a/websocket-sharp/CloseEventArgs.cs b/websocket-sharp/CloseEventArgs.cs index df89b77c..5bef317b 100644 --- a/websocket-sharp/CloseEventArgs.cs +++ b/websocket-sharp/CloseEventArgs.cs @@ -48,27 +48,78 @@ namespace WebSocketSharp { #region Private Fields - private bool _clean; - private ushort _code; - private string _reason; + private bool _clean; + private ushort _code; + private PayloadData _payloadData; + private byte[] _rawData; + private string _reason; #endregion #region Internal Constructors - internal CloseEventArgs (PayloadData payload) + internal CloseEventArgs () { - var data = payload.ApplicationData; - var len = data.Length; + _code = (ushort) CloseStatusCode.NoStatusCode; + _reason = String.Empty; + _rawData = new byte[0]; + } + + internal CloseEventArgs (ushort code) + { + _code = code; + _reason = String.Empty; + _rawData = code.InternalToByteArray (ByteOrder.Big); + } + + internal CloseEventArgs (CloseStatusCode code) + : this ((ushort) code) + { + } + + internal CloseEventArgs (PayloadData payloadData) + { + _payloadData = payloadData; + _rawData = payloadData.ApplicationData; + + var len = _rawData.Length; _code = len > 1 - ? data.SubArray (0, 2).ToUInt16 (ByteOrder.Big) + ? _rawData.SubArray (0, 2).ToUInt16 (ByteOrder.Big) : (ushort) CloseStatusCode.NoStatusCode; _reason = len > 2 - ? Encoding.UTF8.GetString (data.SubArray (2, len - 2)) + ? Encoding.UTF8.GetString (_rawData.SubArray (2, len - 2)) : String.Empty; } + internal CloseEventArgs (ushort code, string reason) + { + _code = code; + _reason = reason ?? String.Empty; + _rawData = code.Append (reason); + } + + internal CloseEventArgs (CloseStatusCode code, string reason) + : this ((ushort) code, reason) + { + } + + #endregion + + #region Internal Properties + + internal PayloadData PayloadData { + get { + return _payloadData ?? (_payloadData = new PayloadData (_rawData)); + } + } + + internal byte[] RawData { + get { + return _rawData; + } + } + #endregion #region Public Properties diff --git a/websocket-sharp/Server/HttpServer.cs b/websocket-sharp/Server/HttpServer.cs index 9dfb6842..fab1df8a 100644 --- a/websocket-sharp/Server/HttpServer.cs +++ b/websocket-sharp/Server/HttpServer.cs @@ -424,10 +424,9 @@ namespace WebSocketSharp.Server _state = ServerState.ShuttingDown; } - _services.Stop ( - ((ushort) CloseStatusCode.ServerError).InternalToByteArray (ByteOrder.Big), true); - + _services.Stop (new CloseEventArgs (CloseStatusCode.ServerError), true); _listener.Abort (); + _state = ServerState.Stop; } @@ -611,7 +610,7 @@ namespace WebSocketSharp.Server (initializer == null ? "'initializer' is null." : null); if (msg != null) { - _logger.Error (String.Format ("{0}\nservice path: {1}", msg, path)); + _logger.Error (msg); return; } @@ -656,7 +655,7 @@ namespace WebSocketSharp.Server { var msg = path.CheckIfValidServicePath (); if (msg != null) { - _logger.Error (String.Format ("{0}\nservice path: {1}", msg, path)); + _logger.Error (msg); return false; } @@ -671,7 +670,7 @@ namespace WebSocketSharp.Server lock (_sync) { var msg = _state.CheckIfStartable () ?? checkIfCertificateExists (); if (msg != null) { - _logger.Error (String.Format ("{0}\nstate: {1}\nsecure: {2}", msg, _state, _secure)); + _logger.Error (msg); return; } @@ -690,14 +689,14 @@ namespace WebSocketSharp.Server lock (_sync) { var msg = _state.CheckIfStart (); if (msg != null) { - _logger.Error (String.Format ("{0}\nstate: {1}", msg, _state)); + _logger.Error (msg); return; } _state = ServerState.ShuttingDown; } - _services.Stop (new byte[0], true); + _services.Stop (new CloseEventArgs (), true); stopReceiving (5000); _state = ServerState.Stop; @@ -715,23 +714,22 @@ namespace WebSocketSharp.Server /// public void Stop (ushort code, string reason) { - byte[] data = null; + CloseEventArgs e = null; lock (_sync) { - var msg = _state.CheckIfStart () ?? - code.CheckIfValidCloseStatusCode () ?? - (data = code.Append (reason)).CheckIfValidControlData ("reason"); + var msg = + _state.CheckIfStart () ?? + code.CheckIfValidCloseStatusCode () ?? + (e = new CloseEventArgs (code, reason)).RawData.CheckIfValidControlData ("reason"); if (msg != null) { - _logger.Error ( - String.Format ("{0}\nstate: {1}\ncode: {2}\nreason: {3}", msg, _state, code, reason)); - + _logger.Error (msg); return; } _state = ServerState.ShuttingDown; } - _services.Stop (data, !code.IsReserved ()); + _services.Stop (e, !code.IsReserved ()); stopReceiving (5000); _state = ServerState.Stop; @@ -750,20 +748,21 @@ namespace WebSocketSharp.Server /// public void Stop (CloseStatusCode code, string reason) { - byte[] data = null; + CloseEventArgs e = null; lock (_sync) { - var msg = _state.CheckIfStart () ?? - (data = ((ushort) code).Append (reason)).CheckIfValidControlData ("reason"); + var msg = + _state.CheckIfStart () ?? + (e = new CloseEventArgs (code, reason)).RawData.CheckIfValidControlData ("reason"); if (msg != null) { - _logger.Error (String.Format ("{0}\nstate: {1}\nreason: {2}", msg, _state, reason)); + _logger.Error (msg); return; } _state = ServerState.ShuttingDown; } - _services.Stop (data, !code.IsReserved ()); + _services.Stop (e, !code.IsReserved ()); stopReceiving (5000); _state = ServerState.Stop; diff --git a/websocket-sharp/Server/WebSocketServer.cs b/websocket-sharp/Server/WebSocketServer.cs index 9d8377ca..57cd47b7 100644 --- a/websocket-sharp/Server/WebSocketServer.cs +++ b/websocket-sharp/Server/WebSocketServer.cs @@ -507,8 +507,7 @@ namespace WebSocketSharp.Server } _listener.Stop (); - _services.Stop ( - ((ushort) CloseStatusCode.ServerError).InternalToByteArray (ByteOrder.Big), true); + _services.Stop (new CloseEventArgs (CloseStatusCode.ServerError), true); _state = ServerState.Stop; } @@ -728,7 +727,7 @@ namespace WebSocketSharp.Server (initializer == null ? "'initializer' is null." : null); if (msg != null) { - _logger.Error (String.Format ("{0}\nservice path: {1}", msg, path)); + _logger.Error (msg); return; } @@ -752,7 +751,7 @@ namespace WebSocketSharp.Server { var msg = path.CheckIfValidServicePath (); if (msg != null) { - _logger.Error (String.Format ("{0}\nservice path: {1}", msg, path)); + _logger.Error (msg); return false; } @@ -767,7 +766,7 @@ namespace WebSocketSharp.Server lock (_sync) { var msg = _state.CheckIfStartable () ?? checkIfCertificateExists (); if (msg != null) { - _logger.Error (String.Format ("{0}\nstate: {1}\nsecure: {2}", msg, _state, _secure)); + _logger.Error (msg); return; } @@ -786,7 +785,7 @@ namespace WebSocketSharp.Server lock (_sync) { var msg = _state.CheckIfStart (); if (msg != null) { - _logger.Error (String.Format ("{0}\nstate: {1}", msg, _state)); + _logger.Error (msg); return; } @@ -794,7 +793,7 @@ namespace WebSocketSharp.Server } stopReceiving (5000); - _services.Stop (new byte[0], true); + _services.Stop (new CloseEventArgs (), true); _state = ServerState.Stop; } @@ -811,16 +810,15 @@ namespace WebSocketSharp.Server /// public void Stop (ushort code, string reason) { - byte[] data = null; + CloseEventArgs e = null; lock (_sync) { - var msg = _state.CheckIfStart () ?? - code.CheckIfValidCloseStatusCode () ?? - (data = code.Append (reason)).CheckIfValidControlData ("reason"); + var msg = + _state.CheckIfStart () ?? + code.CheckIfValidCloseStatusCode () ?? + (e = new CloseEventArgs (code, reason)).RawData.CheckIfValidControlData ("reason"); if (msg != null) { - _logger.Error ( - String.Format ("{0}\nstate: {1}\ncode: {2}\nreason: {3}", msg, _state, code, reason)); - + _logger.Error (msg); return; } @@ -828,7 +826,7 @@ namespace WebSocketSharp.Server } stopReceiving (5000); - _services.Stop (data, !code.IsReserved ()); + _services.Stop (e, !code.IsReserved ()); _state = ServerState.Stop; } @@ -846,13 +844,14 @@ namespace WebSocketSharp.Server /// public void Stop (CloseStatusCode code, string reason) { - byte[] data = null; + CloseEventArgs e = null; lock (_sync) { - var msg = _state.CheckIfStart () ?? - (data = ((ushort) code).Append (reason)).CheckIfValidControlData ("reason"); + var msg = + _state.CheckIfStart () ?? + (e = new CloseEventArgs (code, reason)).RawData.CheckIfValidControlData ("reason"); if (msg != null) { - _logger.Error (String.Format ("{0}\nstate: {1}\nreason: {2}", msg, _state, reason)); + _logger.Error (msg); return; } @@ -860,7 +859,7 @@ namespace WebSocketSharp.Server } stopReceiving (5000); - _services.Stop (data, !code.IsReserved ()); + _services.Stop (e, !code.IsReserved ()); _state = ServerState.Stop; } diff --git a/websocket-sharp/Server/WebSocketServiceHost.cs b/websocket-sharp/Server/WebSocketServiceHost.cs index 7f7be746..c0a80355 100644 --- a/websocket-sharp/Server/WebSocketServiceHost.cs +++ b/websocket-sharp/Server/WebSocketServiceHost.cs @@ -121,10 +121,9 @@ namespace WebSocketSharp.Server internal void Stop (ushort code, string reason) { - var payload = new PayloadData (code.Append (reason)); - var e = new CloseEventArgs (payload); + var e = new CloseEventArgs (code, reason); var bytes = !code.IsReserved () - ? WebSocketFrame.CreateCloseFrame (Mask.Unmask, payload).ToByteArray () + ? WebSocketFrame.CreateCloseFrame (Mask.Unmask, e.PayloadData).ToByteArray () : null; Sessions.Stop (e, bytes); diff --git a/websocket-sharp/Server/WebSocketServiceManager.cs b/websocket-sharp/Server/WebSocketServiceManager.cs index 811d0b96..04047a2c 100644 --- a/websocket-sharp/Server/WebSocketServiceManager.cs +++ b/websocket-sharp/Server/WebSocketServiceManager.cs @@ -325,15 +325,12 @@ namespace WebSocketSharp.Server } } - internal void Stop (byte[] data, bool send) + internal void Stop (CloseEventArgs e, bool send) { lock (_sync) { _state = ServerState.ShuttingDown; - - var payload = new PayloadData (data); - var e = new CloseEventArgs (payload); var bytes = send - ? WebSocketFrame.CreateCloseFrame (Mask.Unmask, payload).ToByteArray () + ? WebSocketFrame.CreateCloseFrame (Mask.Unmask, e.PayloadData).ToByteArray () : null; foreach (var host in _hosts.Values) diff --git a/websocket-sharp/WebSocket.cs b/websocket-sharp/WebSocket.cs index 10ef696c..ad976802 100644 --- a/websocket-sharp/WebSocket.cs +++ b/websocket-sharp/WebSocket.cs @@ -583,12 +583,7 @@ namespace WebSocketSharp : null; } - private void close (CloseStatusCode code, string reason, bool wait) - { - close (new PayloadData (((ushort) code).Append (reason)), !code.IsReserved (), wait); - } - - private void close (PayloadData payload, bool send, bool wait) + private void close (CloseEventArgs e, bool send, bool wait) { lock (_forConn) { if (_readyState == WebSocketState.Closing || _readyState == WebSocketState.Closed) { @@ -601,15 +596,16 @@ namespace WebSocketSharp _logger.Trace ("Start closing the connection."); - var e = new CloseEventArgs (payload); e.WasClean = _client ? closeHandshake ( - send ? WebSocketFrame.CreateCloseFrame (Mask.Mask, payload).ToByteArray () : null, + send ? WebSocketFrame.CreateCloseFrame (Mask.Mask, e.PayloadData).ToByteArray () + : null, wait ? 5000 : 0, releaseClientResources) : closeHandshake ( - send ? WebSocketFrame.CreateCloseFrame (Mask.Unmask, payload).ToByteArray () : null, + send ? WebSocketFrame.CreateCloseFrame (Mask.Unmask, e.PayloadData).ToByteArray () + : null, wait ? 1000 : 0, releaseServerResources); @@ -625,10 +621,10 @@ namespace WebSocketSharp } } - private void closeAsync (PayloadData payload, bool send, bool wait) + private void closeAsync (CloseEventArgs e, bool send, bool wait) { - Action closer = close; - closer.BeginInvoke (payload, send, wait, ar => closer.EndInvoke (ar), null); + Action closer = close; + closer.BeginInvoke (e, send, wait, ar => closer.EndInvoke (ar), null); } private bool closeHandshake (byte[] frameAsBytes, int millisecondsTimeout, Action release) @@ -836,7 +832,7 @@ namespace WebSocketSharp msg = "An error has occurred while connecting."; error (msg, null); - close (CloseStatusCode.Abnormal, msg, false); + close (new CloseEventArgs (CloseStatusCode.Abnormal, msg), false, false); return false; } @@ -898,7 +894,7 @@ namespace WebSocketSharp private bool processCloseFrame (WebSocketFrame frame) { var payload = frame.PayloadData; - close (payload, !payload.IncludesReservedCloseStatusCode, false); + close (new CloseEventArgs (payload), !payload.IncludesReservedCloseStatusCode, false); return false; } @@ -935,7 +931,7 @@ namespace WebSocketSharp return; } - close (code, reason ?? code.GetMessage (), false); + close (new CloseEventArgs (code, reason ?? code.GetMessage ()), !code.IsReserved (), false); } private bool processFragmentedFrame (WebSocketFrame frame) @@ -1560,7 +1556,7 @@ namespace WebSocketSharp } var send = _readyState == WebSocketState.Open; - close (new PayloadData (), send, send); + close (new CloseEventArgs (), send, send); } /// @@ -1577,7 +1573,18 @@ namespace WebSocketSharp /// public void Close (ushort code) { - Close (code, null); + var msg = _readyState.CheckIfClosable () ?? + code.CheckIfValidCloseStatusCode (); + + if (msg != null) { + _logger.Error (msg); + error ("An error has occurred in closing the connection.", null); + + return; + } + + var send = _readyState == WebSocketState.Open && !code.IsReserved (); + close (new CloseEventArgs (code), send, send); } /// @@ -1590,7 +1597,16 @@ namespace WebSocketSharp /// public void Close (CloseStatusCode code) { - Close (code, null); + var msg = _readyState.CheckIfClosable (); + if (msg != null) { + _logger.Error (msg); + error ("An error has occurred in closing the connection.", null); + + return; + } + + var send = _readyState == WebSocketState.Open && !code.IsReserved (); + close (new CloseEventArgs (code), send, send); } /// @@ -1599,7 +1615,7 @@ namespace WebSocketSharp /// /// /// This method emits a event if - /// isn't in the allowable range of the close status code, or the size of + /// isn't in the allowable range of the close status code or the size of /// is greater than 123 bytes. /// /// @@ -1611,20 +1627,20 @@ namespace WebSocketSharp /// public void Close (ushort code, string reason) { - byte[] data = null; + CloseEventArgs e = null; var msg = _readyState.CheckIfClosable () ?? code.CheckIfValidCloseStatusCode () ?? - (data = code.Append (reason)).CheckIfValidControlData ("reason"); + (e = new CloseEventArgs (code, reason)).RawData.CheckIfValidControlData ("reason"); if (msg != null) { - _logger.Error (String.Format ("{0}\ncode: {1} reason: {2}", msg, code, reason)); + _logger.Error (msg); error ("An error has occurred in closing the connection.", null); return; } var send = _readyState == WebSocketState.Open && !code.IsReserved (); - close (new PayloadData (data), send, send); + close (e, send, send); } /// @@ -1644,19 +1660,19 @@ namespace WebSocketSharp /// public void Close (CloseStatusCode code, string reason) { - byte[] data = null; + CloseEventArgs e = null; var msg = _readyState.CheckIfClosable () ?? - (data = ((ushort) code).Append (reason)).CheckIfValidControlData ("reason"); + (e = new CloseEventArgs (code, reason)).RawData.CheckIfValidControlData ("reason"); if (msg != null) { - _logger.Error (String.Format ("{0}\ncode: {1} reason: {2}", msg, code, reason)); + _logger.Error (msg); error ("An error has occurred in closing the connection.", null); return; } var send = _readyState == WebSocketState.Open && !code.IsReserved (); - close (new PayloadData (data), send, send); + close (e, send, send); } /// @@ -1676,7 +1692,7 @@ namespace WebSocketSharp } var send = _readyState == WebSocketState.Open; - closeAsync (new PayloadData (), send, send); + closeAsync (new CloseEventArgs (), send, send); } /// @@ -1697,7 +1713,18 @@ namespace WebSocketSharp /// public void CloseAsync (ushort code) { - CloseAsync (code, null); + var msg = _readyState.CheckIfClosable () ?? + code.CheckIfValidCloseStatusCode (); + + if (msg != null) { + _logger.Error (msg); + error ("An error has occurred in closing the connection.", null); + + return; + } + + var send = _readyState == WebSocketState.Open && !code.IsReserved (); + closeAsync (new CloseEventArgs (code), send, send); } /// @@ -1713,7 +1740,16 @@ namespace WebSocketSharp /// public void CloseAsync (CloseStatusCode code) { - CloseAsync (code, null); + var msg = _readyState.CheckIfClosable (); + if (msg != null) { + _logger.Error (msg); + error ("An error has occurred in closing the connection.", null); + + return; + } + + var send = _readyState == WebSocketState.Open && !code.IsReserved (); + closeAsync (new CloseEventArgs (code), send, send); } /// @@ -1726,7 +1762,7 @@ namespace WebSocketSharp /// /// /// This method emits a event if isn't in - /// the allowable range of the close status code, or the size of + /// the allowable range of the close status code or the size of /// is greater than 123 bytes. /// /// @@ -1738,20 +1774,20 @@ namespace WebSocketSharp /// public void CloseAsync (ushort code, string reason) { - byte[] data = null; + CloseEventArgs e = null; var msg = _readyState.CheckIfClosable () ?? code.CheckIfValidCloseStatusCode () ?? - (data = code.Append (reason)).CheckIfValidControlData ("reason"); + (e = new CloseEventArgs (code, reason)).RawData.CheckIfValidControlData ("reason"); if (msg != null) { - _logger.Error (String.Format ("{0}\ncode: {1} reason: {2}", msg, code, reason)); + _logger.Error (msg); error ("An error has occurred in closing the connection.", null); return; } var send = _readyState == WebSocketState.Open && !code.IsReserved (); - closeAsync (new PayloadData (data), send, send); + closeAsync (e, send, send); } /// @@ -1777,19 +1813,19 @@ namespace WebSocketSharp /// public void CloseAsync (CloseStatusCode code, string reason) { - byte[] data = null; + CloseEventArgs e = null; var msg = _readyState.CheckIfClosable () ?? - (data = ((ushort) code).Append (reason)).CheckIfValidControlData ("reason"); + (e = new CloseEventArgs (code, reason)).RawData.CheckIfValidControlData ("reason"); if (msg != null) { - _logger.Error (String.Format ("{0}\ncode: {1} reason: {2}", msg, code, reason)); + _logger.Error (msg); error ("An error has occurred in closing the connection.", null); return; } var send = _readyState == WebSocketState.Open && !code.IsReserved (); - closeAsync (new PayloadData (data), send, send); + closeAsync (e, send, send); } /// @@ -2224,9 +2260,8 @@ namespace WebSocketSharp /// void IDisposable.Dispose () { - var data = ((ushort) CloseStatusCode.Away).InternalToByteArray (ByteOrder.Big); var send = _readyState == WebSocketState.Open; - close (new PayloadData (data), send, send); + close (new CloseEventArgs (CloseStatusCode.Away), send, send); } #endregion