public static string GetText(this IWebSocketPayload payload)
        {
            if (payload == null || !payload.IsText)
            {
                return(null);
            }

            return(payload.Data == null
                ? string.Empty
                : Encoding.UTF8.GetString(payload.Data, payload.Offset, payload.Length));
        }
Exemple #2
0
        public async Task ReadFromAsync(IDataLayer layer, CancellationToken cancellationToken)
        {
            var headerBytes = await layer.ReadAsync(2, cancellationToken);

            this.IsFin  = (headerBytes[0] & 0x80) == 0x80;
            this.IsRsv1 = (headerBytes[0] & 0x40) == 0x40;
            this.IsRsv2 = (headerBytes[0] & 0x20) == 0x20;
            this.IsRsv3 = (headerBytes[0] & 0x10) == 0x10;
            this.Opcode = (WebSocketOpcode)(headerBytes[0] & 0x0f);

            if (this.IsControlFrame && !this.IsFin)
            {
                throw new WebSocketException(WebSocketErrorCode.CloseInvalidData, ErrorMessages.FragmentedControlFrame);
            }

            if (!this.IsDataFrame && this.IsRsv1)
            {
                throw new WebSocketException(WebSocketErrorCode.CloseInvalidData, ErrorMessages.CompressedNonDataFrame);
            }

            this.IsMasked = (headerBytes[1] & 0x80) == 0x80;

            if (this.IsMasked)
            {
                this.MaskingKey = await layer.ReadAsync(4, cancellationToken);
            }
            else
            {
                this.MaskingKey = null;
            }

            ulong payloadLength = (byte)(headerBytes[1] & 0x7f);

            if (this.IsControlFrame && payloadLength > 125)
            {
                throw new WebSocketException(WebSocketErrorCode.CloseInconstistentData, ErrorMessages.PayloadLengthControlFrame);
            }


            var extendedPayloadLengthSize = payloadLength < 126 ? 0 : payloadLength < 127 ? 2 : 8;

            if (extendedPayloadLengthSize > 0)
            {
                var extendedPayloadLength = await layer.ReadAsync(extendedPayloadLengthSize, cancellationToken);

                payloadLength = extendedPayloadLengthSize == 2
                    ? extendedPayloadLength.ToUInt16(ByteOrder.BigEndian)
                    : extendedPayloadLength.ToUInt64(ByteOrder.BigEndian);

                if (payloadLength > int.MaxValue)
                {
                    throw new WebSocketException(WebSocketErrorCode.CloseMessageTooBig);
                }
            }

            if (payloadLength > 0)
            {
                this.Payload = new WebSocketPayload(this, await layer.ReadAsync((int)payloadLength, cancellationToken));
                if (this.IsMasked)
                {
                    this.MaskPayload(
                        this.Payload.Data, this.Payload.Offset, this.Payload.Length,
                        this.Payload.Data, this.Payload.Offset);
                }
            }
            else
            {
                this.Payload = null;
            }
        }
        public async Task ReadFromAsync(IDataLayer layer, CancellationToken cancellationToken)
        {
            var headerBytes = await layer.ReadAsync(2, cancellationToken);
            this.IsFin = (headerBytes[0] & 0x80) == 0x80;
            this.IsRsv1 = (headerBytes[0] & 0x40) == 0x40;
            this.IsRsv2 = (headerBytes[0] & 0x20) == 0x20;
            this.IsRsv3 = (headerBytes[0] & 0x10) == 0x10;
            this.Opcode = (WebSocketOpcode)(headerBytes[0] & 0x0f);

            if (this.IsControlFrame && !this.IsFin)
                throw new WebSocketException(WebSocketErrorCode.CloseInvalidData, ErrorMessages.FragmentedControlFrame);

            if (!this.IsDataFrame && this.IsRsv1)
                throw new WebSocketException(WebSocketErrorCode.CloseInvalidData, ErrorMessages.CompressedNonDataFrame);

            this.IsMasked = (headerBytes[1] & 0x80) == 0x80;
            
            if (this.IsMasked)
                this.MaskingKey = await layer.ReadAsync(4, cancellationToken);
            else
                this.MaskingKey = null;

            ulong payloadLength = (byte)(headerBytes[1] & 0x7f);
            if (this.IsControlFrame && payloadLength > 125)
                throw new WebSocketException(WebSocketErrorCode.CloseInconstistentData, ErrorMessages.PayloadLengthControlFrame);

            
            var extendedPayloadLengthSize = payloadLength < 126 ? 0 : payloadLength < 127 ? 2 : 8;
            if (extendedPayloadLengthSize > 0)
            {
                var extendedPayloadLength = await layer.ReadAsync(extendedPayloadLengthSize, cancellationToken);
                payloadLength = extendedPayloadLengthSize == 2
                    ? extendedPayloadLength.ToUInt16(ByteOrder.BigEndian)
                    : extendedPayloadLength.ToUInt64(ByteOrder.BigEndian);

                if (payloadLength > int.MaxValue)
                    throw new WebSocketException(WebSocketErrorCode.CloseMessageTooBig);
            }

            if (payloadLength > 0)
            {
                this.Payload = new WebSocketPayload(this, await layer.ReadAsync((int)payloadLength, cancellationToken));
                if (this.IsMasked)
                {
                    this.MaskPayload(
                        this.Payload.Data, this.Payload.Offset, this.Payload.Length,
                        this.Payload.Data, this.Payload.Offset);
                }
            }
            else
            {
                this.Payload = null;
            }
        }