Пример #1
0
        public static void ToHttp2Headers(HttpHeaders inHeaders, IHttp2Headers output)
        {
            // Choose 8 as a default size because it is unlikely we will see more than 4 Connection headers values, but
            // still allowing for "enough" space in the map to reduce the chance of hash code collision.
            var connectionBlacklist = ToLowercaseMap(inHeaders.GetAll(HttpHeaderNames.Connection), 8);

            foreach (var entry in inHeaders)
            {
                AsciiString aName = entry.Key.ToLowerCase();
                if (!HttpToHttp2HeaderBlacklist.Contains(aName) && !connectionBlacklist.Contains(aName))
                {
                    // https://tools.ietf.org/html/rfc7540#section-8.1.2.2 makes a special exception for TE
                    if (aName.ContentEqualsIgnoreCase(HttpHeaderNames.Te))
                    {
                        ToHttp2HeadersFilterTE(entry, output);
                    }
                    else if (aName.ContentEqualsIgnoreCase(HttpHeaderNames.Cookie))
                    {
                        AsciiString value       = AsciiString.Of(entry.Value);
                        uint        uValueCount = (uint)value.Count;
                        // split up cookies to allow for better compression
                        // https://tools.ietf.org/html/rfc7540#section-8.1.2.5
                        try
                        {
                            int index = value.ForEachByte(ByteProcessor.FindSemicolon);
                            if (uValueCount > (uint)index) // != -1
                            {
                                int start = 0;
                                do
                                {
                                    _ = output.Add(HttpHeaderNames.Cookie, value.SubSequence(start, index, false));
                                    // skip 2 characters "; " (see https://tools.ietf.org/html/rfc6265#section-4.2.1)
                                    start = index + 2;
                                } while ((uint)start < uValueCount &&
                                         uValueCount > (uint)(index = value.ForEachByte(start, value.Count - start, ByteProcessor.FindSemicolon))); // != -1
                                if ((uint)start >= uValueCount)
                                {
                                    ThrowHelper.ThrowArgumentException_CookieValueIsOfUnexpectedFormat(value);
                                }
                                _ = output.Add(HttpHeaderNames.Cookie, value.SubSequence(start, value.Count, false));
                            }
                            else
                            {
                                _ = output.Add(HttpHeaderNames.Cookie, value);
                            }
                        }
                        catch (Exception)
                        {
                            // This is not expect to happen because FIND_SEMI_COLON never throws but must be caught
                            // because of the ByteProcessor interface.
                            ThrowHelper.ThrowInvalidOperationException();
                        }
                    }
                    else
                    {
                        _ = output.Add(aName, entry.Value);
                    }
                }
            }
        }
Пример #2
0
        private static CharSequenceMap <AsciiString> ToLowercaseMap(IEnumerable <ICharSequence> values, int arraySizeHint)
        {
            var valueConverter = UnsupportedValueConverter <AsciiString> .Instance;
            var result         = new CharSequenceMap <AsciiString>(true, valueConverter, arraySizeHint);

            foreach (var item in values)
            {
                AsciiString lowerCased = AsciiString.Of(item).ToLowerCase();
                try
                {
                    int index = lowerCased.ForEachByte(ByteProcessor.FindComma);
                    if (index != -1)
                    {
                        int start = 0;
                        do
                        {
                            _     = result.Add(lowerCased.SubSequence(start, index, false).Trim(), AsciiString.Empty);
                            start = index + 1;
                        } while (start < lowerCased.Count &&
                                 (index = lowerCased.ForEachByte(start, lowerCased.Count - start, ByteProcessor.FindComma)) != -1);
                        _ = result.Add(lowerCased.SubSequence(start, lowerCased.Count, false).Trim(), AsciiString.Empty);
                    }
                    else
                    {
                        _ = result.Add(lowerCased.Trim(), AsciiString.Empty);
                    }
                }
                catch (Exception)
                {
                    // This is not expect to happen because FIND_COMMA never throws but must be caught
                    // because of the ByteProcessor interface.
                    ThrowHelper.ThrowInvalidOperationException();
                }
            }

            return(result);
        }