예제 #1
0
        /// <summary>
        /// Gets or creates a new stream for the dictionary.
        /// </summary>
        /// <param name="streamId">The stream id.</param>
        /// <returns>The current stream.</returns>
        internal ContextStream GetStream(int streamId)
        {
            ContextStream stream;

            if (!_contextStreamDictionary.TryGetValue(streamId, out stream))
            {
                // Get the max stream concurrent streams
                SettingsPair max = _settings[2];

                // If more streams can be created.
                if (_contextStreamDictionary.Count < max.Value)
                {
                    // Try to create the stream.
                    stream        = new ContextStream(streamId, this);
                    stream.Opened = true;

                    // Add the stream to the connection.
                    _contextStreamDictionary.Add(streamId, stream);
                    return(stream);
                }
                else
                {
                    return(null);
                }
            }
            return(stream);
        }
예제 #2
0
        /// <summary>
        /// Set the settings value internally.
        /// </summary>
        /// <param name="id">The setting id.</param>
        /// <param name="value">The setting value.</param>
        internal void SetSettingsPair(SettingsRegistry id, int value)
        {
            // For each setting.
            for (int i = 0; i < _settings.Length; i++)
            {
                // Get the item.
                SettingsPair item = _settings[i];

                // If the id has been found.
                if (id == item.Id)
                {
                    // Set the new value.
                    _settings[i].Value = value;
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Http server context.
        /// </summary>
        /// <param name="requestInput">The request input stream containing the raw data.</param>
        /// <param name="responseOutput">The response output stream containing the raw data.</param>
        public HttpContext(System.IO.Stream requestInput, System.IO.Stream responseOutput)
        {
            // Create the initial settings.
            _settings    = new SettingsPair[6];
            _settings[0] = new SettingsPair(SettingsRegistry.Header_Table_Size, 4096);
            _settings[1] = new SettingsPair(SettingsRegistry.Enable_Push, 1);
            _settings[2] = new SettingsPair(SettingsRegistry.Max_Concurrent_Streams, Constants.DefaultMaxConcurrentStreams);
            _settings[3] = new SettingsPair(SettingsRegistry.Initial_Window_Size, Constants.InitialFlowControlWindowSize);
            _settings[4] = new SettingsPair(SettingsRegistry.Max_Frame_Size, Constants.MaxFramePayloadSize);
            _settings[5] = new SettingsPair(SettingsRegistry.Max_Header_List_Size, Int32.MaxValue);

            // Create the stream collections.
            _contextStreamDictionary = new Collections.CustomDictionary <int, ContextStream>();
            _promisedResources       = new Dictionary <int, string>();

            // Set the request and response streams.
            Input  = requestInput;
            Output = responseOutput;
        }
예제 #4
0
        /// <summary>
        /// Process a setting frame request.
        /// </summary>
        /// <param name="httpContext">The current http context.</param>
        /// <param name="settingFrame">The setting frame.</param>
        private static void ProcessSettingFrameRequest(Nequeo.Net.Http2.HttpContext httpContext, SettingsFrame settingFrame)
        {
            bool isAck = false;

            /*  If an endpoint receives a SETTINGS frame whose stream identifier
             *  field is other than 0x0, the endpoint MUST respond with a connection
             *  error of type PROTOCOL_ERROR. */
            if (settingFrame.StreamId != 0)
            {
                throw new ProtocolError(ErrorCodeRegistry.Protocol_Error, "Settings frame stream id is not equal to 0.");
            }

            /*  Receipt of a SETTINGS frame with the ACK flag set and a length
             *  field value other than 0 MUST be treated as a connection error
             *  of type FRAME_SIZE_ERROR. */
            if (settingFrame.IsAck)
            {
                if (settingFrame.PayloadLength != 0)
                {
                    throw new ProtocolError(ErrorCodeRegistry.Frame_Size_Error,
                                            "Settings frame with ACK flag set and non-zero payload.");
                }

                isAck = true;
            }

            // If is not acknowledged.
            if (!isAck)
            {
                // For the settings data received.
                for (int i = 0; i < settingFrame.EntryCount; i++)
                {
                    SettingsPair setting = settingFrame[i];
                    switch (setting.Id)
                    {
                    case SettingsRegistry.Enable_Push:
                        httpContext.SetSettingsPair(SettingsRegistry.Enable_Push, setting.Value);
                        break;

                    case SettingsRegistry.Header_Table_Size:
                        httpContext.SetSettingsPair(SettingsRegistry.Header_Table_Size, setting.Value);
                        break;

                    case SettingsRegistry.Initial_Window_Size:
                        httpContext.SetSettingsPair(SettingsRegistry.Initial_Window_Size, setting.Value);
                        break;

                    case SettingsRegistry.Max_Concurrent_Streams:
                        httpContext.SetSettingsPair(SettingsRegistry.Max_Concurrent_Streams, setting.Value);
                        break;

                    case SettingsRegistry.Max_Frame_Size:
                        httpContext.SetSettingsPair(SettingsRegistry.Max_Frame_Size, setting.Value);
                        break;

                    case SettingsRegistry.Max_Header_List_Size:
                        httpContext.SetSettingsPair(SettingsRegistry.Max_Header_List_Size, setting.Value);
                        break;

                    default:
                        /*  An endpoint that receives a SETTINGS frame with any other identifier
                         *  MUST treat this as a connection error of type PROTOCOL_ERROR. */
                        throw new ProtocolError(ErrorCodeRegistry.Protocol_Error, "Unknown setting identifier.");
                    }
                }
            }

            // If is not acknowledged.
            if (!settingFrame.IsAck)
            {
                // Sending ACK settings
                SettingsFrame frame = new SettingsFrame(new List <SettingsPair>(new SettingsPair[0]), true);

                // Write the frame.
                httpContext.ResponseWrite(frame.Buffer);
            }
        }