예제 #1
0
        private async Task <StreamReadInfo> GetStreamReadInfo(WebSocketFrameHeader header, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            /* Extended Payload Length */

            var size = header.PayloadLength < 126 ? 0 : header.PayloadLength == 126 ? 2 : 8;

            var extPayloadLen = size > 0 ? await _innerStream.ReadBytes(size).ConfigureAwait(false) : 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.");
            }

            /* Masking Key */

            var masked     = header.Mask == Mask.Mask;
            var maskingKey = masked ? await _innerStream.ReadBytes(4).ConfigureAwait(false) : new byte[0];

            if (masked && maskingKey.Length != 4)
            {
                throw new WebSocketException("The 'Masking Key' of a frame cannot be read from the data source.");
            }

            /* Payload Data */

            var len = header.PayloadLength < 126
                            ? header.PayloadLength
                            : header.PayloadLength == 126
                                  ? extPayloadLen.ToUInt16(ByteOrder.Big)
                                  : extPayloadLen.ToUInt64(ByteOrder.Big);

            return(new StreamReadInfo(header.Fin == Fin.Final, len, maskingKey));
        }
예제 #2
0
        private async Task <WebSocketFrameHeader> ReadHeader(CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            byte[] header;

            try
            {
                header = await _innerStream.ReadBytes(2).ConfigureAwait(false);
            }
            catch (IOException)
            {
                return(null);
            }

            if (header.Length == 0)
            {
                return(null);
            }

            if (header.Length != 2)
            {
                throw new WebSocketException("The header part of a frame cannot be read from the data source.");
            }

            var frameHeader = new WebSocketFrameHeader(header);
            var validation  = WebSocketFrameHeader.Validate(frameHeader);

            if (validation != null)
            {
                throw new WebSocketException(CloseStatusCode.ProtocolError, validation);
            }

            return(frameHeader);
        }
예제 #3
0
        private WebSocketMessage CreateMessage(WebSocketFrameHeader header, StreamReadInfo readInfo, SemaphoreSlim waitHandle)
        {
            switch (header.Opcode)
            {
            case Opcode.Cont:
                throw new WebSocketException(CloseStatusCode.InconsistentData, "Did not expect continuation frame.");

            default:
            case Opcode.Close:
            case Opcode.Text:
            case Opcode.Binary:
                return(new FragmentedMessage(header.Opcode, _innerStream, readInfo, GetStreamReadInfo, waitHandle, _fragmentLength));
            }
        }
        public static string Validate(WebSocketFrameHeader header)
        {
            // Check if valid header
            var err = IsControl(header.Opcode) && header.PayloadLength > 125
                                          ? "A control frame has a payload data which is greater than the allowable max size."
                                          : IsControl(header.Opcode) && header.Fin == Fin.More
                                                ? "A control frame is fragmented."
                                                : !IsData(header.Opcode) && header.Rsv1 == Rsv.On
                                                  ? "A non data frame (" + header.Opcode + ") is compressed."
                                                  : null;

            if (!string.IsNullOrWhiteSpace(err))
            {
                Trace.TraceError(err);
            }

            return(err);
        }