From 5dc4703b332dd2b43b6830da000298518250987c Mon Sep 17 00:00:00 2001 From: sta Date: Sat, 26 Jul 2014 22:01:13 +0900 Subject: [PATCH] Refactored WebSocketFrame.cs --- websocket-sharp/WebSocket.cs | 4 +- websocket-sharp/WebSocketFrame.cs | 271 ++++++++++++++--------------- websocket-sharp/WebSocketStream.cs | 4 +- 3 files changed, 132 insertions(+), 147 deletions(-) diff --git a/websocket-sharp/WebSocket.cs b/websocket-sharp/WebSocket.cs index 293b44df..fa5fa1c6 100644 --- a/websocket-sharp/WebSocket.cs +++ b/websocket-sharp/WebSocket.cs @@ -1141,7 +1141,7 @@ namespace WebSocketSharp } return _stream.WriteBytes ( - WebSocketFrame.CreateFrame (fin, opcode, mask, data, compressed).ToByteArray ()); + WebSocketFrame.CreateWebSocketFrame (fin, opcode, mask, data, compressed).ToByteArray ()); } } @@ -1424,7 +1424,7 @@ namespace WebSocketSharp try { byte[] cached; if (!cache.TryGetValue (_compression, out cached)) { - cached = WebSocketFrame.CreateFrame ( + cached = WebSocketFrame.CreateWebSocketFrame ( Fin.Final, opcode, Mask.Unmask, diff --git a/websocket-sharp/WebSocketFrame.cs b/websocket-sharp/WebSocketFrame.cs index 131b0f55..58ce15f1 100644 --- a/websocket-sharp/WebSocketFrame.cs +++ b/websocket-sharp/WebSocketFrame.cs @@ -38,10 +38,10 @@ namespace WebSocketSharp { #region Private Fields - private byte [] _extPayloadLength; + private byte[] _extPayloadLength; private Fin _fin; private Mask _mask; - private byte [] _maskingKey; + private byte[] _maskingKey; private Opcode _opcode; private PayloadData _payloadData; private byte _payloadLength; @@ -51,9 +51,9 @@ namespace WebSocketSharp #endregion - #region Internal Static Fields + #region Internal Fields - internal static readonly byte [] EmptyUnmaskPingData; + internal static readonly byte[] EmptyUnmaskPingData; #endregion @@ -74,24 +74,25 @@ namespace WebSocketSharp #endregion - #region Public Constructors + #region Internal Constructors - public WebSocketFrame (Opcode opcode, PayloadData payload) + internal WebSocketFrame (Opcode opcode, PayloadData payload) : this (Fin.Final, opcode, Mask.Mask, payload, false) { } - public WebSocketFrame (Opcode opcode, Mask mask, PayloadData payload) + internal WebSocketFrame (Opcode opcode, Mask mask, PayloadData payload) : this (Fin.Final, opcode, mask, payload, false) { } - public WebSocketFrame (Fin fin, Opcode opcode, Mask mask, PayloadData payload) + internal WebSocketFrame (Fin fin, Opcode opcode, Mask mask, PayloadData payload) : this (fin, opcode, mask, payload, false) { } - public WebSocketFrame (Fin fin, Opcode opcode, Mask mask, PayloadData payload, bool compressed) + internal WebSocketFrame ( + Fin fin, Opcode opcode, Mask mask, PayloadData payload, bool compressed) { _fin = fin; _rsv1 = isData (opcode) && compressed ? Rsv.On : Rsv.Off; @@ -103,7 +104,7 @@ namespace WebSocketSharp var len = payload.Length; if (len < 126) { _payloadLength = (byte) len; - _extPayloadLength = new byte [0]; + _extPayloadLength = new byte[0]; } else if (len < 0x010000) { _payloadLength = (byte) 126; @@ -119,7 +120,7 @@ namespace WebSocketSharp payload.Mask (_maskingKey); } else { - _maskingKey = new byte [0]; + _maskingKey = new byte[0]; } _payloadData = payload; @@ -129,7 +130,7 @@ namespace WebSocketSharp #region Public Properties - public byte [] ExtendedPayloadLength { + public byte[] ExtendedPayloadLength { get { return _extPayloadLength; } @@ -231,7 +232,7 @@ namespace WebSocketSharp } } - public byte [] MaskingKey { + public byte[] MaskingKey { get { return _maskingKey; } @@ -277,9 +278,9 @@ namespace WebSocketSharp #region Private Methods - private static byte [] createMaskingKey () + private static byte[] createMaskingKey () { - var key = new byte [4]; + var key = new byte[4]; var rand = new Random (); rand.NextBytes (key); @@ -333,15 +334,15 @@ namespace WebSocketSharp var j = i * 4; if (i < cnt) printLine ( - 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')); + 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 (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, + 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); } @@ -359,24 +360,85 @@ namespace WebSocketSharp return opcode == Opcode.Text || opcode == Opcode.Binary; } - private static WebSocketFrame parse (byte [] header, Stream stream, bool unmask) + private static string print (WebSocketFrame frame) + { + /* Opcode */ + + var opcode = frame._opcode.ToString (); + + /* Payload Length */ + + var payloadLen = frame._payloadLength; + + /* Extended Payload Length */ + + var ext = frame._extPayloadLength; + var size = ext.Length; + var extPayloadLen = 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; + + /* Payload Data */ + + var payload = payloadLen == 0 + ? String.Empty + : size > 0 + ? String.Format ("A {0} frame.", opcode.ToLower ()) + : !masked && !frame.IsFragmented && frame.IsText + ? Encoding.UTF8.GetString (frame._payloadData.ApplicationData) + : frame._payloadData.ToString (); + + var fmt = +@" FIN: {0} + RSV1: {1} + RSV2: {2} + RSV3: {3} + Opcode: {4} + MASK: {5} + Payload Length: {6} +Extended Payload Length: {7} + Masking Key: {8} + Payload Data: {9}"; + + return String.Format ( + fmt, + frame._fin, + frame._rsv1, + frame._rsv2, + frame._rsv3, + opcode, + frame._mask, + payloadLen, + extPayloadLen, + maskingKey, + payload); + } + + private static WebSocketFrame read (byte[] header, Stream stream, bool unmask) { /* Header */ // FIN - var fin = (header [0] & 0x80) == 0x80 ? Fin.Final : Fin.More; + var fin = (header[0] & 0x80) == 0x80 ? Fin.Final : Fin.More; // RSV1 - var rsv1 = (header [0] & 0x40) == 0x40 ? Rsv.On : Rsv.Off; + var rsv1 = (header[0] & 0x40) == 0x40 ? Rsv.On : Rsv.Off; // RSV2 - var rsv2 = (header [0] & 0x20) == 0x20 ? Rsv.On : Rsv.Off; + var rsv2 = (header[0] & 0x20) == 0x20 ? Rsv.On : Rsv.Off; // RSV3 - var rsv3 = (header [0] & 0x10) == 0x10 ? Rsv.On : Rsv.Off; + var rsv3 = (header[0] & 0x10) == 0x10 ? Rsv.On : Rsv.Off; // Opcode - var opcode = (Opcode) (header [0] & 0x0f); + var opcode = (Opcode) (header[0] & 0x0f); // MASK - var mask = (header [1] & 0x80) == 0x80 ? Mask.Mask : Mask.Unmask; + var mask = (header[1] & 0x80) == 0x80 ? Mask.Mask : Mask.Unmask; // Payload Length - var payloadLen = (byte) (header [1] & 0x7f); + var payloadLen = (byte) (header[1] & 0x7f); // Check if correct frame. var incorrect = isControl (opcode) && fin == Fin.More @@ -411,7 +473,7 @@ namespace WebSocketSharp ? 2 : 8; - var extPayloadLen = size > 0 ? stream.ReadBytes (size) : new byte [0]; + var extPayloadLen = size > 0 ? stream.ReadBytes (size) : new byte[0]; if (size > 0 && extPayloadLen.Length != size) throw new WebSocketException ( "The 'Extended Payload Length' of a frame cannot be read from the data source."); @@ -421,7 +483,7 @@ namespace WebSocketSharp /* Masking Key */ var masked = mask == Mask.Mask; - var maskingKey = masked ? stream.ReadBytes (4) : new byte [0]; + var maskingKey = masked ? stream.ReadBytes (4) : new byte[0]; if (masked && maskingKey.Length != 4) throw new WebSocketException ( "The 'Masking Key' of a frame cannot be read from the data source."); @@ -436,7 +498,7 @@ namespace WebSocketSharp ? extPayloadLen.ToUInt16 (ByteOrder.Big) : extPayloadLen.ToUInt64 (ByteOrder.Big); - byte [] data = null; + byte[] data = null; if (len > 0) { // Check if allowable payload data length. if (payloadLen > 126 && len > PayloadData.MaxLength) @@ -453,170 +515,83 @@ namespace WebSocketSharp "The 'Payload Data' of a frame cannot be read from the data source."); } else { - data = new byte [0]; + data = new byte[0]; } var payload = new PayloadData (data, masked); if (masked && unmask) { payload.Mask (maskingKey); frame._mask = Mask.Unmask; - frame._maskingKey = new byte [0]; + frame._maskingKey = new byte[0]; } frame._payloadData = payload; return frame; } - private static string print (WebSocketFrame frame) - { - /* Opcode */ - - var opcode = frame._opcode.ToString (); - - /* Payload Length */ - - var payloadLen = frame._payloadLength; - - /* Extended Payload Length */ - - var ext = frame._extPayloadLength; - var size = ext.Length; - var extPayloadLen = 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; - - /* Payload Data */ - - var payload = payloadLen == 0 - ? String.Empty - : size > 0 - ? String.Format ("A {0} frame.", opcode.ToLower ()) - : !masked && !frame.IsFragmented && frame.IsText - ? Encoding.UTF8.GetString (frame._payloadData.ApplicationData) - : frame._payloadData.ToString (); - - var format = -@" FIN: {0} - RSV1: {1} - RSV2: {2} - RSV3: {3} - Opcode: {4} - MASK: {5} - Payload Length: {6} -Extended Payload Length: {7} - Masking Key: {8} - Payload Data: {9}"; - - return String.Format ( - format, - frame._fin, - frame._rsv1, - frame._rsv2, - frame._rsv3, - opcode, - frame._mask, - payloadLen, - extPayloadLen, - maskingKey, - payload); - } - #endregion #region Internal Methods - internal static WebSocketFrame CreateCloseFrame (Mask mask, PayloadData payload) + internal static WebSocketFrame CreateCloseFrame (Mask mask, byte[] data) { - return new WebSocketFrame (Opcode.Close, mask, payload); - } - - internal static WebSocketFrame CreatePongFrame (Mask mask, PayloadData payload) - { - return new WebSocketFrame (Opcode.Pong, mask, payload); + return new WebSocketFrame (Opcode.Close, mask, new PayloadData (data)); } - #endregion - - #region Public Methods - - public static WebSocketFrame CreateCloseFrame (Mask mask, byte [] data) + internal static WebSocketFrame CreateCloseFrame (Mask mask, PayloadData payload) { - return new WebSocketFrame (Opcode.Close, mask, new PayloadData (data)); + return new WebSocketFrame (Opcode.Close, mask, payload); } - public static WebSocketFrame CreateCloseFrame (Mask mask, CloseStatusCode code, string reason) + internal static WebSocketFrame CreateCloseFrame (Mask mask, CloseStatusCode code, string reason) { return new WebSocketFrame ( Opcode.Close, mask, new PayloadData (((ushort) code).Append (reason))); } - public static WebSocketFrame CreateFrame ( - Fin fin, Opcode opcode, Mask mask, byte [] data, bool compressed) - { - return new WebSocketFrame (fin, opcode, mask, new PayloadData (data), compressed); - } - - public static WebSocketFrame CreatePingFrame (Mask mask) + internal static WebSocketFrame CreatePingFrame (Mask mask) { return new WebSocketFrame (Opcode.Ping, mask, new PayloadData ()); } - public static WebSocketFrame CreatePingFrame (Mask mask, byte [] data) + internal static WebSocketFrame CreatePingFrame (Mask mask, byte[] data) { return new WebSocketFrame (Opcode.Ping, mask, new PayloadData (data)); } - public IEnumerator GetEnumerator () - { - foreach (var b in ToByteArray ()) - yield return b; - } - - public static WebSocketFrame Parse (byte [] src) + internal static WebSocketFrame CreatePongFrame (Mask mask, PayloadData payload) { - return Parse (src, true); + return new WebSocketFrame (Opcode.Pong, mask, payload); } - public static WebSocketFrame Parse (Stream stream) + internal static WebSocketFrame CreateWebSocketFrame ( + Fin fin, Opcode opcode, Mask mask, byte[] data, bool compressed) { - return Parse (stream, true); + return new WebSocketFrame (fin, opcode, mask, new PayloadData (data), compressed); } - public static WebSocketFrame Parse (byte [] src, bool unmask) + internal static WebSocketFrame Read (Stream stream) { - using (var stream = new MemoryStream (src)) - return Parse (stream, unmask); + return Read (stream, true); } - public static WebSocketFrame Parse (Stream stream, bool unmask) + internal static WebSocketFrame Read (Stream stream, bool unmask) { 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 parse (header, stream, unmask); + return read (header, stream, unmask); } - public static void ParseAsync (Stream stream, Action completed) - { - ParseAsync (stream, true, completed, null); - } - - public static void ParseAsync ( + internal static void ReadAsync ( Stream stream, Action completed, Action error) { - ParseAsync (stream, true, completed, error); + ReadAsync (stream, true, completed, error); } - public static void ParseAsync ( + internal static void ReadAsync ( Stream stream, bool unmask, Action completed, Action error) { stream.ReadBytesAsync ( @@ -626,13 +601,23 @@ Extended Payload Length: {7} throw new WebSocketException ( "The header part of a frame cannot be read from the data source."); - var frame = parse (header, stream, unmask); + var frame = read (header, stream, unmask); if (completed != null) completed (frame); }, error); } + #endregion + + #region Public Methods + + public IEnumerator GetEnumerator () + { + foreach (var b in ToByteArray ()) + yield return b; + } + public void Print (bool dumped) { Console.WriteLine (dumped ? dump (this) : print (this)); @@ -645,7 +630,7 @@ Extended Payload Length: {7} : print (this); } - public byte [] ToByteArray () + public byte[] ToByteArray () { using (var buff = new MemoryStream ()) { var header = (int) _fin; diff --git a/websocket-sharp/WebSocketStream.cs b/websocket-sharp/WebSocketStream.cs index 21714972..a451fd35 100644 --- a/websocket-sharp/WebSocketStream.cs +++ b/websocket-sharp/WebSocketStream.cs @@ -157,13 +157,13 @@ namespace WebSocketSharp internal WebSocketFrame ReadWebSocketFrame () { - return WebSocketFrame.Parse (_innerStream, true); + return WebSocketFrame.Read (_innerStream, true); } internal void ReadWebSocketFrameAsync ( Action completed, Action error) { - WebSocketFrame.ParseAsync (_innerStream, true, completed, error); + WebSocketFrame.ReadAsync (_innerStream, true, completed, error); } internal HttpResponse SendHttpRequest (HttpRequest request, int millisecondsTimeout)