Beispiel #1
0
        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);
            }
        }
Beispiel #2
0
        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);
            }
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        private bool processUnsupportedFrame(WebSocketFrame frame, CloseStatusCode code, string reason)
        {
            processException(new WebSocketException(code, reason), null);

            return(false);
        }
Beispiel #5
0
        private bool processPongFrame(WebSocketFrame frame)
        {
            _receivePong.Set();

            return(true);
        }
Beispiel #6
0
        private bool processPingFrame(WebSocketFrame frame)
        {
            var mask = Mask.Unmask;

            return(true);
        }
Beispiel #7
0
 private bool processFragmentedFrame(WebSocketFrame frame)
 {
     return(frame.IsContinuation // Not first fragment
            ? true
            : processFragments(frame));
 }
Beispiel #8
0
 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());
        }
Beispiel #10
0
        private async Task <bool> ProcessUnsupportedFrameAsync(WebSocketFrame frame, CloseStatusCode code, string reason)
        {
            await ProcessExceptionAsync(new WebSocketException(code, reason), null).ConfigureAwait(false);

            return(false);
        }
Beispiel #11
0
 private Task <bool> ProcessFragmentedFrameAsync(WebSocketFrame frame)
 {
     return(frame.IsContinuation // Not first fragment
            ? Task.FromResult(true)
            : ProcessFragmentsAsync(frame));
 }