Exemplo n.º 1
0
        private static (string PrevHeaderValue, string NextHeaderValue) GetHeaderValues(HttpRequestHeaders headers, string prevName, string nextName, string prevValue, string nextValue)
        {
            headers.Reset();
            var headerName = Encoding.ASCII.GetBytes(prevName).AsSpan();
            var prevSpan   = Encoding.UTF8.GetBytes(prevValue).AsSpan();

            headers.Append(headerName, prevSpan);
            headers.OnHeadersComplete();
            var prevHeaderValue = ((IHeaderDictionary)headers)[prevName].ToString();

            headers.Reset();

            if (nextValue != null)
            {
                headerName = Encoding.ASCII.GetBytes(prevName).AsSpan();
                var nextSpan = Encoding.UTF8.GetBytes(nextValue).AsSpan();
                headers.Append(headerName, nextSpan);
            }

            headers.OnHeadersComplete();

            var newHeaderValue = ((IHeaderDictionary)headers)[nextName].ToString();

            return(prevHeaderValue, newHeaderValue);
        }
Exemplo n.º 2
0
        public void ValueReuseLatin1NotConfusedForUtf16AndStillRejected(bool reuseValue, KnownHeader header)
        {
            var headers = new HttpRequestHeaders(reuseHeaderValues: reuseValue);

            var headerValue = new char[127]; // 64 + 32 + 16 + 8 + 4 + 2 + 1

            for (var i = 0; i < headerValue.Length; i++)
            {
                headerValue[i] = 'a';
            }

            for (var i = 0; i < headerValue.Length; i++)
            {
                // Set non-ascii Latin char that is valid Utf16 when widened; but not a valid utf8 -> utf16 conversion.
                headerValue[i] = '\u00a3';

                for (var mode = 0; mode <= 1; mode++)
                {
                    string headerValueUtf16Latin1CrossOver;
                    if (mode == 0)
                    {
                        // Full length
                        headerValueUtf16Latin1CrossOver = new string(headerValue);
                    }
                    else
                    {
                        // Truncated length (to ensure different paths from changing lengths in matching)
                        headerValueUtf16Latin1CrossOver = new string(headerValue.AsSpan().Slice(0, i + 1));
                    }

                    headers.Reset();

                    var headerName = Encoding.ASCII.GetBytes(header.Name).AsSpan();
                    var prevSpan   = Encoding.UTF8.GetBytes(headerValueUtf16Latin1CrossOver).AsSpan();

                    headers.Append(headerName, prevSpan);
                    headers.OnHeadersComplete();
                    var prevHeaderValue = ((IHeaderDictionary)headers)[header.Name].ToString();

                    Assert.Equal(headerValueUtf16Latin1CrossOver, prevHeaderValue);
                    Assert.NotSame(headerValueUtf16Latin1CrossOver, prevHeaderValue);

                    headers.Reset();

                    Assert.Throws <InvalidOperationException>(() =>
                    {
                        var headerName = Encoding.ASCII.GetBytes(header.Name).AsSpan();
                        var nextSpan   = Encoding.Latin1.GetBytes(headerValueUtf16Latin1CrossOver).AsSpan();

                        Assert.False(nextSpan.SequenceEqual(Encoding.ASCII.GetBytes(headerValueUtf16Latin1CrossOver)));

                        headers.Append(headerName, nextSpan);
                    });
                }

                // Reset back to Ascii
                headerValue[i] = 'a';
            }
        }
