internal WebSocketFrame( Fin fin, Opcode opcode, Mask mask, PayloadData payload, bool compressed) { _fin = fin; _rsv1 = isData(opcode) && compressed ? Rsv.On : Rsv.Off; _rsv2 = Rsv.Off; _rsv3 = Rsv.Off; _opcode = opcode; _mask = mask; var len = payload.Length; if (len < 126) { _payloadLength = (byte)len; _extPayloadLength = new byte[0]; } else if (len < 0x010000) { _payloadLength = (byte)126; _extPayloadLength = ((ushort)len).ToByteArrayInternally(ByteOrder.Big); } else { _payloadLength = (byte)127; _extPayloadLength = len.ToByteArrayInternally(ByteOrder.Big); } if (mask == Mask.Mask) { _maskingKey = createMaskingKey(); payload.Mask(_maskingKey); } else { _maskingKey = new byte[0]; } _payloadData = payload; }
internal WebSocketFrame(Fin fin, Opcode opcode, Mask mask, PayloadData payload) : this(fin, opcode, mask, payload, false) { }
internal WebSocketFrame(Opcode opcode, Mask mask, PayloadData payload) : this(Fin.Final, opcode, mask, payload, false) { }
internal static WebSocketFrame CreatePongFrame(Mask mask, PayloadData payload) { return(new WebSocketFrame(Opcode.Pong, mask, payload)); }
internal static WebSocketFrame CreateCloseFrame(Mask mask, PayloadData payload) { return(new WebSocketFrame(Opcode.Close, mask, payload)); }
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); }
internal MessageEventArgs(Opcode opcode, PayloadData payload) { _opcode = opcode; _rawData = payload.ApplicationData; _data = convertToString(opcode, _rawData); }