private bool processFragments(WebSocketFrame first) { using (var buff = _memoryStreamFactory.CreateNew()) { buff.WriteBytes(first.PayloadData.ApplicationData); if (!concatenateFragmentsInto(buff)) { return(false); } byte[] data; if (_compression != CompressionMethod.None) { data = buff.DecompressToArray(_compression); } else { data = buff.ToArray(); } enqueueToMessageEventQueue(new MessageEventArgs(first.Opcode, data)); return(true); } }
private async Task <bool> ProcessFragmentsAsync(WebSocketFrame first) { using (var buff = new MemoryStream()) { buff.WriteBytes(first.PayloadData.ApplicationData); if (!await ConcatenateFragmentsIntoAsync(buff).ConfigureAwait(false)) { return(false); } byte[] data; if (_compression != CompressionMethod.None) { data = buff.DecompressToArray(_compression); } else { data = buff.ToArray(); } enqueueToMessageEventQueue(new MessageEventArgs(first.Opcode, data)); return(true); } }
private static async Task <WebSocketFrame> ReadAsync(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 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.IncorrectData, incorrect); } // Check if consistent frame. if (isControl(opcode) && payloadLen > 125) { throw new WebSocketException( CloseStatusCode.InconsistentData, "The length of payload data of a control frame is greater than 125 bytes."); } 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 ? await stream.ReadBytesAsync(size).ConfigureAwait(false) : Array.Empty <byte>(); 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 ? await stream.ReadBytesAsync(4).ConfigureAwait(false) : Array.Empty <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 len = payloadLen < 126 ? payloadLen : payloadLen == 126 ? extPayloadLen.ToUInt16(ByteOrder.Big) : extPayloadLen.ToUInt64(ByteOrder.Big); byte[] data = null; if (len > 0) { // Check if allowable payload data 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 length."); } data = payloadLen > 126 ? await stream.ReadBytesAsync((long)len, 1024).ConfigureAwait(false) : await stream.ReadBytesAsync((int)len).ConfigureAwait(false); //if (data.LongLength != (long)len) // throw new WebSocketException( // "The 'Payload Data' of a frame cannot be read from the data source."); } else { data = Array.Empty <byte>(); } var payload = new PayloadData(data, masked); if (masked && unmask) { payload.Mask(maskingKey); frame._mask = Mask.Unmask; frame._maskingKey = Array.Empty <byte>(); } frame._payloadData = payload; return(frame); }
private bool processUnsupportedFrame(WebSocketFrame frame, CloseStatusCode code, string reason) { processException(new WebSocketException(code, reason), null); return(false); }
private bool processPongFrame(WebSocketFrame frame) { _receivePong.Set(); return(true); }
private bool processPingFrame(WebSocketFrame frame) { var mask = Mask.Unmask; return(true); }
private bool processFragmentedFrame(WebSocketFrame frame) { return(frame.IsContinuation // Not first fragment ? true : processFragments(frame)); }
private bool processPingFrame(WebSocketFrame frame) { return(true); }
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 frameAsBytes = frame.ToByteArray(); for (long i = 0; i <= cnt; i++) { 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')); } 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); } } output.AppendFormat(footerFmt, String.Empty); return(output.ToString()); }
private async Task <bool> ProcessUnsupportedFrameAsync(WebSocketFrame frame, CloseStatusCode code, string reason) { await ProcessExceptionAsync(new WebSocketException(code, reason), null).ConfigureAwait(false); return(false); }
private Task <bool> ProcessFragmentedFrameAsync(WebSocketFrame frame) { return(frame.IsContinuation // Not first fragment ? Task.FromResult(true) : ProcessFragmentsAsync(frame)); }