Ejemplo n.º 1
0
        private PriorityFrame DecodePriorityFrame(DecodingContext context, int payloadLength, byte flags,
                                                  int streamIdentifier)
        {
            if (streamIdentifier == 0)
            {
                throw new DecoderException(Http2ErrorCode.ProtocolError, "PRIORITY frames require a stream identifier.");
            }
            if (payloadLength != 5)
            {
                throw new DecoderException(Http2ErrorCode.FrameSizeError, "PRIORITY frame payload should be 5 bytes.");
            }


            var exlusive   = (context.Buffer[context.Offset] & Bit32) == Bit32;
            var dependency = BitConverter.ToInt32(context.Buffer, context.Offset) & ~Bit32;
            var weight     = context.Buffer[context.Offset + 4];

            context.Offset             += 5;
            context.BytesLeftToProcess -= 5;

            var frame = new PriorityFrame
            {
                DependencyStreamId = dependency,
                Weight             = weight,
                IsExclusive        = exlusive,
                StreamIdentifier   = streamIdentifier,
                FrameFlags         = flags
            };

            return(frame);
        }
Ejemplo n.º 2
0
        private void HandlePriority(PriorityFrame priorityFrame, out Http2Stream stream)
        {
            Http2Logger.LogDebug("PRIORITY frame: stream id={0}, exclusive={1}, dependency={2}, weight={3}",
                                 priorityFrame.StreamId, priorityFrame.Exclusive, priorityFrame.StreamDependency,
                                 priorityFrame.Weight);

            /* 12 -> 6.3
             * The PRIORITY frame is associated with an existing stream. If a
             * PRIORITY frame is received with a stream identifier of 0x0, the
             * recipient MUST respond with a connection error of type PROTOCOL_ERROR. */
            if (priorityFrame.StreamId == 0)
            {
                throw new ProtocolError(ResetStatusCode.ProtocolError, "Incoming priority frame with stream id=0");
            }

            stream = GetStream(priorityFrame.StreamId);

            /* 12 -> 6.3
             * The PRIORITY frame can be sent on a stream in any of the "reserved
             * (remote)", "open", "half-closed (local)", or "half closed (remote)"
             * states, though it cannot be sent between consecutive frames that
             * comprise a single header block. */

            if (stream.Closed)
            {
                throw new Http2StreamNotFoundException(priorityFrame.StreamId);
            }

            if (!(stream.Opened || stream.ReservedRemote || stream.HalfClosedLocal))
            {
                throw new ProtocolError(ResetStatusCode.ProtocolError, "priority for non opened or reserved stream");
            }

            if (!_usePriorities)
            {
                return;
            }

            stream.Priority = priorityFrame.Weight;
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Process a priority frame request.
        /// </summary>
        /// <param name="httpContext">The current http context.</param>
        /// <param name="priorityFrame">The priority frame.</param>
        /// <param name="stream">The selected stream context.</param>
        private static void ProcessPriorityFrameRequest(Nequeo.Net.Http2.HttpContext httpContext, PriorityFrame priorityFrame, out ContextStream stream)
        {
            /*  The PRIORITY frame is associated with an existing stream. If a
             *  PRIORITY frame is received with a stream identifier of 0x0, the
             *  recipient MUST respond with a connection error of type PROTOCOL_ERROR. */
            if (priorityFrame.StreamId == 0)
            {
                throw new ProtocolError(ErrorCodeRegistry.Protocol_Error, "Incoming priority frame with stream id equal to 0.");
            }

            // Attempt to get the sepcific stream.
            stream = httpContext.GetStream(priorityFrame.StreamId);
            if (stream == null)
            {
                throw new MaxConcurrentStreamsLimitException();
            }

            /*  The PRIORITY frame can be sent on a stream in any of the "reserved
             *  (remote)", "open", "half-closed (local)", or "half closed (remote)"
             *  states, though it cannot be sent between consecutive frames that
             *  comprise a single header block. */

            if (stream.Closed)
            {
                throw new StreamNotFoundException(priorityFrame.StreamId);
            }

            if (!(stream.Opened || stream.ReservedRemote || stream.HalfClosedLocal))
            {
                throw new ProtocolError(ErrorCodeRegistry.Protocol_Error, "Priority for non opened or reserved stream.");
            }

            // If using priorities.
            if (httpContext.UsePriorities)
            {
                // Set the priority weight.
                stream.Priority = priorityFrame.Weight;
            }
        }