예제 #1
0
 public WsFrame(Fin fin, Opcode opcode, Mask mask, PayloadData payload)
     : this(fin, opcode, mask, payload, false)
 {
 }
 internal MessageEventArgs(Opcode opcode, PayloadData payload)
 {
     _opcode  = opcode;
     _rawData = payload.ApplicationData;
     _data    = convertToString(opcode, _rawData);
 }
예제 #3
0
 public WsFrame(Opcode opcode, Mask mask, PayloadData payload)
     : this(Fin.FINAL, opcode, mask, payload)
 {
 }
예제 #4
0
 public WsFrame(Opcode opcode, PayloadData payload)
     : this(opcode, Mask.MASK, payload)
 {
 }
예제 #5
0
 internal static WsFrame CreatePongFrame(Mask mask, PayloadData payload)
 {
     return(new WsFrame(Opcode.PONG, mask, payload));
 }
예제 #6
0
 internal static WsFrame CreateCloseFrame(Mask mask, PayloadData payload)
 {
     return(new WsFrame(Opcode.CLOSE, mask, payload));
 }
예제 #7
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);
        }