Beispiel #1
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 #2
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.INCORRECT_DATA, incorrect);
            }

            // Check if consistent frame.
            if (isControl(opcode) && payloadLen > 125)
            {
                throw new WebSocketException(
                          CloseStatusCode.INCONSISTENT_DATA,
                          "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.TOO_BIG, "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);
        }
Beispiel #3
0
        private static string dump(WsFrame frame)
        {
            var len   = frame.Length;
            var count = (long)(len / 4);
            var rem   = (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}+--------+--------+--------+--------+\n", spFmt);
            var footerFmt = String.Format("{0}+--------+--------+--------+--------+", spFmt);

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

            buffer.AppendFormat(headerFmt, String.Empty);

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

            for (i = 0; i <= count; i++)
            {
                j = i * 4;
                if (i < count)
                {
                    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);
                }
            }

            buffer.AppendFormat(footerFmt, String.Empty);
            return(buffer.ToString());
        }
Beispiel #4
0
 public bool WriteFrame(WsFrame frame)
 {
     return(Write(frame.ToByteArray()));
 }
Beispiel #5
0
 public void ReadFrameAsync(Action <WsFrame> completed, Action <Exception> error)
 {
     WsFrame.ParseAsync(_innerStream, true, completed, error);
 }
Beispiel #6
0
 public WsFrame ReadFrame()
 {
     return(WsFrame.Parse(_innerStream, true));
 }