Beispiel #1
0
 public static void ParseAsync(Stream stream, Action <WsFrame> completed, Action <Exception> error)
 {
     WsFrame.ParseAsync(stream, true, completed, error);
 }
Beispiel #2
0
 public void Print(bool dumped)
 {
     Console.WriteLine((!dumped) ? WsFrame.print(this) : WsFrame.dump(this));
 }
Beispiel #3
0
 public static WsFrame Parse(Stream stream)
 {
     return(WsFrame.Parse(stream, true));
 }
Beispiel #4
0
 public static void ParseAsync(Stream stream, Action <WsFrame> completed)
 {
     WsFrame.ParseAsync(stream, true, completed, null);
 }
Beispiel #5
0
        private static WsFrame parse(byte[] header, Stream stream, bool unmask)
        {
            Fin    fin    = ((header[0] & 128) != 128) ? Fin.More : Fin.Final;
            Rsv    rsv    = ((header[0] & 64) != 64) ? Rsv.Off : Rsv.On;
            Rsv    rsv2   = ((header[0] & 32) != 32) ? Rsv.Off : Rsv.On;
            Rsv    rsv3   = ((header[0] & 16) != 16) ? Rsv.Off : Rsv.On;
            Opcode opcode = (Opcode)(header[0] & 15);
            Mask   mask   = ((header[1] & 128) != 128) ? Mask.Unmask : Mask.Mask;
            byte   b      = header[1] & 127;
            string text   = (!WsFrame.isControl(opcode) || fin != Fin.More) ? ((WsFrame.isData(opcode) || rsv != Rsv.On) ? null : "A non data frame is compressed.") : "A control frame is fragmented.";

            if (text != null)
            {
                throw new WebSocketException(CloseStatusCode.IncorrectData, text);
            }
            if (WsFrame.isControl(opcode) && b > 125)
            {
                throw new WebSocketException(CloseStatusCode.InconsistentData, "The payload data length of a control frame is greater than 125 bytes.");
            }
            WsFrame wsFrame = new WsFrame
            {
                Fin        = fin,
                Rsv1       = rsv,
                Rsv2       = rsv2,
                Rsv3       = rsv3,
                Opcode     = opcode,
                Mask       = mask,
                PayloadLen = b
            };
            int num = (b >= 126) ? ((b != 126) ? 8 : 2) : 0;

            byte[] array = (num <= 0) ? new byte[0] : stream.ReadBytes(num);
            if (num > 0 && array.Length != num)
            {
                throw new WebSocketException("The 'Extended Payload Length' of a frame cannot be read from the data source.");
            }
            wsFrame.ExtPayloadLen = array;
            bool flag = mask == Mask.Mask;

            byte[] array2 = (!flag) ? new byte[0] : stream.ReadBytes(4);
            if (flag && array2.Length != 4)
            {
                throw new WebSocketException("The 'Masking Key' of a frame cannot be read from the data source.");
            }
            wsFrame.MaskingKey = array2;
            ulong num2 = (b >= 126) ? ((b != 126) ? array.ToUInt64(ByteOrder.Big) : ((ulong)array.ToUInt16(ByteOrder.Big))) : ((ulong)b);

            byte[] array3;
            if (num2 > 0UL)
            {
                if (b > 126 && num2 > 9223372036854775807UL)
                {
                    throw new WebSocketException(CloseStatusCode.TooBig, "The 'Payload Data' length is greater than the allowable length.");
                }
                array3 = ((b <= 126) ? stream.ReadBytes((int)num2) : stream.ReadBytes((long)num2, 1024));
                if (array3.LongLength != (long)num2)
                {
                    throw new WebSocketException("The 'Payload Data' of a frame cannot be read from the data source.");
                }
            }
            else
            {
                array3 = new byte[0];
            }
            PayloadData payloadData = new PayloadData(array3, flag);

            if (flag && unmask)
            {
                payloadData.Mask(array2);
                wsFrame.Mask       = Mask.Unmask;
                wsFrame.MaskingKey = new byte[0];
            }
            wsFrame.PayloadData = payloadData;
            return(wsFrame);
        }
Beispiel #6
0
 public static WsFrame Parse(byte[] src)
 {
     return(WsFrame.Parse(src, true));
 }
Beispiel #7
0
 public void ReadFrameAsync(Action <WsFrame> completed)
 {
     WsFrame.ParseAsync(_innerStream, completed);
 }