Exemplo n.º 3
0
        public void Latin1ValuesAcceptedInLatin1ModeButNotReused(bool reuseValue, KnownHeader header)
        {
            var headers = new HttpRequestHeaders(reuseHeaderValues: reuseValue, _ => Encoding.Latin1);

            var headerValue = new char[127]; // 64 + 32 + 16 + 8 + 4 + 2 + 1

            for (var i = 0; i < headerValue.Length; i++)
            {
                headerValue[i] = 'a';
            }

            for (var i = 0; i < headerValue.Length; i++)
            {
                // Set non-ascii Latin char that is valid Utf16 when widened; but not a valid utf8 -> utf16 conversion.
                headerValue[i] = '\u00a3';

                for (var mode = 0; mode <= 1; mode++)
                {
                    string headerValueUtf16Latin1CrossOver;
                    if (mode == 0)
                    {
                        // Full length
                        headerValueUtf16Latin1CrossOver = new string(headerValue);
                    }
                    else
                    {
                        // Truncated length (to ensure different paths from changing lengths in matching)
                        headerValueUtf16Latin1CrossOver = new string(headerValue.AsSpan().Slice(0, i + 1));
                    }

                    var headerName     = Encoding.ASCII.GetBytes(header.Name).AsSpan();
                    var latinValueSpan = Encoding.Latin1.GetBytes(headerValueUtf16Latin1CrossOver).AsSpan();

                    Assert.False(latinValueSpan.SequenceEqual(Encoding.ASCII.GetBytes(headerValueUtf16Latin1CrossOver)));

                    headers.Reset();
                    headers.Append(headerName, latinValueSpan);
                    headers.OnHeadersComplete();
                    var parsedHeaderValue1 = ((IHeaderDictionary)headers)[header.Name].ToString();

                    headers.Reset();
                    headers.Append(headerName, latinValueSpan);
                    headers.OnHeadersComplete();
                    var parsedHeaderValue2 = ((IHeaderDictionary)headers)[header.Name].ToString();

                    Assert.Equal(headerValueUtf16Latin1CrossOver, parsedHeaderValue1);
                    Assert.Equal(parsedHeaderValue1, parsedHeaderValue2);
                    Assert.NotSame(parsedHeaderValue1, parsedHeaderValue2);
                }

                // Reset back to Ascii
                headerValue[i] = 'a';
            }
        }
Exemplo n.º 4
0
    public void EntriesCanBeEnumeratedAfterResets()
    {
        HttpRequestHeaders headers = new HttpRequestHeaders();

        EnumerateEntries((IHeaderDictionary)headers);
        headers.Reset();
        EnumerateEntries((IDictionary <string, StringValues>)headers);
        headers.Reset();
        EnumerateEntries((IHeaderDictionary)headers);
        headers.Reset();
        EnumerateEntries((IDictionary <string, StringValues>)headers);
    }
Exemplo n.º 5
0
        public void NullCharactersRejectedInUTF8AndLatin1Mode(bool useLatin1, KnownHeader header)
        {
            var headers = new HttpRequestHeaders(encodingSelector: useLatin1 ? _ => Encoding.Latin1 : (Func <string, Encoding>)null);

            var valueArray = new char[127]; // 64 + 32 + 16 + 8 + 4 + 2 + 1

            for (var i = 0; i < valueArray.Length; i++)
            {
                valueArray[i] = 'a';
            }

            for (var i = 1; i < valueArray.Length; i++)
            {
                // Set non-ascii Latin char that is valid Utf16 when widened; but not a valid utf8 -> utf16 conversion.
                valueArray[i] = '\0';
                string valueString = new string(valueArray);

                headers.Reset();

                Assert.Throws <InvalidOperationException>(() =>
                {
                    var headerName = Encoding.ASCII.GetBytes(header.Name).AsSpan();
                    var valueSpan  = Encoding.ASCII.GetBytes(valueString).AsSpan();

                    headers.Append(headerName, valueSpan);
                });

                valueArray[i] = 'a';
            }
        }
Exemplo n.º 6
0
    public void EnumeratorReusedAfterReset()
    {
        HttpRequestHeaders headers = new HttpRequestHeaders();
        IEnumerable <KeyValuePair <string, StringValues> > enumerable = headers;

        var enumerator0 = enumerable.GetEnumerator();

        headers.Reset();
        var enumerator1 = enumerable.GetEnumerator();

        Assert.Same(enumerator0, enumerator1);
    }
