Ejemplo n.º 1
0
        /// <summary>
        /// Process cookies.
        /// </summary>
        /// <param name="toProcess">The header list containing the cookies.</param>
        private void ProcessCookie(HeadersList toProcess)
        {
            /* 12 -> 8.1.3.4.
             * If there are multiple Cookie header fields after
             * decompression, these MUST be concatenated into a single octet string
             * using the two octet delimiter of 0x3B, 0x20 (the ASCII string "; "). */

            const string delimiter = "; ";
            var          cookie    = new StringBuilder(String.Empty);

            for (int i = 0; i < toProcess.Count; i++)
            {
                if (!toProcess[i].Key.Equals(CommonHeaders.Cookie))
                {
                    continue;
                }

                cookie.Append(toProcess[i].Value);
                cookie.Append(delimiter);
                toProcess.RemoveAt(i--);
            }

            if (cookie.Length > 0)
            {
                // Add without last delimeter
                toProcess.Add(new KeyValuePair <string, string>(CommonHeaders.Cookie,
                                                                cookie.ToString(cookie.Length - 2, 2)));
            }
        }
Ejemplo n.º 2
0
        private void EvictHeaderTableEntries(HeadersList headersTable, HeadersList refTable)
        {
            /* 07 -> 3.3.2
            Whenever the maximum size for the header table is made smaller,
            entries are evicted from the end of the header table until the size
            of the header table is less than or equal to the maximum size. */
            while (headersTable.StoredHeadersSize >= _maxHeaderByteSize && headersTable.Count > 0)
            {
                var header = headersTable[headersTable.Count - 1];
                headersTable.RemoveAt(headersTable.Count - 1);

                /* 07 -> 3.3.2
                Whenever an entry is evicted from the header table, any reference to
                that entry contained by the reference set is removed. */
                if (refTable.Contains(header))
                    refTable.Remove(header);
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Evict header table entry.
        /// </summary>
        /// <param name="headersTable"></param>
        /// <param name="refTable"></param>
        private void EvictHeaderTableEntries(HeadersList headersTable, HeadersList refTable)
        {
            /* 07 -> 3.3.2
             * Whenever the maximum size for the header table is made smaller,
             * entries are evicted from the end of the header table until the size
             * of the header table is less than or equal to the maximum size. */
            while (headersTable.StoredHeadersSize >= _maxHeaderByteSize && headersTable.Count > 0)
            {
                var header = headersTable[headersTable.Count - 1];
                headersTable.RemoveAt(headersTable.Count - 1);

                /* 07 -> 3.3.2
                 * Whenever an entry is evicted from the header table, any reference to
                 * that entry contained by the reference set is removed. */
                if (refTable.Contains(header))
                {
                    refTable.Remove(header);
                }
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Insert to headers table.
        /// </summary>
        /// <param name="header">The header.</param>
        /// <param name="refSet">The refernced header list.</param>
        /// <param name="headersTable">The header list.</param>
        private void InsertToHeadersTable(KeyValuePair <string, string> header, HeadersList refSet,
                                          HeadersList headersTable)
        {
            /* 07 -> 3.3.1
             * The size of an entry is the sum of its name's length in octets (as
             * defined in Section 4.1.2), of its value's length in octets
             * (Section 4.1.2) and of 32 octets. */
            int headerLen = header.Key.Length + header.Value.Length + 32;

            /* 07 -> 3.3.2
             * Whenever a new entry is to be added to the table, any name referenced
             * by the representation of this new entry is cached, and then entries
             * are evicted from the end of the header table until the size of the
             * header table is less than or equal to (maximum size - new entry
             * size), or until the table is empty.
             *
             * If the size of the new entry is less than or equal to the maximum
             * size, that entry is added to the table.  It is not an error to
             * attempt to add an entry that is larger than the maximum size. */

            while (headersTable.StoredHeadersSize + headerLen >= _maxHeaderByteSize && headersTable.Count > 0)
            {
                headersTable.RemoveAt(headersTable.Count - 1);

                /* 07 -> 3.3.2
                 * Whenever an entry is evicted from the header table, any reference to
                 * that entry contained by the reference set is removed. */

                if (refSet.Contains(header))
                {
                    refSet.Remove(header);
                }
            }

            /* 07 -> 3.2.1
             * We should always insert into
             * begin of the headers table. */
            headersTable.Insert(0, header);
        }
        /// <summary>
        /// Modifies the table.
        /// </summary>
        /// <param name="headerName">Name of the header.</param>
        /// <param name="headerValue">The header value.</param>
        /// <param name="headerType">Type of the header.</param>
        /// <param name="useHeadersTable">The use headers table.</param>
        /// <param name="index">The index.</param>
        private void ModifyTable(string headerName, string headerValue, IndexationType headerType,
                                        HeadersList useHeadersTable, int index)
        {
            int headerLen = headerName.Length + headerValue.Length + sizeof(Int32);

            //spec 04: 3.2.3.  Header Table Management
            //   The header table can be modified by either adding a new entry to it
            //or by replacing an existing one.  Before doing such a modification,
            //it has to be ensured that the header table size will stay lower than
            //or equal to the SETTINGS_MAX_BUFFER_SIZE limit (see Section 5).  To
            //achieve this, repeatedly, the first entry of the header table is
            //removed, until enough space is available for the modification.

            //A consequence of removing one or more entries at the beginning of the
            //header table is that the remaining entries are renumbered.  The first
            //entry of the header table is always associated to the index 0.

            //When the modification of the header table is the replacement of an
            //existing entry, the replaced entry is the one indicated in the
            //literal representation before any entry is removed from the header
            //table.  If the entry to be replaced is removed from the header table
            //when performing the size adjustment, the replacement entry is
            //inserted at the beginning of the header table.

            //The addition of a new entry with a size greater than the
            //SETTINGS_MAX_BUFFER_SIZE limit causes all the entries from the header
            //table to be dropped and the new entry not to be added to the header
            //table.  The replacement of an existing entry with a new entry with a
            //size greater than the SETTINGS_MAX_BUFFER_SIZE has the same
            //consequences.

            switch (headerType)
            {
                case IndexationType.Incremental:
                    while (useHeadersTable.StoredHeadersSize + headerLen > MaxHeaderByteSize && useHeadersTable.Count > 0)
                    {
                            useHeadersTable.RemoveAt(0);
                    }
                    useHeadersTable.Add(new KeyValuePair<string, string>(headerName, headerValue));
                    break;
                case IndexationType.Substitution:
                    if (index != -1)
                    {
                        var header = useHeadersTable[index];
                        int substHeaderLen = header.Key.Length + header.Value.Length + sizeof(Int32);
                        int deletedHeadersCounter = 0;

                        while (useHeadersTable.StoredHeadersSize + headerLen - substHeaderLen > MaxHeaderByteSize)
                        {
                            if (useHeadersTable.Count > 0)
                            {
                                useHeadersTable.RemoveAt(0);
                                deletedHeadersCounter++;
                            }
                        }

                        if (index >= deletedHeadersCounter)
                        {
                            useHeadersTable[index - deletedHeadersCounter] =
                                            new KeyValuePair<string, string>(headerName, headerValue);
                        }
                        else
                        {
                            useHeadersTable.Insert(0, new KeyValuePair<string, string>(headerName, headerValue));
                        }
                    }
                    //If header wasn't found then add it to the table
                    else
                    {
                        while (useHeadersTable.StoredHeadersSize + headerLen > MaxHeaderByteSize && useHeadersTable.Count > 0)
                        {
                            useHeadersTable.RemoveAt(0);
                        }
                        useHeadersTable.Add(new KeyValuePair<string, string>(headerName, headerValue));
                    }
                    break;
                default:
                    return;
            }
        }
Ejemplo n.º 6
0
        private void ProcessCookie(HeadersList toProcess)
        {
            /* 12 -> 8.1.3.4.
            If there are multiple Cookie header fields after
            decompression, these MUST be concatenated into a single octet string
            using the two octet delimiter of 0x3B, 0x20 (the ASCII string "; "). */

            const string delimiter = "; ";
            var cookie = new StringBuilder(String.Empty);

            for (int i = 0; i < toProcess.Count; i++)
            {
                if (!toProcess[i].Key.Equals(CommonHeaders.Cookie))
                    continue;

                cookie.Append(toProcess[i].Value);
                cookie.Append(delimiter);
                toProcess.RemoveAt(i--);
            }

            if (cookie.Length > 0)
            {
                // Add without last delimeter
                toProcess.Add(new KeyValuePair<string, string>(CommonHeaders.Cookie,
                                                               cookie.ToString(cookie.Length - 2, 2)));
            }
        }
Ejemplo n.º 7
0
        private void InsertToHeadersTable(KeyValuePair<string, string> header, HeadersList refSet,
            HeadersList headersTable)
        {
            /* 07 -> 3.3.1
            The size of an entry is the sum of its name's length in octets (as
            defined in Section 4.1.2), of its value's length in octets
            (Section 4.1.2) and of 32 octets. */
            int headerLen = header.Key.Length + header.Value.Length + 32;

            /* 07 -> 3.3.2 
            Whenever a new entry is to be added to the table, any name referenced
            by the representation of this new entry is cached, and then entries
            are evicted from the end of the header table until the size of the
            header table is less than or equal to (maximum size - new entry
            size), or until the table is empty. 
            
            If the size of the new entry is less than or equal to the maximum
            size, that entry is added to the table.  It is not an error to
            attempt to add an entry that is larger than the maximum size. */

            while (headersTable.StoredHeadersSize + headerLen >= _maxHeaderByteSize && headersTable.Count > 0)
            {
                headersTable.RemoveAt(headersTable.Count - 1);

                /* 07 -> 3.3.2
                Whenever an entry is evicted from the header table, any reference to
                that entry contained by the reference set is removed. */

                if (refSet.Contains(header))
                    refSet.Remove(header);
            }

            /* 07 -> 3.2.1
            We should always insert into 
            begin of the headers table. */
            headersTable.Insert(0, header);
        }
Ejemplo n.º 8
0
        //09 -> 8.1.3.4.  Compressing the Cookie Header Field
        private void ProcessCookie(HeadersList toProcess)
        {
            //The Cookie header field [COOKIE] can carry a significant amount of
            //redundant data.

            //The Cookie header field uses a semi-colon (";") to delimit cookie-
            //pairs (or "crumbs").  This header field doesn't follow the list
            //construction rules in HTTP (see [HTTP-p1], Section 3.2.2), which
            //prevents cookie-pairs from being separated into different name-value
            //pairs.  This can significantly reduce compression efficiency as
            //individual cookie-pairs are updated.

            //To allow for better compression efficiency, the Cookie header field
            //MAY be split into separate header fields, each with one or more
            //cookie-pairs.  If there are multiple Cookie header fields after
            //decompression, these MUST be concatenated into a single octet string
            //using the two octet delimiter of 0x3B, 0x20 (the ASCII string "; ").

            const string delimiter = "; ";
            var cookie = new StringBuilder(String.Empty);

            for (int i = 0; i < toProcess.Count; i++)
            {
                if (!toProcess[i].Key.Equals(CommonHeaders.Cookie))
                    continue;

                cookie.Append(toProcess[i].Value);
                cookie.Append(delimiter);
                toProcess.RemoveAt(i--);
            }

            if (cookie.Length > 0)
            {
                //Add without last delimeter
                toProcess.Add(new KeyValuePair<string, string>(CommonHeaders.Cookie,
                                                               cookie.ToString(cookie.Length - 2, 2)));
            }
        }
Ejemplo n.º 9
0
        private void MakeHeadersTableBeUpToDate(HeadersList headersTable, HeadersList refTable)
        {
            while (headersTable.StoredHeadersSize >= _maxHeaderByteSize && headersTable.Count > 0)
            {

                var header = headersTable[headersTable.Count - 1];
                headersTable.RemoveAt(headersTable.Count - 1);

                //spec 05
                //3.3.2. Entry Eviction When Header Table Size Changes
                //Whenever an entry is evicted from the header table, any reference to
                //that entry contained by the reference set is removed.

                if (refTable.Contains(header))
                    refTable.Remove(header);
            }
        }
Ejemplo n.º 10
0
        private void InsertToHeadersTable(KeyValuePair<string, string> header, 
                                          HeadersList refSet,
                                          HeadersList headersTable)
        {
            //spec 05
            // The size of an entry is the sum of its name's length in octets (as
            //defined in Section 4.1.2), of its value's length in octets
            //(Section 4.1.2) and of 32 octets.
            int headerLen = header.Key.Length + header.Value.Length + 32;

            //spec 05
            //3.3.3. Entry Eviction when Adding New Entries
            //Whenever a new entry is to be added to the table, any name referenced
            //by the representation of this new entry is cached, and then entries
            //are evicted from the end of the header table until the size of the
            //header table is less than or equal to SETTINGS_HEADER_TABLE_SIZE -
            //new entry size, or until the table is empty.

            //If the size of the new entry is less than or equal to
            //SETTINGS_HEADER_TABLE_SIZE, that entry is added to the table.  It is
            //not an error to attempt to add an entry that is larger than
            //SETTINGS_HEADER_TABLE_SIZE.

            while (headersTable.StoredHeadersSize + headerLen >= _maxHeaderByteSize && headersTable.Count > 0)
            {
                headersTable.RemoveAt(headersTable.Count - 1);

                //spec 05
                //3.3.2. Entry Eviction When Header Table Size Changes
                //Whenever an entry is evicted from the header table, any reference to
                //that entry contained by the reference set is removed.

                if (refSet.Contains(header))
                    refSet.Remove(header);
            }

            //spec 05
            //We should always insert into begin of the headers table.
            //See 3.2.1.  Header Field Representation Processing
            headersTable.Insert(0, header);
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Modifies the table.
        /// </summary>
        /// <param name="headerName">Name of the header.</param>
        /// <param name="headerValue">The header value.</param>
        /// <param name="headerType">Type of the header.</param>
        /// <param name="useHeadersTable">The use headers table.</param>
        /// <param name="index">The index.</param>
        private void ModifyTable(string headerName, string headerValue, IndexationType headerType,
                                        HeadersList useHeadersTable, int index)
        {
            int headerLen = headerName.Length + headerValue.Length;
                switch (headerType)
                {
                    case IndexationType.Incremental:
                        if (useHeadersTable.Count > HeadersLimit - 1)
                        {
                            useHeadersTable.RemoveAt(0);
                        }

                        while (useHeadersTable.StoredHeadersSize + headerLen > MaxHeaderByteSize)
                        {
                            useHeadersTable.RemoveAt(0);
                        }
                        useHeadersTable.Add(new KeyValuePair<string, string>(headerName, headerValue));
                        break;
                    case IndexationType.Substitution:
                        if (index != -1)
                        {
                            useHeadersTable[index] = new KeyValuePair<string, string>(headerName, headerValue);
                        }
                        else
                        {
                            if (useHeadersTable.Count > HeadersLimit - 1)
                            {
                                useHeadersTable.RemoveAt(0);
                            }

                            while (useHeadersTable.StoredHeadersSize + headerLen > MaxHeaderByteSize)
                            {
                                useHeadersTable.RemoveAt(0);
                            }
                            //If header wasn't found then add it to the table
                            useHeadersTable.Add(new KeyValuePair<string, string>(headerName, headerValue));
                        }
                        break;
                    default:
                        return;
                }
        }