Beispiel #8
0
        private static WsFrame parse(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 len
            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 payload data length of a control frame is greater than 125 bytes.");
            }

            var frame = new WsFrame {
                Fin        = fin,
                Rsv1       = rsv1,
                Rsv2       = rsv2,
                Rsv3       = rsv3,
                Opcode     = opcode,
                Mask       = mask,
                PayloadLen = payloadLen
            };

            /* Extended Payload Length */

            var extLen = payloadLen < 126
                 ? 0
                 : payloadLen == 126
                   ? 2
                   : 8;

            var extPayloadLen = extLen > 0
                        ? stream.ReadBytes(extLen)
                        : new byte [] {};

            if (extLen > 0 && extPayloadLen.Length != extLen)
            {
                throw new WebSocketException(
                          "The 'Extended Payload Length' of a frame cannot be read from the data source.");
            }

            frame.ExtPayloadLen = extPayloadLen;

            /* Masking Key */

            var masked     = mask == Mask.Mask;
            var maskingKey = masked
                     ? stream.ReadBytes(4)
                     : new 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 dataLen = payloadLen < 126
                    ? payloadLen
                    : payloadLen == 126
                      ? extPayloadLen.ToUInt16(ByteOrder.Big)
                      : extPayloadLen.ToUInt64(ByteOrder.Big);

            byte [] data = null;
            if (dataLen > 0)
            {
                // Check if allowable payload data length.
                if (payloadLen > 126 && dataLen > PayloadData.MaxLength)
                {
                    throw new WebSocketException(
                              CloseStatusCode.TooBig, "The 'Payload Data' length is greater than the allowable length.");
                }

                data = payloadLen > 126
             ? stream.ReadBytes((long)dataLen, 1024)
             : stream.ReadBytes((int)dataLen);

                if (data.LongLength != (long)dataLen)
                {
                    throw new WebSocketException(
                              "The 'Payload Data' of a frame cannot be read from the data source.");
                }
            }
            else
            {
                data = new byte [] {};
            }

            var payload = new PayloadData(data, masked);

            if (masked && unmask)
            {
                payload.Mask(maskingKey);
                frame.Mask       = Mask.Unmask;
                frame.MaskingKey = new byte [] {};
            }

            frame.PayloadData = payload;
            return(frame);
        }
 public void ReadFrameAsync(
     Action <WsFrame> completed, Action <Exception> error)
 {
     WsFrame.ParseAsync(_innerStream, true, completed, error);
 }
 public bool WriteFrame(WsFrame frame)
 {
     return(write(frame.ToByteArray()));
 }
 public WsFrame ReadFrame()
 {
     return(WsFrame.Parse(_innerStream, true));
 }
