using System; using System.Collections.Generic; using System.Linq; using System.Text; using SuperSocket.SocketBase.Command; using SuperWebSocket.Protocol; namespace SuperWebSocket.Command { /// /// FragmentCommand /// /// The type of the web socket session. abstract class FragmentCommand : CommandBase where TWebSocketSession : WebSocketSession, new() { /// /// Gets the UTF8 encoding which has been set ExceptionFallback. /// protected Encoding Utf8Encoding { get; private set; } /// /// Initializes a new instance of the class. /// public FragmentCommand() { Utf8Encoding = Encoding.GetEncoding(65001, EncoderFallback.ExceptionFallback, DecoderFallback.ExceptionFallback); } /// /// Checks the frame. /// /// The frame. /// protected bool CheckFrame(WebSocketDataFrame frame) { //Check RSV return (frame.InnerData[0] & 0x70) == 0x00; } /// /// Checks the control frame. /// /// The frame. /// protected bool CheckControlFrame(WebSocketDataFrame frame) { if (!CheckFrame(frame)) return false; //http://tools.ietf.org/html/rfc6455#section-5.5 //All control frames MUST have a payload length of 125 bytes or less and MUST NOT be fragmented if (!frame.FIN || frame.ActualPayloadLength > 125) { return false; } return true; } /// /// Gets data from websocket frames. /// /// The frames. /// protected byte[] GetWebSocketData(IList frames) { int offset, length; var resultBuffer = new byte[frames.Sum(f => (int)f.ActualPayloadLength)]; int copied = 0; for (var i = 0; i < frames.Count; i++) { var frame = frames[i]; offset = frame.InnerData.Count - (int)frame.ActualPayloadLength; length = (int)frame.ActualPayloadLength; if (length > 0) { if (frame.HasMask) { frame.InnerData.DecodeMask(frame.MaskKey, offset, length); } frame.InnerData.CopyTo(resultBuffer, offset, copied, length); copied += length; } } return resultBuffer; } /// /// Gets text string from websocket frames. /// /// The frames. /// protected string GetWebSocketText(IList frames) { var data = GetWebSocketData(frames); return Utf8Encoding.GetString(data); } /// /// Gets data from a websocket frame. /// /// The frame. /// protected byte[] GetWebSocketData(WebSocketDataFrame frame) { int offset = frame.InnerData.Count - (int)frame.ActualPayloadLength; int length = (int)frame.ActualPayloadLength; if (frame.HasMask && length > 0) { frame.InnerData.DecodeMask(frame.MaskKey, offset, length); } byte[] data; if (length > 0) data = frame.InnerData.ToArrayData(offset, length); else data = new byte[0]; return data; } /// /// Gets text string from a websocket frame. /// /// The frame. /// protected string GetWebSocketText(WebSocketDataFrame frame) { int offset = frame.InnerData.Count - (int)frame.ActualPayloadLength; int length = (int)frame.ActualPayloadLength; if (frame.HasMask && length > 0) { frame.InnerData.DecodeMask(frame.MaskKey, offset, length); } string text; if (length > 0) { text = frame.InnerData.Decode(Utf8Encoding, offset, length); } else { text = string.Empty; } return text; } } }