private static WebSocketFrame read(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 Length var payloadLen = (byte)(header[1] & 0x7f); // Check if valid header var err = isControl(opcode) && payloadLen > 125 ? "A control frame has a payload data which is greater than the allowable max size." : isControl(opcode) && fin == Fin.More ? "A control frame is fragmented." : !isData(opcode) && rsv1 == Rsv.On ? "A non data frame is compressed." : null; if (err != null) { throw new WebSocketException(CloseStatusCode.ProtocolError, err); } var frame = new WebSocketFrame(); frame._fin = fin; frame._rsv1 = rsv1; frame._rsv2 = rsv2; frame._rsv3 = rsv3; frame._opcode = opcode; frame._mask = mask; frame._payloadLength = payloadLen; /* Extended Payload Length */ var size = payloadLen < 126 ? 0 : payloadLen == 126 ? 2 : 8; 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."); } frame._extPayloadLength = extPayloadLen; /* Masking Key */ var masked = mask == Mask.Mask; 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."); } frame._maskingKey = maskingKey; /* Payload Data */ ulong len = payloadLen < 126 ? payloadLen : payloadLen == 126 ? extPayloadLen.ToUInt16(ByteOrder.Big) : extPayloadLen.ToUInt64(ByteOrder.Big); byte[] data = null; if (len > 0) { // Check if allowable max length. if (payloadLen > 126 && len > PayloadData.MaxLength) { throw new WebSocketException( CloseStatusCode.TooBig, "The length of 'Payload Data' of a frame is greater than the allowable max length."); } data = payloadLen > 126 ? stream.ReadBytes((long)len, 1024) : stream.ReadBytes((int)len); if (data.LongLength != (long)len) { throw new WebSocketException( "The 'Payload Data' of a frame cannot be read from the data source."); } } else { data = new byte[0]; } frame._payloadData = new PayloadData(data, masked); if (unmask && masked) { frame.Unmask(); } return(frame); }
internal MessageEventArgs(WebSocketFrame frame) { _opcode = frame.Opcode; _rawData = frame.PayloadData.ApplicationData; _data = convertToString(_opcode, _rawData); }
private static string dump(WebSocketFrame frame) { var len = frame.Length; var cnt = (long)(len / 4); var rem = (int)(len % 4); int cntDigit; string cntFmt; if (cnt < 10000) { cntDigit = 4; cntFmt = "{0,4}"; } else if (cnt < 0x010000) { cntDigit = 4; cntFmt = "{0,4:X}"; } else if (cnt < 0x0100000000) { cntDigit = 8; cntFmt = "{0,8:X}"; } else { cntDigit = 16; cntFmt = "{0,16:X}"; } var spFmt = String.Format("{{0,{0}}}", cntDigit); var headerFmt = String.Format(@" {0} 01234567 89ABCDEF 01234567 89ABCDEF {0}+--------+--------+--------+--------+\n", spFmt); var lineFmt = String.Format("{0}|{{1,8}} {{2,8}} {{3,8}} {{4,8}}|\n", cntFmt); var footerFmt = String.Format("{0}+--------+--------+--------+--------+", spFmt); var output = new StringBuilder(64); Func <Action <string, string, string, string> > linePrinter = () => { long lineCnt = 0; return((arg1, arg2, arg3, arg4) => output.AppendFormat(lineFmt, ++lineCnt, arg1, arg2, arg3, arg4)); }; output.AppendFormat(headerFmt, String.Empty); var printLine = linePrinter(); var bytes = frame.ToByteArray(); for (long i = 0; i <= cnt; i++) { var j = i * 4; if (i < cnt) { printLine( Convert.ToString(bytes[j], 2).PadLeft(8, '0'), Convert.ToString(bytes[j + 1], 2).PadLeft(8, '0'), Convert.ToString(bytes[j + 2], 2).PadLeft(8, '0'), Convert.ToString(bytes[j + 3], 2).PadLeft(8, '0')); } else if (rem > 0) { printLine( Convert.ToString(bytes[j], 2).PadLeft(8, '0'), rem >= 2 ? Convert.ToString(bytes[j + 1], 2).PadLeft(8, '0') : String.Empty, rem == 3 ? Convert.ToString(bytes[j + 2], 2).PadLeft(8, '0') : String.Empty, String.Empty); } } output.AppendFormat(footerFmt, String.Empty); return(output.ToString()); }