コード例 #1
0
ファイル: WebSocketFrame.cs プロジェクト: yilin101/jellyfin
        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;
        }
コード例 #2
0
ファイル: WebSocketFrame.cs プロジェクト: yilin101/jellyfin
        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);
        }