Beispiel #12
0
        private static void dump(WsFrame frame)
        {
            var len       = frame.Length;
            var count     = (long)(len / 4);
            var remainder = (int)(len % 4);

            int    countDigit;
            string countFmt;

            if (count < 10000)
            {
                countDigit = 4;
                countFmt   = "{0,4}";
            }
            else if (count < 0x010000)
            {
                countDigit = 4;
                countFmt   = "{0,4:X}";
            }
            else if (count < 0x0100000000)
            {
                countDigit = 8;
                countFmt   = "{0,8:X}";
            }
            else
            {
                countDigit = 16;
                countFmt   = "{0,16:X}";
            }

            var spFmt     = String.Format("{{0,{0}}}", countDigit);
            var headerFmt = String.Format(@"
 {0} 01234567 89ABCDEF 01234567 89ABCDEF
 {0}+--------+--------+--------+--------+", spFmt);
            var footerFmt = String.Format(" {0}+--------+--------+--------+--------+", spFmt);

            Func <Action <string, string, string, string> > linePrinter = () =>
            {
                long lineCount = 0;
                var  lineFmt   = String.Format(" {0}|{{1,8}} {{2,8}} {{3,8}} {{4,8}}|", countFmt);
                return((arg1, arg2, arg3, arg4) =>
                {
                    Console.WriteLine(lineFmt, ++lineCount, arg1, arg2, arg3, arg4);
                });
            };
            var printLine = linePrinter();

            Console.WriteLine(headerFmt, String.Empty);

            var buffer = frame.ToByteArray();
            int i, j;

            for (i = 0; i <= count; i++)
            {
                j = i * 4;
                if (i < count)
                {
                    printLine(
                        Convert.ToString(buffer[j], 2).PadLeft(8, '0'),
                        Convert.ToString(buffer[j + 1], 2).PadLeft(8, '0'),
                        Convert.ToString(buffer[j + 2], 2).PadLeft(8, '0'),
                        Convert.ToString(buffer[j + 3], 2).PadLeft(8, '0'));
                }
                else if (remainder > 0)
                {
                    printLine(
                        Convert.ToString(buffer[j], 2).PadLeft(8, '0'),
                        remainder >= 2 ? Convert.ToString(buffer[j + 1], 2).PadLeft(8, '0') : String.Empty,
                        remainder == 3 ? Convert.ToString(buffer[j + 2], 2).PadLeft(8, '0') : String.Empty,
                        String.Empty);
                }
            }

            Console.WriteLine(footerFmt, String.Empty);
        }
Beispiel #13
0
        private static string print(WsFrame frame)
        {
            /* Opcode */

            var opcode = frame.Opcode.ToString();

            /* Payload Len */

            var payloadLen = frame.PayloadLen;

            /* Extended Payload Len */

            var ext    = frame.ExtPayloadLen;
            var size   = ext.Length;
            var extLen = size == 2
                 ? ext.ToUInt16(ByteOrder.Big).ToString()
                 : size == 8
                   ? ext.ToUInt64(ByteOrder.Big).ToString()
                   : String.Empty;

            /* Masking Key */

            var masked = frame.IsMasked;
            var key    = masked
              ? BitConverter.ToString(frame.MaskingKey)
              : String.Empty;

            /* Payload Data */

            var data = payloadLen == 0
               ? String.Empty
               : size > 0
                 ? String.Format("A {0} data with {1} bytes.", opcode.ToLower(), extLen)
                 : masked || frame.IsFragmented || frame.IsBinary || frame.IsClose
                   ? BitConverter.ToString(frame.PayloadData.ToByteArray())
                   : Encoding.UTF8.GetString(frame.PayloadData.ApplicationData);

            var format =
                @"                 FIN: {0}
                RSV1: {1}
                RSV2: {2}
                RSV3: {3}
              Opcode: {4}
                MASK: {5}
         Payload Len: {6}
Extended Payload Len: {7}
         Masking Key: {8}
        Payload Data: {9}";

            return(String.Format(
                       format,
                       frame.Fin,
                       frame.Rsv1,
                       frame.Rsv2,
                       frame.Rsv3,
                       opcode,
                       frame.Mask,
                       payloadLen,
                       extLen,
                       key,
                       data));
        }
Beispiel #14
0
 public string PrintToString(bool dumped)
 {
     return((!dumped) ? WsFrame.print(this) : WsFrame.dump(this));
 }
Beispiel #15
0
        private static string dump(WsFrame frame)
        {
            ulong  length = frame.Length;
            long   num    = (long)(length / 4UL);
            int    num2   = (int)(length % 4UL);
            string countFmt;
            int    num3;

            if (num < 10000L)
            {
                num3     = 4;
                countFmt = "{0,4}";
            }
            else if (num < 65536L)
            {
                num3     = 4;
                countFmt = "{0,4:X}";
            }
            else if (num < 4294967296L)
            {
                num3     = 8;
                countFmt = "{0,8:X}";
            }
            else
            {
                num3     = 16;
                countFmt = "{0,16:X}";
            }
            string        arg     = string.Format("{{0,{0}}}", num3);
            string        format  = string.Format("{0} 01234567 89ABCDEF 01234567 89ABCDEF\n{0}+--------+--------+--------+--------+\\n", arg);
            string        format2 = string.Format("{0}+--------+--------+--------+--------+", arg);
            StringBuilder buffer  = new StringBuilder(64);
            Func <Action <string, string, string, string> > func = delegate()
            {
                long   lineCount = 0L;
                string lineFmt   = string.Format("{0}|{{1,8}} {{2,8}} {{3,8}} {{4,8}}|\n", countFmt);
                return(delegate(string arg1, string arg2, string arg3, string arg4)
                {
                    buffer.AppendFormat(lineFmt, new object[]
                    {
                        lineCount += 1L,
                        arg1,
                        arg2,
                        arg3,
                        arg4
                    });
                });
            };
            Action <string, string, string, string> action = func();

            buffer.AppendFormat(format, string.Empty);
            byte[] array = frame.ToByteArray();
            int    num4  = 0;

            while ((long)num4 <= num)
            {
                int num5 = num4 * 4;
                if ((long)num4 < num)
                {
                    action(Convert.ToString(array[num5], 2).PadLeft(8, '0'), Convert.ToString(array[num5 + 1], 2).PadLeft(8, '0'), Convert.ToString(array[num5 + 2], 2).PadLeft(8, '0'), Convert.ToString(array[num5 + 3], 2).PadLeft(8, '0'));
                }
                else if (num2 > 0)
                {
                    action(Convert.ToString(array[num5], 2).PadLeft(8, '0'), (num2 < 2) ? string.Empty : Convert.ToString(array[num5 + 1], 2).PadLeft(8, '0'), (num2 != 3) ? string.Empty : Convert.ToString(array[num5 + 2], 2).PadLeft(8, '0'), string.Empty);
                }
                num4++;
            }
            buffer.AppendFormat(format2, string.Empty);
            return(buffer.ToString());
        }
Beispiel #16
0
        private byte[] receiveFragmented(WsFrame firstFrame)
        {
            var buffer = new List <byte>(firstFrame.PayloadData.ToBytes());

            while (true)
            {
                var frame = readFrame();
                if (frame.IsNull())
                {
                    return(null);
                }

                if (frame.Fin == Fin.MORE)
                {
                    if (frame.Opcode == Opcode.CONT)
                    {// MORE & CONT
                        buffer.AddRange(frame.PayloadData.ToBytes());
                        continue;
                    }

          #if DEBUG
                    Console.WriteLine("WS: Info@receiveFragmented: Starts closing handshake.");
          #endif
                    close(CloseStatusCode.INCORRECT_DATA, String.Empty);
                    return(null);
                }

                if (frame.Opcode == Opcode.CONT)
                {// FINAL & CONT
                    buffer.AddRange(frame.PayloadData.ToBytes());
                    break;
                }

                if (frame.Opcode == Opcode.CLOSE)
                {// FINAL & CLOSE
          #if DEBUG
                    Console.WriteLine("WS: Info@receiveFragmented: Starts closing handshake.");
          #endif
                    close(frame.PayloadData);
                    return(null);
                }

                if (frame.Opcode == Opcode.PING)
                {// FINAL & PING
          #if DEBUG
                    Console.WriteLine("WS: Info@receiveFragmented: Returns Pong.");
          #endif
                    pong(frame.PayloadData);
                    continue;
                }

                if (frame.Opcode == Opcode.PONG)
                {// FINAL & PONG
          #if DEBUG
                    Console.WriteLine("WS: Info@receiveFragmented: Receives Pong.");
          #endif
                    _receivePong.Set();
                    continue;
                }

                // FINAL & (TEXT | BINARY)
        #if DEBUG
                Console.WriteLine("WS: Info@receiveFragmented: Starts closing handshake.");
        #endif
                close(CloseStatusCode.INCORRECT_DATA, String.Empty);
                return(null);
            }

            return(buffer.ToArray());
        }
Beispiel #17
0
        private static WsFrame parse(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 len
            var payloadLen = (byte)(header[1] & 0x7f);

            if (isControl(opcode) && payloadLen > 125)
            {
                return(createCloseFrame(CloseStatusCode.INCONSISTENT_DATA,
                                        "The payload length of a control frame must be 125 bytes or less."));
            }

            var frame = new WsFrame {
                Fin        = fin,
                Rsv1       = rsv1,
                Rsv2       = rsv2,
                Rsv3       = rsv3,
                Opcode     = opcode,
                Mask       = mask,
                PayloadLen = payloadLen
            };

            /* Extended Payload Length */

            var extLen = payloadLen < 126
                 ? 0
                 : payloadLen == 126
                   ? 2
                   : 8;

            var extPayloadLen = extLen > 0
                        ? stream.ReadBytesInternal(extLen)
                        : new byte[] {};

            if (extLen > 0 && extPayloadLen.Length != extLen)
            {
                return(createCloseFrame(CloseStatusCode.ABNORMAL,
                                        "'Extended Payload Length' of a frame cannot be read from the data stream."));
            }

            frame.ExtPayloadLen = extPayloadLen;

            /* Masking Key */

            var masked     = mask == Mask.MASK ? true : false;
            var maskingKey = masked
                     ? stream.ReadBytesInternal(4)
                     : new byte[] {};

            if (masked && maskingKey.Length != 4)
            {
                return(createCloseFrame(CloseStatusCode.ABNORMAL,
                                        "'Masking Key' of a frame cannot be read from the data stream."));
            }

            frame.MaskingKey = maskingKey;

            /* Payload Data */

            ulong dataLen = payloadLen < 126
                    ? payloadLen
                    : payloadLen == 126
                      ? extPayloadLen.To <ushort>(ByteOrder.BIG)
                      : extPayloadLen.To <ulong>(ByteOrder.BIG);

            byte[] data = null;
            if (dataLen > 0)
            {
                if (payloadLen > 126 && dataLen > PayloadData.MaxLength)
                {
                    var code = CloseStatusCode.TOO_BIG;
                    return(createCloseFrame(code, code.GetMessage()));
                }

                data = dataLen > 1024
             ? stream.ReadBytesInternal((long)dataLen, 1024)
             : stream.ReadBytesInternal((int)dataLen);

                if (data.LongLength != (long)dataLen)
                {
                    return(createCloseFrame(CloseStatusCode.ABNORMAL,
                                            "'Payload Data' of a frame cannot be read from the data stream."));
                }
            }
            else
            {
                data = new byte[] {};
            }

            var payloadData = new PayloadData(data, masked);

            if (masked && unmask)
            {
                payloadData.Mask(maskingKey);
                frame.Mask       = Mask.UNMASK;
                frame.MaskingKey = new byte[] {};
            }

            frame.PayloadData = payloadData;
            return(frame);
        }