Exemplo n.º 7
0
    public void ClearPseudoRequestHeadersPlusResetClearsHeaderReferenceValue()
    {
        const BindingFlags privateFlags = BindingFlags.NonPublic | BindingFlags.Instance;

        HttpRequestHeaders headers = new HttpRequestHeaders(reuseHeaderValues: false);

        headers.HeaderMethod = "GET";
        headers.ClearPseudoRequestHeaders();
        headers.Reset();

        // Hacky but required because header references is private.
        var headerReferences = typeof(HttpRequestHeaders).GetField("_headers", privateFlags).GetValue(headers);
        var methodValue      = (StringValues)headerReferences.GetType().GetField("_Method").GetValue(headerReferences);

        Assert.Equal(StringValues.Empty, methodValue);
    }
Exemplo n.º 8
0
        public void MultiValueReuseEmptyAfterReset(bool reuseValue, KnownHeader header)
        {
            const string HeaderValue1 = "Hello1";
            const string HeaderValue2 = "Hello2";

            var headers    = new HttpRequestHeaders(reuseHeaderValues: reuseValue);
            var headerName = Encoding.ASCII.GetBytes(header.Name).AsSpan();
            var prevSpan1  = Encoding.UTF8.GetBytes(HeaderValue1).AsSpan();
            var prevSpan2  = Encoding.UTF8.GetBytes(HeaderValue2).AsSpan();

            headers.Append(headerName, prevSpan1);
            headers.Append(headerName, prevSpan2);
            headers.OnHeadersComplete();
            var prevHeaderValue = ((IHeaderDictionary)headers)[header.Name];

            Assert.Equal(2, prevHeaderValue.Count);

            Assert.NotEqual(string.Empty, prevHeaderValue.ToString());
            Assert.Single(headers);
            var count = headers.Count;

            Assert.Equal(1, count);

            headers.Reset();

            // Empty after reset
            var nextHeaderValue = ((IHeaderDictionary)headers)[header.Name].ToString();

            Assert.NotNull(nextHeaderValue);
            Assert.Equal(string.Empty, nextHeaderValue);
            Assert.Empty(headers);
            count = headers.Count;
            Assert.Equal(0, count);

            headers.OnHeadersComplete();

            // Still empty after complete
            nextHeaderValue = ((IHeaderDictionary)headers)[header.Name].ToString();

            Assert.NotNull(nextHeaderValue);
            Assert.Equal(string.Empty, nextHeaderValue);
            Assert.Empty(headers);
            count = headers.Count;
            Assert.Equal(0, count);
        }
Exemplo n.º 9
0
        public void ValueReuseEmptyAfterReset(bool reuseValue, KnownHeader header)
        {
            const string HeaderValue = "Hello";

            var headers    = new HttpRequestHeaders(reuseHeaderValues: reuseValue);
            var headerName = Encoding.ASCII.GetBytes(header.Name).AsSpan();
            var prevSpan   = Encoding.UTF8.GetBytes(HeaderValue).AsSpan();

            headers.Append(headerName, prevSpan, checkForNewlineChars: false);
            headers.OnHeadersComplete();
            var prevHeaderValue = ((IHeaderDictionary)headers)[header.Name].ToString();

            Assert.NotNull(prevHeaderValue);
            Assert.NotEqual(string.Empty, prevHeaderValue);
            Assert.Equal(HeaderValue, prevHeaderValue);
            Assert.NotSame(HeaderValue, prevHeaderValue);
            Assert.Single(headers);
            var count = headers.Count;

            Assert.Equal(1, count);

            headers.Reset();

            // Empty after reset
            var nextHeaderValue = ((IHeaderDictionary)headers)[header.Name].ToString();

            Assert.NotNull(nextHeaderValue);
            Assert.Equal(string.Empty, nextHeaderValue);
            Assert.NotEqual(HeaderValue, nextHeaderValue);
            Assert.Empty(headers);
            count = headers.Count;
            Assert.Equal(0, count);

            headers.OnHeadersComplete();

            // Still empty after complete
            nextHeaderValue = ((IHeaderDictionary)headers)[header.Name].ToString();

            Assert.NotNull(nextHeaderValue);
            Assert.Equal(string.Empty, nextHeaderValue);
            Assert.NotEqual(HeaderValue, nextHeaderValue);
            Assert.Empty(headers);
            count = headers.Count;
            Assert.Equal(0, count);
        }