private static string print(WsFrame frame) { /* 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 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)); }
private static WsFrame parse(byte [] header, Stream stream, bool unmask) { /* Header */ // FIN var fin = (header [0] & 0x80) == 0x80 ? Fin.FINAL : Fin.MORE; // RSV1 var rsv1 = (header [0] & 0x40) == 0x40 ? Rsv.ON : Rsv.OFF; // RSV2 var rsv2 = (header [0] & 0x20) == 0x20 ? Rsv.ON : Rsv.OFF; // RSV3 var rsv3 = (header [0] & 0x10) == 0x10 ? Rsv.ON : Rsv.OFF; // Opcode var opcode = (Opcode)(header [0] & 0x0f); // MASK var mask = (header [1] & 0x80) == 0x80 ? Mask.MASK : Mask.UNMASK; // 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) { throw new WebSocketException( CloseStatusCode.INCONSISTENT_DATA, "The payload data length of a control frame is greater than 125 bytes."); } var frame = new WsFrame { Fin = fin, Rsv1 = rsv1, Rsv2 = rsv2, Rsv3 = rsv3, Opcode = opcode, Mask = mask, PayloadLen = payloadLen }; /* Extended Payload Length */ var extLen = payloadLen < 126 ? 0 : payloadLen == 126 ? 2 : 8; var extPayloadLen = extLen > 0 ? stream.ReadBytes(extLen) : new byte [] {}; if (extLen > 0 && extPayloadLen.Length != extLen) { throw new WebSocketException( "The 'Extended Payload Length' of a frame cannot be read from the data source."); } frame.ExtPayloadLen = extPayloadLen; /* Masking Key */ var masked = mask == Mask.MASK; var maskingKey = masked ? stream.ReadBytes(4) : new byte [] {}; if (masked && maskingKey.Length != 4) { throw new WebSocketException( "The 'Masking Key' of a frame cannot be read from the data source."); } frame.MaskingKey = maskingKey; /* Payload Data */ ulong dataLen = payloadLen < 126 ? payloadLen : payloadLen == 126 ? extPayloadLen.ToUInt16(ByteOrder.BIG) : extPayloadLen.ToUInt64(ByteOrder.BIG); byte [] data = null; if (dataLen > 0) { // Check if allowable payload data length. if (payloadLen > 126 && dataLen > PayloadData.MaxLength) { throw new WebSocketException( CloseStatusCode.TOO_BIG, "The 'Payload Data' length is greater than the allowable length."); } data = payloadLen > 126 ? stream.ReadBytes((long)dataLen, 1024) : stream.ReadBytes((int)dataLen); if (data.LongLength != (long)dataLen) { throw new WebSocketException( "The 'Payload Data' of a frame cannot be read from the data source."); } } else { data = new byte [] {}; } var payload = new PayloadData(data, masked); if (masked && unmask) { payload.Mask(maskingKey); frame.Mask = Mask.UNMASK; frame.MaskingKey = new byte [] {}; } frame.PayloadData = payload; return(frame); }
private static string dump(WsFrame frame) { var len = frame.Length; var count = (long)(len / 4); var rem = (int)(len % 4); int countDigit; string countFmt; if (count < 10000) { countDigit = 4; countFmt = "{0,4}"; } else if (count < 0x010000) { countDigit = 4; countFmt = "{0,4:X}"; } else if (count < 0x0100000000) { countDigit = 8; countFmt = "{0,8:X}"; } else { countDigit = 16; countFmt = "{0,16:X}"; } var spFmt = String.Format("{{0,{0}}}", countDigit); var headerFmt = String.Format( @"{0} 01234567 89ABCDEF 01234567 89ABCDEF {0}+--------+--------+--------+--------+\n", spFmt); var footerFmt = String.Format("{0}+--------+--------+--------+--------+", spFmt); var buffer = new StringBuilder(64); Func <Action <string, string, string, string> > linePrinter = () => { long lineCount = 0; var lineFmt = String.Format("{0}|{{1,8}} {{2,8}} {{3,8}} {{4,8}}|\n", countFmt); return((arg1, arg2, arg3, arg4) => buffer.AppendFormat(lineFmt, ++lineCount, arg1, arg2, arg3, arg4)); }; var printLine = linePrinter(); buffer.AppendFormat(headerFmt, String.Empty); var frameAsBytes = frame.ToByteArray(); int i, j; for (i = 0; i <= count; i++) { j = i * 4; if (i < count) { 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')); } 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, String.Empty); } } buffer.AppendFormat(footerFmt, String.Empty); return(buffer.ToString()); }
public bool WriteFrame(WsFrame frame) { return(Write(frame.ToByteArray())); }
public void ReadFrameAsync(Action <WsFrame> completed, Action <Exception> error) { WsFrame.ParseAsync(_innerStream, true, completed, error); }
public WsFrame ReadFrame() { return(WsFrame.Parse(_innerStream, true)); }