コード例 #1
0
        private byte[] SerializeControlFrameHeaders(ProtocolHeaders frameHeaders)
        {
            var headers = new List <byte>(256);

            headers.AddRange(BinaryHelper.Int32ToBytes(frameHeaders.Count));
            foreach (KeyValuePair <string, string> pair in frameHeaders)
            {
                byte[] nameBin = Encoding.UTF8.GetBytes(pair.Key);

                headers.AddRange(BinaryHelper.Int32ToBytes(nameBin.Length));
                headers.AddRange(nameBin);

                byte[] valBin = Encoding.UTF8.GetBytes(pair.Value);
                headers.AddRange(BinaryHelper.Int32ToBytes(valBin.Length));

                headers.AddRange(valBin);
            }

            return(headers.ToArray());
        }
コード例 #2
0
 /// <summary>
 /// Parses HTTP header of Http2 data frame.
 /// </summary>
 /// <param name="frame">The frame.</param>
 /// <param name="data">The data.</param>
 private static void ParseDataFrameHeader(ref DataFrame frame, byte[] data)
 {
     frame.StreamId = BinaryHelper.Int32FromBytes(new ArraySegment <byte>(data, 0, 4), 0);
     frame.Flags    = data[4];
     frame.IsFinal  = (frame.Flags & 0x01) != 0;
 }
コード例 #3
0
        /// <summary>
        /// Deserializes the data into control frame.
        /// </summary>
        /// <param name="data">The data.</param>
        /// <returns>Deserialized frame.</returns>
        private BaseFrame DeserializeControlFrame(byte[] data)
        {
            FrameType    type  = GetFrameType(data);
            ControlFrame frame = new ControlFrame();

            switch (type)
            {
            case FrameType.RTS:
                frame.StreamId   = BinaryHelper.Int32FromBytes(new ArraySegment <byte>(data, 8, 4));
                frame.StatusCode = (StatusCode)BinaryHelper.Int32FromBytes(new ArraySegment <byte>(data, 12, 4));
                break;

            case FrameType.Headers:
            case FrameType.SynReply:
                ParseControlFrameHeader(ref frame, data);

                frame.StreamId = BinaryHelper.Int32FromBytes(new ArraySegment <byte>(data, 8, 4));

                ParseControlFrameHeaders(ref frame, data, 12);
                break;

            case FrameType.SynStream:
                ParseControlFrameHeader(ref frame, data);

                frame.StreamId             = BinaryHelper.Int32FromBytes(new ArraySegment <byte>(data, 8, 4));
                frame.AssociatedToStreamId = BinaryHelper.Int32FromBytes(new ArraySegment <byte>(data, 12, 4));
                frame.Priority             = (byte)(data[16] >> 5);
                frame.Slot = data[17];

                ParseControlFrameHeaders(ref frame, data, 18);
                break;

            case FrameType.Settings:
                int numberOfEntries = BinaryHelper.Int32FromBytes(new ArraySegment <byte>(data, 8, 4));
                frame = new SettingsFrame(numberOfEntries);
                int headersOffset = 12;

                for (int i = 0; i < numberOfEntries; i++)
                {
                    int key = BinaryHelper.Int32FromBytes(new ArraySegment <byte>(data, headersOffset, 4));
                    headersOffset += 4;
                    int value = BinaryHelper.Int32FromBytes(new ArraySegment <byte>(data, headersOffset, 4));
                    headersOffset += 4;

                    frame.SettingsHeaders.Add(key, value);
                }

                ParseControlFrameHeader(ref frame, data);
                break;

            case FrameType.GoAway:
                int        lastSeenGoodStreamId = BinaryHelper.Int32FromBytes(new ArraySegment <byte>(data, 8, 4));
                StatusCode status = StatusCode.Success;

                if (data.Length > 12)
                {
                    status = (StatusCode)BinaryHelper.Int32FromBytes(new ArraySegment <byte>(data, 12, 4));
                }

                frame = new GoAwayFrame(lastSeenGoodStreamId, status);
                ParseControlFrameHeader(ref frame, data);
                break;

            case FrameType.Ping:
                int streamID = BinaryHelper.Int32FromBytes(new ArraySegment <byte>(data, 4, 4));
                frame = new ControlFrame {
                    StreamId = streamID
                };

                ParseControlFrameHeader(ref frame, data);
                break;

            case FrameType.WindowUpdate:
                int streamId        = BinaryHelper.Int32FromBytes(new ArraySegment <byte>(data, 4, 4));
                int deltaWindowSize = BinaryHelper.Int32FromBytes(new ArraySegment <byte>(data, 8, 4));
                frame = new WindowUpdateFrame(streamId, deltaWindowSize);

                ParseControlFrameHeader(ref frame, data);
                break;
            }
            frame.Type = type;

            return(frame);
        }
