diff --git a/websocket-sharp/CloseEventArgs.cs b/websocket-sharp/CloseEventArgs.cs index cec627a4..35dba173 100644 --- a/websocket-sharp/CloseEventArgs.cs +++ b/websocket-sharp/CloseEventArgs.cs @@ -36,10 +36,10 @@ namespace WebSocketSharp /// /// /// A event occurs when the WebSocket connection has been closed. - /// If you want to get the reason for closure, you use the or + /// If you want to get the reason for closure, you access the or /// property. /// - public class CloseEventArgs : MessageEventArgs + public class CloseEventArgs : EventArgs { #region Private Fields @@ -52,10 +52,10 @@ namespace WebSocketSharp #region Internal Constructors internal CloseEventArgs (PayloadData payload) - : base (Opcode.CLOSE, payload) { - _code = getCodeFrom (RawData); - _reason = getReasonFrom (RawData); + var data = payload.ApplicationData; + _code = getCodeFrom (data); + _reason = getReasonFrom (data); _clean = false; } @@ -67,7 +67,7 @@ namespace WebSocketSharp /// Gets the status code for closure. /// /// - /// A that contains a status code for closure if any. + /// A that indicates the status code for closure if any. /// public ushort Code { get { @@ -88,10 +88,10 @@ namespace WebSocketSharp } /// - /// Indicates whether the WebSocket connection has been closed cleanly. + /// Gets a value indicating whether the WebSocket connection has been closed cleanly. /// /// - /// true if the WebSocket connection has been closed cleanly; otherwise, false. + /// true if the connection has been closed cleanly; otherwise, false. /// public bool WasClean { get { @@ -111,7 +111,7 @@ namespace WebSocketSharp { return data.Length > 1 ? data.SubArray (0, 2).ToUInt16 (ByteOrder.BIG) - : (ushort) 0; + : (ushort) CloseStatusCode.NO_STATUS_CODE; } private static string getReasonFrom (byte [] data) diff --git a/websocket-sharp/CloseStatusCode.cs b/websocket-sharp/CloseStatusCode.cs index 0c2146e0..1cf2f058 100644 --- a/websocket-sharp/CloseStatusCode.cs +++ b/websocket-sharp/CloseStatusCode.cs @@ -28,15 +28,16 @@ using System; -namespace WebSocketSharp { - +namespace WebSocketSharp +{ /// /// Contains the values of the status codes for the WebSocket connection closure. /// /// /// - /// The CloseStatusCode enumeration contains the values of the status codes for the WebSocket connection closure - /// defined in RFC 6455 for the WebSocket protocol. + /// The CloseStatusCode enumeration contains the values of the status codes for the WebSocket + /// connection closure defined in RFC 6455 + /// for the WebSocket protocol. /// /// /// "Reserved value" must not be set as a status code in a close control frame by an endpoint. @@ -55,13 +56,14 @@ namespace WebSocketSharp { /// AWAY = 1001, /// - /// Equivalent to close status 1002. Indicates that an endpoint is terminating the connection - /// due to a protocol error. + /// Equivalent to close status 1002. + /// Indicates that an endpoint is terminating the connection due to a protocol error. /// PROTOCOL_ERROR = 1002, /// - /// Equivalent to close status 1003. Indicates that an endpoint is terminating the connection - /// because it has received a type of data it cannot accept. + /// Equivalent to close status 1003. + /// Indicates that an endpoint is terminating the connection because it has received + /// a type of data it cannot accept. /// INCORRECT_DATA = 1003, /// @@ -69,42 +71,50 @@ namespace WebSocketSharp { /// UNDEFINED = 1004, /// - /// Equivalent to close status 1005. Indicates that no status code was actually present. Reserved value. + /// Equivalent to close status 1005. + /// Indicates that no status code was actually present. Reserved value. /// NO_STATUS_CODE = 1005, /// - /// Equivalent to close status 1006. Indicates that the connection was closed abnormally. Reserved value. + /// Equivalent to close status 1006. + /// Indicates that the connection was closed abnormally. Reserved value. /// ABNORMAL = 1006, /// - /// Equivalent to close status 1007. Indicates that an endpoint is terminating the connection - /// because it has received data within a message that was not consistent with the type of the message. + /// Equivalent to close status 1007. + /// Indicates that an endpoint is terminating the connection because it has received + /// data within a message that was not consistent with the type of the message. /// INCONSISTENT_DATA = 1007, /// - /// Equivalent to close status 1008. Indicates that an endpoint is terminating the connection - /// because it has received a message that violates its policy. + /// Equivalent to close status 1008. + /// Indicates that an endpoint is terminating the connection because it has received + /// a message that violates its policy. /// POLICY_VIOLATION = 1008, /// - /// Equivalent to close status 1009. Indicates that an endpoint is terminating the connection - /// because it has received a message that is too big for it to process. + /// Equivalent to close status 1009. + /// Indicates that an endpoint is terminating the connection because it has received + /// a message that is too big to process. /// TOO_BIG = 1009, /// - /// Equivalent to close status 1010. Indicates that an endpoint (client) is terminating the connection - /// because it has expected the server to negotiate one or more extension, but the server didn't return - /// them in the response message of the WebSocket handshake. + /// Equivalent to close status 1010. + /// Indicates that an endpoint (client) is terminating the connection because it has expected + /// the server to negotiate one or more extension, but the server didn't return them + /// in the response message of the WebSocket handshake. /// IGNORE_EXTENSION = 1010, /// - /// Equivalent to close status 1011. Indicates that a server is terminating the connection because it encountered + /// Equivalent to close status 1011. + /// Indicates that a server is terminating the connection because it encountered /// an unexpected condition that prevented it from fulfilling the request. /// SERVER_ERROR = 1011, /// - /// Equivalent to close status 1015. Indicates that the connection was closed due to a failure to perform - /// a TLS handshake. Reserved value. + /// Equivalent to close status 1015. + /// Indicates that the connection was closed due to a failure to perform a TLS handshake. + /// Reserved value. /// TLS_HANDSHAKE_FAILURE = 1015 } diff --git a/websocket-sharp/ErrorEventArgs.cs b/websocket-sharp/ErrorEventArgs.cs index 9b11c626..8c38c551 100644 --- a/websocket-sharp/ErrorEventArgs.cs +++ b/websocket-sharp/ErrorEventArgs.cs @@ -28,20 +28,20 @@ using System; -namespace WebSocketSharp { - +namespace WebSocketSharp +{ /// - /// Contains the event data associated with a error event. + /// Contains the event data associated with a event. /// /// - /// The error event occurs when this event sender gets an error. - /// If you want to get the error message, you should access the property. + /// A event occurs when the gets an error. + /// If you want to get the error message, you access the property. /// public class ErrorEventArgs : EventArgs { #region Internal Constructors - internal ErrorEventArgs(string message) + internal ErrorEventArgs (string message) { Message = message; } @@ -54,7 +54,7 @@ namespace WebSocketSharp { /// Gets the error message. /// /// - /// A that contains a error message. + /// A that contains an error message. /// public string Message { get; private set; } diff --git a/websocket-sharp/Ext.cs b/websocket-sharp/Ext.cs index 9db34be2..bc0eb04b 100644 --- a/websocket-sharp/Ext.cs +++ b/websocket-sharp/Ext.cs @@ -300,6 +300,14 @@ namespace WebSocketSharp : stream.ToByteArray (); } + internal static T [] Copy (this T [] src, long length) + { + var dest = new T [length]; + Array.Copy (src, 0, dest, 0, length); + + return dest; + } + internal static void CopyTo (this Stream src, Stream dest) { src.CopyTo (dest, false); @@ -399,6 +407,17 @@ namespace WebSocketSharp : original; } + internal static string GetErrorMessage (this CloseStatusCode code) + { + return code == CloseStatusCode.INCORRECT_DATA + ? "An incorrect data has been received." + : code == CloseStatusCode.INCONSISTENT_DATA + ? "An inconsistent data has been received." + : code == CloseStatusCode.TOO_BIG + ? "A too big data has been received." + : "A WebSocket exception has occured."; + } + internal static string GetNameInternal (this string nameAndValue, string separator) { int i = nameAndValue.IndexOf (separator); @@ -407,16 +426,15 @@ namespace WebSocketSharp : null; } - internal static string GetMessage (this CloseStatusCode code) + internal static string GetReason (this CloseStatusCode code) { - if (code == CloseStatusCode.ABNORMAL) - return "What we've got here is a failure to communicate in the WebSocket protocol."; - - if (code == CloseStatusCode.TOO_BIG) - return String.Format ("The size of received payload data is bigger than the allowable value ({0} bytes).", - PayloadData.MaxLength); - - return String.Empty; + return code == CloseStatusCode.ABNORMAL + ? "A WebSocket exception has occured." + : code == CloseStatusCode.TOO_BIG + ? String.Format ( + "The payload data length is greater than the allowable length ({0} bytes).", + PayloadData.MaxLength) + : String.Empty; } internal static string GetValueInternal (this string nameAndValue, string separator) diff --git a/websocket-sharp/MessageEventArgs.cs b/websocket-sharp/MessageEventArgs.cs index cf2cf8a1..64d1583a 100644 --- a/websocket-sharp/MessageEventArgs.cs +++ b/websocket-sharp/MessageEventArgs.cs @@ -35,9 +35,10 @@ namespace WebSocketSharp /// Contains the event data associated with a event. /// /// - /// The event occurs when the WebSocket receives a text or binary data frame. - /// If you want to get the received data, you should access the or - /// properties. + /// A event occurs when the receives + /// a text or binary data frame. + /// If you want to get the received data, you access the or + /// property. /// public class MessageEventArgs : EventArgs { @@ -51,19 +52,21 @@ namespace WebSocketSharp #region Internal Constructors - internal MessageEventArgs (Opcode opcode, byte[] rawData) + internal MessageEventArgs (Opcode opcode, byte[] data) { - if ((ulong) rawData.LongLength > PayloadData.MaxLength) + if ((ulong) data.LongLength > PayloadData.MaxLength) throw new WebSocketException (CloseStatusCode.TOO_BIG); _opcode = opcode; - _rawData = rawData; + _rawData = data; + _data = convertToString (opcode, data); } - internal MessageEventArgs (Opcode opcode, PayloadData data) + internal MessageEventArgs (Opcode opcode, PayloadData payload) { _opcode = opcode; - _rawData = data.ApplicationData; + _rawData = payload.ApplicationData; + _data = convertToString (opcode, _rawData); } #endregion @@ -78,13 +81,6 @@ namespace WebSocketSharp /// public string Data { get { - if (_data == null) - _data = _rawData.LongLength == 0 - ? String.Empty - : _opcode == Opcode.TEXT - ? Encoding.UTF8.GetString (_rawData) - : _opcode.ToString (); - return _data; } } @@ -114,5 +110,18 @@ namespace WebSocketSharp } #endregion + + #region Private Methods + + private static string convertToString (Opcode opcode, byte [] data) + { + return data.LongLength == 0 + ? String.Empty + : opcode == Opcode.TEXT + ? Encoding.UTF8.GetString (data) + : opcode.ToString (); + } + + #endregion } } diff --git a/websocket-sharp/WebSocket.cs b/websocket-sharp/WebSocket.cs index 2f670261..05387de7 100644 --- a/websocket-sharp/WebSocket.cs +++ b/websocket-sharp/WebSocket.cs @@ -316,7 +316,7 @@ namespace WebSocketSharp /// Gets a value indicating whether the WebSocket connection is alive. /// /// - /// true if the WebSocket connection is alive; otherwise, false. + /// true if the connection is alive; otherwise, false. /// public bool IsAlive { get { @@ -627,11 +627,6 @@ namespace WebSocketSharp while (true) { var frame = _stream.ReadFrame (); - if (frame == null) - return processAbnormalFrame (); - - if (frame.IsCompressed) - return processIncorrectFrame (); // MORE & CONT if (!frame.IsFinal && frame.IsContinuation) @@ -666,7 +661,7 @@ namespace WebSocketSharp return processCloseFrame (frame); // ? - return processIncorrectFrame (); + return processIncorrectFrame (frame, null); } return true; @@ -827,14 +822,6 @@ namespace WebSocketSharp startReceiving (); } - private bool processAbnormalFrame () - { - var code = CloseStatusCode.ABNORMAL; - close (code, code.GetMessage (), false); - - return false; - } - private bool processCloseFrame (WsFrame frame) { var payload = frame.PayloadData; @@ -854,13 +841,30 @@ namespace WebSocketSharp return true; } + private void processException (Exception exception) + { + _logger.Fatal (exception.ToString ()); + + var code = CloseStatusCode.ABNORMAL; + var reason = "An exception has occured."; + var msg = reason; + if (exception.GetType () == typeof (WebSocketException)) + { + var wsex = (WebSocketException) exception; + code = wsex.Code; + reason = wsex.Message; + msg = code.GetErrorMessage (); + } + + error (msg); + close (code, reason, false); + } + private bool processFragmentedFrame (WsFrame frame) { return frame.IsContinuation // Not first fragment ? true - : frame.IsData - ? processFragments (frame) - : processIncorrectFrame (); + : processFragments (frame); } private bool processFragments (WsFrame first) @@ -889,27 +893,27 @@ namespace WebSocketSharp private bool processFrame (WsFrame frame) { - return frame == null - ? processAbnormalFrame () - : (!frame.IsData && frame.IsCompressed) || - (frame.IsCompressed && _compression == CompressionMethod.NONE) - ? processIncorrectFrame () - : frame.IsFragmented - ? processFragmentedFrame (frame) - : frame.IsData - ? processDataFrame (frame) - : frame.IsPing - ? processPingFrame (frame) - : frame.IsPong - ? processPongFrame () - : frame.IsClose - ? processCloseFrame (frame) - : processIncorrectFrame (); - } - - private bool processIncorrectFrame () - { - close (CloseStatusCode.INCORRECT_DATA, null, false); + return frame.IsCompressed && _compression == CompressionMethod.NONE + ? processIncorrectFrame (frame, "A compressed frame without available decompression method.") + : frame.IsFragmented + ? processFragmentedFrame (frame) + : frame.IsData + ? processDataFrame (frame) + : frame.IsPing + ? processPingFrame (frame) + : frame.IsPong + ? processPongFrame () + : frame.IsClose + ? processCloseFrame (frame) + : processIncorrectFrame (frame, null); + } + + private bool processIncorrectFrame (WsFrame frame, string reason) + { + _logger.Debug ("Incorrect frame:\n" + frame.PrintToString (false)); + processException (new WebSocketException ( + CloseStatusCode.INCORRECT_DATA, reason ?? String.Empty)); + return false; } @@ -1240,18 +1244,7 @@ namespace WebSocketSharp else _exitReceiving.Set (); }, - ex => - { - _logger.Fatal (ex.ToString ()); - error ("An exception has occured."); - if (ex.GetType () == typeof (WebSocketException)) - { - var wsex = (WebSocketException) ex; - close (wsex.Code, wsex.Message, false); - } - else - close (CloseStatusCode.ABNORMAL, null, false); - }); + processException); receive (); } @@ -1659,8 +1652,12 @@ namespace WebSocketSharp return; } - if (data.LongLength <= FragmentLength) - send (Opcode.BINARY, data, completed); + var len = data.LongLength; + if (len <= FragmentLength) + send ( + Opcode.BINARY, + len > 0 && _client && _compression == CompressionMethod.NONE ? data.Copy (len) : data, + completed); else send (Opcode.BINARY, new MemoryStream (data), completed); } diff --git a/websocket-sharp/WebSocketException.cs b/websocket-sharp/WebSocketException.cs index 1e6aba81..bd7394f5 100644 --- a/websocket-sharp/WebSocketException.cs +++ b/websocket-sharp/WebSocketException.cs @@ -44,17 +44,17 @@ namespace WebSocketSharp } internal WebSocketException (CloseStatusCode code) - : this (code, code.GetMessage ()) + : this (code, code.GetReason ()) { } - internal WebSocketException (string message) - : this (CloseStatusCode.NO_STATUS_CODE, message) + internal WebSocketException (string reason) + : this (CloseStatusCode.ABNORMAL, reason) { } - internal WebSocketException (CloseStatusCode code, string message) - : base (message) + internal WebSocketException (CloseStatusCode code, string reason) + : base (reason) { Code = code; } @@ -67,8 +67,7 @@ namespace WebSocketSharp /// Gets the associated with the . /// /// - /// One of the values that indicate the causes of - /// the . + /// One of the values, indicates the causes of the . /// public CloseStatusCode Code { get; private set; diff --git a/websocket-sharp/WsFrame.cs b/websocket-sharp/WsFrame.cs index 555f7141..7a83ddef 100644 --- a/websocket-sharp/WsFrame.cs +++ b/websocket-sharp/WsFrame.cs @@ -250,11 +250,11 @@ namespace WebSocketSharp return key; } - private static void dump (WsFrame frame) + private static string dump (WsFrame frame) { var len = frame.Length; var count = (long) (len / 4); - var remainder = (int) (len % 4); + var rem = (int) (len % 4); int countDigit; string countFmt; @@ -280,44 +280,44 @@ namespace WebSocketSharp } var spFmt = String.Format ("{{0,{0}}}", countDigit); - var headerFmt = String.Format (@" - {0} 01234567 89ABCDEF 01234567 89ABCDEF - {0}+--------+--------+--------+--------+", spFmt); - var footerFmt = String.Format (" {0}+--------+--------+--------+--------+", spFmt); + var headerFmt = String.Format ( +@"{0} 01234567 89ABCDEF 01234567 89ABCDEF +{0}+--------+--------+--------+--------+\n", spFmt); + var footerFmt = String.Format ("{0}+--------+--------+--------+--------+", spFmt); + var buffer = new StringBuilder (64); Func> linePrinter = () => { long lineCount = 0; - var lineFmt = String.Format (" {0}|{{1,8}} {{2,8}} {{3,8}} {{4,8}}|", countFmt); + var lineFmt = String.Format ("{0}|{{1,8}} {{2,8}} {{3,8}} {{4,8}}|\n", countFmt); return (arg1, arg2, arg3, arg4) => - { - Console.WriteLine (lineFmt, ++lineCount, arg1, arg2, arg3, arg4); - }; + buffer.AppendFormat (lineFmt, ++lineCount, arg1, arg2, arg3, arg4); }; var printLine = linePrinter (); - Console.WriteLine (headerFmt, String.Empty); + buffer.AppendFormat (headerFmt, String.Empty); - var buffer = frame.ToByteArray (); + var frameAsBytes = frame.ToByteArray (); int i, j; for (i = 0; i <= count; i++) { j = i * 4; if (i < count) printLine ( - Convert.ToString (buffer [j], 2).PadLeft (8, '0'), - Convert.ToString (buffer [j + 1], 2).PadLeft (8, '0'), - Convert.ToString (buffer [j + 2], 2).PadLeft (8, '0'), - Convert.ToString (buffer [j + 3], 2).PadLeft (8, '0')); - else if (remainder > 0) + Convert.ToString (frameAsBytes [j], 2).PadLeft (8, '0'), + Convert.ToString (frameAsBytes [j + 1], 2).PadLeft (8, '0'), + Convert.ToString (frameAsBytes [j + 2], 2).PadLeft (8, '0'), + Convert.ToString (frameAsBytes [j + 3], 2).PadLeft (8, '0')); + else if (rem > 0) printLine ( - Convert.ToString (buffer [j], 2).PadLeft (8, '0'), - remainder >= 2 ? Convert.ToString (buffer [j + 1], 2).PadLeft (8, '0') : String.Empty, - remainder == 3 ? Convert.ToString (buffer [j + 2], 2).PadLeft (8, '0') : String.Empty, + Convert.ToString (frameAsBytes [j], 2).PadLeft (8, '0'), + rem >= 2 ? Convert.ToString (frameAsBytes [j + 1], 2).PadLeft (8, '0') : String.Empty, + rem == 3 ? Convert.ToString (frameAsBytes [j + 2], 2).PadLeft (8, '0') : String.Empty, String.Empty); } - Console.WriteLine (footerFmt, String.Empty); + buffer.AppendFormat (footerFmt, String.Empty); + return buffer.ToString (); } private static bool isBinary (Opcode opcode) @@ -389,11 +389,21 @@ namespace WebSocketSharp // Payload len var payloadLen = (byte) (header [1] & 0x7f); + // Check if correct frame. + var incorrect = isControl (opcode) && fin == Fin.MORE + ? "A control frame is fragmented." + : !isData (opcode) && rsv1 == Rsv.ON + ? "A non data frame is compressed." + : null; + + if (incorrect != null) + throw new WebSocketException (CloseStatusCode.INCORRECT_DATA, incorrect); + + // Check if consistent frame. if (isControl (opcode) && payloadLen > 125) - return CreateCloseFrame ( - Mask.UNMASK, + throw new WebSocketException ( CloseStatusCode.INCONSISTENT_DATA, - "The payload length of a control frame must be 125 bytes or less."); + "The payload data length of a control frame is greater than 125 bytes."); var frame = new WsFrame { Fin = fin, @@ -418,10 +428,8 @@ namespace WebSocketSharp : new byte []{}; if (extLen > 0 && extPayloadLen.Length != extLen) - return CreateCloseFrame ( - Mask.UNMASK, - CloseStatusCode.ABNORMAL, - "The 'Extended Payload Length' part of a frame cannot be read from the data source."); + throw new WebSocketException ( + "The 'Extended Payload Length' of a frame cannot be read from the data source."); frame.ExtPayloadLen = extPayloadLen; @@ -433,10 +441,8 @@ namespace WebSocketSharp : new byte []{}; if (masked && maskingKey.Length != 4) - return CreateCloseFrame ( - Mask.UNMASK, - CloseStatusCode.ABNORMAL, - "The 'Masking Key' part of a frame cannot be read from the data source."); + throw new WebSocketException ( + "The 'Masking Key' of a frame cannot be read from the data source."); frame.MaskingKey = maskingKey; @@ -451,21 +457,17 @@ namespace WebSocketSharp byte [] data = null; if (dataLen > 0) { + // Check if allowable payload data length. if (payloadLen > 126 && dataLen > PayloadData.MaxLength) - { - var code = CloseStatusCode.TOO_BIG; - return CreateCloseFrame (Mask.UNMASK, code, code.GetMessage ()); - } + throw new WebSocketException (CloseStatusCode.TOO_BIG); data = payloadLen > 126 ? stream.ReadBytes ((long) dataLen, 1024) : stream.ReadBytes ((int) dataLen); if (data.LongLength != (long) dataLen) - return CreateCloseFrame ( - Mask.UNMASK, - CloseStatusCode.ABNORMAL, - "The 'Payload Data' part of a frame cannot be read from the data source."); + throw new WebSocketException ( + "The 'Payload Data' of a frame cannot be read from the data source."); } else { @@ -484,41 +486,67 @@ namespace WebSocketSharp return frame; } - private static void print (WsFrame frame) + private static string print (WsFrame frame) { - var len = frame.ExtPayloadLen.Length; - var extPayloadLen = len == 2 - ? frame.ExtPayloadLen.ToUInt16 (ByteOrder.BIG).ToString () - : len == 8 - ? frame.ExtPayloadLen.ToUInt64 (ByteOrder.BIG).ToString () - : String.Empty; + /* Opcode */ + + var opcode = frame.Opcode.ToString (); + + /* Payload Len */ + + var payloadLen = frame.PayloadLen; + + /* Extended Payload Len */ + + var ext = frame.ExtPayloadLen; + var size = ext.Length; + var extLen = size == 2 + ? ext.ToUInt16 (ByteOrder.BIG).ToString () + : size == 8 + ? ext.ToUInt64 (ByteOrder.BIG).ToString () + : String.Empty; + + /* Masking Key */ var masked = frame.IsMasked; - var maskingKey = masked - ? BitConverter.ToString (frame.MaskingKey) - : String.Empty; - - var opcode = frame.Opcode; - var payloadData = frame.PayloadData.Length == 0 - ? String.Empty - : masked || frame.IsFragmented || frame.IsBinary || frame.IsClose - ? BitConverter.ToString (frame.PayloadData.ToByteArray ()) - : Encoding.UTF8.GetString (frame.PayloadData.ToByteArray ()); - - var format = @" - FIN: {0} - RSV1: {1} - RSV2: {2} - RSV3: {3} - Opcode: {4} - MASK: {5} - Payload Len: {6} - Extended Payload Len: {7} - Masking Key: {8} - Payload Data: {9}"; - - Console.WriteLine ( - format, frame.Fin, frame.Rsv1, frame.Rsv2, frame.Rsv3, opcode, frame.Mask, frame.PayloadLen, extPayloadLen, maskingKey, payloadData); + var key = masked + ? BitConverter.ToString (frame.MaskingKey) + : String.Empty; + + /* Payload Data */ + + var data = payloadLen == 0 + ? String.Empty + : size > 0 + ? String.Format ("A {0} data with {1} bytes.", opcode.ToLower (), extLen) + : masked || frame.IsFragmented || frame.IsBinary || frame.IsClose + ? BitConverter.ToString (frame.PayloadData.ToByteArray ()) + : Encoding.UTF8.GetString (frame.PayloadData.ApplicationData); + + var format = +@" FIN: {0} + RSV1: {1} + RSV2: {2} + RSV3: {3} + Opcode: {4} + MASK: {5} + Payload Len: {6} +Extended Payload Len: {7} + Masking Key: {8} + Payload Data: {9}"; + + return String.Format ( + format, + frame.Fin, + frame.Rsv1, + frame.Rsv2, + frame.Rsv3, + opcode, + frame.Mask, + payloadLen, + extLen, + key, + data); } #endregion @@ -573,50 +601,30 @@ namespace WebSocketSharp public static WsFrame Parse (byte [] src) { - return Parse (src, true, null); + return Parse (src, true); } public static WsFrame Parse (Stream stream) { - return Parse (stream, true, null); - } - - public static WsFrame Parse (byte [] src, Action error) - { - return Parse (src, true, error); - } - - public static WsFrame Parse (Stream stream, Action error) - { - return Parse (stream, true, error); + return Parse (stream, true); } - public static WsFrame Parse (byte [] src, bool unmask, Action error) + public static WsFrame Parse (byte [] src, bool unmask) { using (var stream = new MemoryStream (src)) { - return Parse (stream, unmask, error); + return Parse (stream, unmask); } } - public static WsFrame Parse (Stream stream, bool unmask, Action error) + public static WsFrame Parse (Stream stream, bool unmask) { - WsFrame frame = null; - try { - var header = stream.ReadBytes (2); - frame = header.Length == 2 - ? parse (header, stream, unmask) - : CreateCloseFrame ( - Mask.UNMASK, - CloseStatusCode.ABNORMAL, - "The header part of a frame cannot be read from the data source."); - } - catch (Exception ex) { - if (error != null) - error (ex); - } + var header = stream.ReadBytes (2); + if (header.Length != 2) + throw new WebSocketException ( + "The header part of a frame cannot be read from the data source."); - return frame; + return parse (header, stream, unmask); } public static void ParseAsync (Stream stream, Action completed) @@ -636,13 +644,11 @@ namespace WebSocketSharp 2, header => { - var frame = header.Length == 2 - ? parse (header, stream, unmask) - : CreateCloseFrame ( - Mask.UNMASK, - CloseStatusCode.ABNORMAL, - "The header part of a frame cannot be read from the data source."); + if (header.Length != 2) + throw new WebSocketException ( + "The header part of a frame cannot be read from the data source."); + var frame = parse (header, stream, unmask); if (completed != null) completed (frame); }, @@ -651,10 +657,12 @@ namespace WebSocketSharp public void Print (bool dumped) { - if (dumped) - dump (this); - else - print (this); + Console.WriteLine (dumped ? dump (this) : print (this)); + } + + public string PrintToString (bool dumped) + { + return dumped ? dump (this) : print (this); } public byte [] ToByteArray() diff --git a/websocket-sharp/WsStream.cs b/websocket-sharp/WsStream.cs index 4ea3dd37..6642ec74 100644 --- a/websocket-sharp/WsStream.cs +++ b/websocket-sharp/WsStream.cs @@ -47,8 +47,7 @@ namespace WebSocketSharp #region Private Fields - private Object _forRead; - private Object _forWrite; + private object _forWrite; private Stream _innerStream; private bool _secure; @@ -60,7 +59,6 @@ namespace WebSocketSharp { _innerStream = innerStream; _secure = secure; - _forRead = new object (); _forWrite = new object (); } @@ -172,28 +170,12 @@ namespace WebSocketSharp public WsFrame ReadFrame () { - lock (_forRead) - { - return WsFrame.Parse (_innerStream, null); - } - } - - public WsFrame ReadFrame (Action error) - { - lock (_forRead) - { - return WsFrame.Parse (_innerStream, error); - } - } - - public void ReadFrameAsync (Action completed) - { - WsFrame.ParseAsync (_innerStream, completed, null); + return WsFrame.Parse (_innerStream, true); } public void ReadFrameAsync (Action completed, Action error) { - WsFrame.ParseAsync (_innerStream, completed, error); + WsFrame.ParseAsync (_innerStream, true, completed, error); } public string [] ReadHandshake ()