private static WebSocketFrame processHeader(byte[] header)
        {
            if (header.Length != 2)
            {
                var msg = "The header part of a frame could not be read.";
                throw new WebSocketException(msg);
            }

            // 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 = (byte)(header[0] & 0x0f);

            // MASK
            var mask = (header[1] & 0x80) == 0x80 ? Mask.On : Mask.Off;

            // Payload Length
            var payloadLen = (byte)(header[1] & 0x7f);

            if (!opcode.IsSupported())
            {
                var msg = "A frame has an unsupported opcode.";
                throw new WebSocketException(CloseStatusCode.ProtocolError, msg);
            }

            if (!opcode.IsData() && rsv1 == Rsv.On)
            {
                var msg = "A non data frame is compressed.";
                throw new WebSocketException(CloseStatusCode.ProtocolError, msg);
            }

            if (opcode.IsControl())
            {
                if (fin == Fin.More)
                {
                    var msg = "A control frame is fragmented.";
                    throw new WebSocketException(CloseStatusCode.ProtocolError, msg);
                }

                if (payloadLen > 125)
                {
                    var msg = "A control frame has too long payload length.";
                    throw new WebSocketException(CloseStatusCode.ProtocolError, msg);
                }
            }

            var frame = new WebSocketFrame();

            frame._fin           = fin;
            frame._rsv1          = rsv1;
            frame._rsv2          = rsv2;
            frame._rsv3          = rsv3;
            frame._opcode        = (Opcode)opcode;
            frame._mask          = mask;
            frame._payloadLength = payloadLen;

            return(frame);
        }
Exemple #2
0
 internal MessageEventArgs(WebSocketFrame frame)
 {
     _opcode  = frame.Opcode;
     _rawData = frame.PayloadData.ApplicationData;
 }
        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 buff = new StringBuilder(64);

            Func <Action <string, string, string, string> > linePrinter =
                () => {
                long lineCnt = 0;
                return((arg1, arg2, arg3, arg4) => {
                    buff.AppendFormat(
                        lineFmt, ++lineCnt, arg1, arg2, arg3, arg4
                        );
                });
            };

            var printLine = linePrinter();
            var bytes     = frame.ToArray();

            buff.AppendFormat(headerFmt, String.Empty);

            for (long i = 0; i <= cnt; i++)
            {
                var j = i * 4;

                if (i < cnt)
                {
                    printLine(
                        Convert.ToString(bytes[j], 2).PadLeft(8, '0'),
                        Convert.ToString(bytes[j + 1], 2).PadLeft(8, '0'),
                        Convert.ToString(bytes[j + 2], 2).PadLeft(8, '0'),
                        Convert.ToString(bytes[j + 3], 2).PadLeft(8, '0')
                        );

                    continue;
                }

                if (rem > 0)
                {
                    printLine(
                        Convert.ToString(bytes[j], 2).PadLeft(8, '0'),
                        rem >= 2
            ? Convert.ToString(bytes[j + 1], 2).PadLeft(8, '0')
            : String.Empty,
                        rem == 3
            ? Convert.ToString(bytes[j + 2], 2).PadLeft(8, '0')
            : String.Empty,
                        String.Empty
                        );
                }
            }

            buff.AppendFormat(footerFmt, String.Empty);
            return(buff.ToString());
        }