コード例 #4
0
 private FrameType GetFrameType(byte[] data)
 {
     return((FrameType)BinaryHelper.Int16FromBytes(data[2], data[3]));
 }
コード例 #5
0
        /// <summary>
        /// Serializes the control frame.
        /// </summary>
        /// <param name="frame">The frame.</param>
        /// <returns>Serialized control frame.</returns>
        private byte[] SerializeControlFrame(ControlFrame frame)
        {
            var byteList = new List <byte>();

            byteList.Add((byte)(((frame.Version & 0xFF00) >> 8) | 0x80));
            byteList.Add((byte)(frame.Version & 0x00FF));

            byteList.Add((byte)(((Int16)frame.Type & 0xFF00) >> 8));
            byteList.Add((byte)((Int16)frame.Type & 0x00FF));

            var headersArray = new byte[0];

            switch (frame.Type)
            {
            case FrameType.SynStream:
                byteList.Add(Convert.ToByte(frame.Flags | (frame.IsFinal ? 0x01 : 0x00)));

                headersArray = SerializeControlFrameHeaders(frame.Headers);

                if (headersArray.Length > 0)
                {
                    ProcessorRun(ref headersArray, DirectionProcessType.Outbound, frame.Flags);
                }

                byteList.AddRange(BinaryHelper.Int32ToBytes(headersArray.Length + 10, 3));
                byteList.AddRange(BinaryHelper.Int32ToBytes(frame.StreamId));

                byteList.AddRange(BinaryHelper.Int32ToBytes(0));

                byteList.Add(Convert.ToByte(frame.Priority >> 5));

                byteList.Add(Unused);

                break;

            case FrameType.RTS:
                byteList.Add(0);
                byteList.AddRange(BinaryHelper.Int32ToBytes(headersArray.Length + 8, 3));
                byteList.AddRange(BinaryHelper.Int32ToBytes(frame.StreamId));
                byteList.AddRange(BinaryHelper.Int32ToBytes((int)frame.StatusCode));
                break;

            case FrameType.SynReply:
                byteList.Add(frame.Flags);
                headersArray = SerializeControlFrameHeaders(frame.Headers);

                if (headersArray.Length > 0)
                {
                    ProcessorRun(ref headersArray, DirectionProcessType.Outbound, frame.Flags);
                }

                byteList.AddRange(BinaryHelper.Int32ToBytes(headersArray.Length + 4, 3));
                byteList.AddRange(BinaryHelper.Int32ToBytes(frame.StreamId));
                break;

            case FrameType.GoAway:
                byteList.Add(frame.Flags);
                byteList.AddRange(BinaryHelper.Int32ToBytes(frame.Length, 3));
                byteList.AddRange(BinaryHelper.Int32ToBytes(frame.StreamId));
                byteList.AddRange(BinaryHelper.Int32ToBytes((int)frame.StatusCode));
                break;

            case FrameType.Ping:
                byteList.Add(frame.Flags);
                byteList.AddRange(BinaryHelper.Int32ToBytes(frame.Length, 3));
                byteList.AddRange(BinaryHelper.Int32ToBytes(frame.StreamId));
                break;

            case FrameType.WindowUpdate:
                byteList.Add(frame.Flags);
                byteList.AddRange(BinaryHelper.Int32ToBytes(frame.Length, 3));
                byteList.AddRange(BinaryHelper.Int32ToBytes(frame.StreamId));
                byteList.AddRange(BinaryHelper.Int64ToBytes(((WindowUpdateFrame)frame).DeltaWindowSize));
                break;

            case FrameType.Settings:
                byteList.Add(frame.Flags);
                byteList.AddRange(BinaryHelper.Int32ToBytes(frame.Length, 3));
                byteList.AddRange(BinaryHelper.Int32ToBytes(frame.NumberOfEntries));
                break;
            }


            byteList.AddRange(headersArray);
            return(byteList.ToArray());
        }