public void SameExceptionThrownForMissingKey()
        {
            IDictionary<string, StringValues> headers = new FrameRequestHeaders();

            Assert.Throws<KeyNotFoundException>(() => headers["custom"]);
            Assert.Throws<KeyNotFoundException>(() => headers["host"]);
        }
        public void ContainsAndContainsKeyWork()
        {
            IDictionary<string, StringValues> headers = new FrameRequestHeaders();
            var kv1 = new KeyValuePair<string, StringValues>("host", new[] { "localhost" });
            var kv2 = new KeyValuePair<string, StringValues>("custom", new[] { "value" });
            var kv1b = new KeyValuePair<string, StringValues>("host", new[] { "localhost" });
            var kv2b = new KeyValuePair<string, StringValues>("custom", new[] { "value" });

            Assert.False(headers.ContainsKey("host"));
            Assert.False(headers.ContainsKey("custom"));
            Assert.False(headers.Contains(kv1));
            Assert.False(headers.Contains(kv2));

            headers["host"] = kv1.Value;
            Assert.True(headers.ContainsKey("host"));
            Assert.False(headers.ContainsKey("custom"));
            Assert.True(headers.Contains(kv1));
            Assert.False(headers.Contains(kv2));
            Assert.False(headers.Contains(kv1b));
            Assert.False(headers.Contains(kv2b));

            headers["custom"] = kv2.Value;
            Assert.True(headers.ContainsKey("host"));
            Assert.True(headers.ContainsKey("custom"));
            Assert.True(headers.Contains(kv1));
            Assert.True(headers.Contains(kv2));
            Assert.False(headers.Contains(kv1b));
            Assert.False(headers.Contains(kv2b));
        }
        public void InitialDictionaryIsEmpty()
        {
            IDictionary<string, StringValues> headers = new FrameRequestHeaders();

            Assert.Equal(0, headers.Count);
            Assert.False(headers.IsReadOnly);
        }
        public static MessageBody For(
            string httpVersion,
            FrameRequestHeaders headers,
            FrameContext context)
        {
            // see also http://tools.ietf.org/html/rfc2616#section-4.4

            var keepAlive = httpVersion != "HTTP/1.0";

            var connection = headers.HeaderConnection.ToString();
            if (connection.Length > 0)
            {
                keepAlive = connection.Equals("keep-alive", StringComparison.OrdinalIgnoreCase);
            }

            var transferEncoding = headers.HeaderTransferEncoding.ToString();
            if (transferEncoding.Length > 0)
            {
                return new ForChunkedEncoding(keepAlive, context);
            }

            var contentLength = headers.HeaderContentLength.ToString();
            if (contentLength.Length > 0)
            {
                return new ForContentLength(keepAlive, int.Parse(contentLength), context);
            }

            if (keepAlive)
            {
                return new ForContentLength(true, 0, context);
            }

            return new ForRemainingData(context);
        }
        public void KnownAndCustomHeaderCountAddedTogether()
        {
            IDictionary<string, StringValues> headers = new FrameRequestHeaders();

            headers["host"] = new[] { "value" };
            headers["custom"] = new[] { "value" };

            Assert.Equal(2, headers.Count);
        }
        public void SettingKnownHeadersWorks()
        {
            IDictionary<string, StringValues> headers = new FrameRequestHeaders();

            headers["host"] = new[] { "value" };

            Assert.NotNull(headers["host"]);
            Assert.Equal(1, headers["host"].Count);
            Assert.Equal("value", headers["host"][0]);
        }
        public void EntriesCanBeEnumerated()
        {
            IDictionary<string, StringValues> headers = new FrameRequestHeaders();
            var v1 = new[] { "localhost" };
            var v2 = new[] { "value" };
            headers["host"] = v1;
            headers["custom"] = v2;

            Assert.Equal(
                new[] {
                    new KeyValuePair<string, StringValues>("Host", v1),
                    new KeyValuePair<string, StringValues>("custom", v2),
                },
                headers);
        }
        public void TryGetValueWorksForKnownAndUnknownHeaders()
        {
            IDictionary<string, StringValues> headers = new FrameRequestHeaders();

            StringValues value;
            Assert.False(headers.TryGetValue("host", out value));
            Assert.False(headers.TryGetValue("custom", out value));

            headers["host"] = new[] { "value" };
            Assert.True(headers.TryGetValue("host", out value));
            Assert.False(headers.TryGetValue("custom", out value));

            headers["custom"] = new[] { "value" };
            Assert.True(headers.TryGetValue("host", out value));
            Assert.True(headers.TryGetValue("custom", out value));
        }
        public void ClearRemovesAllHeaders()
        {
            IDictionary<string, StringValues> headers = new FrameRequestHeaders();
            headers.Add("host", new[] { "localhost" });
            headers.Add("custom", new[] { "value" });

            StringValues value;
            Assert.Equal(2, headers.Count);
            Assert.True(headers.TryGetValue("host", out value));
            Assert.True(headers.TryGetValue("custom", out value));

            headers.Clear();

            Assert.Equal(0, headers.Count);
            Assert.False(headers.TryGetValue("host", out value));
            Assert.False(headers.TryGetValue("custom", out value));
        }
        public void AddWorksLikeSetAndThrowsIfKeyExists()
        {
            IDictionary<string, StringValues> headers = new FrameRequestHeaders();

            StringValues value;
            Assert.False(headers.TryGetValue("host", out value));
            Assert.False(headers.TryGetValue("custom", out value));

            headers.Add("host", new[] { "localhost" });
            headers.Add("custom", new[] { "value" });
            Assert.True(headers.TryGetValue("host", out value));
            Assert.True(headers.TryGetValue("custom", out value));

            Assert.Throws<ArgumentException>(() => headers.Add("host", new[] { "localhost" }));
            Assert.Throws<ArgumentException>(() => headers.Add("custom", new[] { "value" }));
            Assert.True(headers.TryGetValue("host", out value));
            Assert.True(headers.TryGetValue("custom", out value));
        }
        public void EmptyHeaderValuesCanBeParsed(string rawHeaders, int numHeaders)
        {
            var socketInput = new SocketInput(new MemoryPool2());
            var headerCollection = new FrameRequestHeaders();

            var headerArray = Encoding.ASCII.GetBytes(rawHeaders);
            var inputBuffer = socketInput.IncomingStart(headerArray.Length);
            Buffer.BlockCopy(headerArray, 0, inputBuffer.Data.Array, inputBuffer.Data.Offset, headerArray.Length);
            socketInput.IncomingComplete(headerArray.Length, null);

            var success = Frame.TakeMessageHeaders(socketInput, headerCollection);

            Assert.True(success);
            Assert.Equal(numHeaders, headerCollection.Count());

            // Assert TakeMessageHeaders consumed all the input
            var scan = socketInput.ConsumingStart();
            Assert.True(scan.IsEnd);
        }
Exemple #12
0
        public static bool TakeMessageHeaders(SocketInput input, FrameRequestHeaders requestHeaders)
        {
            var scan     = input.ConsumingStart();
            var consumed = scan;

            try
            {
                int chFirst;
                int chSecond;
                while (!scan.IsEnd)
                {
                    var beginName = scan;
                    scan.Seek(ref _vectorColons, ref _vectorCRs);
                    var endName = scan;

                    chFirst = scan.Take();
                    var beginValue = scan;
                    chSecond = scan.Take();

                    if (chFirst == -1 || chSecond == -1)
                    {
                        return(false);
                    }
                    if (chFirst == '\r')
                    {
                        if (chSecond == '\n')
                        {
                            consumed = scan;
                            return(true);
                        }
                        throw new InvalidDataException("Malformed request");
                    }

                    while (
                        chSecond == ' ' ||
                        chSecond == '\t' ||
                        chSecond == '\r' ||
                        chSecond == '\n')
                    {
                        if (chSecond == '\r')
                        {
                            var scanAhead = scan;
                            var chAhead   = scanAhead.Take();
                            if (chAhead == '\n')
                            {
                                chAhead = scanAhead.Take();
                                // If the "\r\n" isn't part of "linear whitespace",
                                // then this header has no value.
                                if (chAhead != ' ' && chAhead != '\t')
                                {
                                    break;
                                }
                            }
                        }

                        beginValue = scan;
                        chSecond   = scan.Take();
                    }
                    scan = beginValue;

                    var wrapping = false;
                    while (!scan.IsEnd)
                    {
                        if (scan.Seek(ref _vectorCRs) == -1)
                        {
                            // no "\r" in sight, burn used bytes and go back to await more data
                            return(false);
                        }

                        var endValue = scan;
                        chFirst  = scan.Take(); // expecting: /r
                        chSecond = scan.Take(); // expecting: /n

                        if (chSecond != '\n')
                        {
                            // "\r" was all by itself, move just after it and try again
                            scan = endValue;
                            scan.Take();
                            continue;
                        }

                        var chThird = scan.Peek();
                        if (chThird == ' ' || chThird == '\t')
                        {
                            // special case, "\r\n " or "\r\n\t".
                            // this is considered wrapping"linear whitespace" and is actually part of the header value
                            // continue past this for the next
                            wrapping = true;
                            continue;
                        }

                        var name  = beginName.GetArraySegment(endName);
                        var value = beginValue.GetAsciiString(endValue);
                        if (wrapping)
                        {
                            value = value.Replace("\r\n", " ");
                        }

                        consumed = scan;
                        requestHeaders.Append(name.Array, name.Offset, name.Count, value);
                        break;
                    }
                }
                return(false);
            }
            finally
            {
                input.ConsumingComplete(consumed, scan);
            }
        }
        public void CopyToMovesDataIntoArray()
        {
            IDictionary<string, StringValues> headers = new FrameRequestHeaders();
            headers.Add("host", new[] { "localhost" });
            headers.Add("custom", new[] { "value" });

            var entries = new KeyValuePair<string, StringValues>[4];
            headers.CopyTo(entries, 1);

            Assert.Null(entries[0].Key);
            Assert.Equal(new StringValues(), entries[0].Value);

            Assert.Equal("Host", entries[1].Key);
            Assert.Equal(new[] { "localhost" }, entries[1].Value);

            Assert.Equal("custom", entries[2].Key);
            Assert.Equal(new[] { "value" }, entries[2].Value);

            Assert.Null(entries[3].Key);
            Assert.Equal(new StringValues(), entries[0].Value);
        }
        public void KeysAndValuesCanBeEnumerated()
        {
            IDictionary<string, StringValues> headers = new FrameRequestHeaders();
            StringValues v1 = new[] { "localhost" };
            StringValues v2 = new[] { "value" };
            headers["host"] = v1;
            headers["custom"] = v2;

            Assert.Equal<string>(
                new[] { "Host", "custom" },
                headers.Keys);

            Assert.Equal<StringValues>(
                new[] { v1, v2 },
                headers.Values);
        }
Exemple #15
0
        public static bool TakeMessageHeaders(SocketInput input, FrameRequestHeaders requestHeaders)
        {
            var scan = input.ConsumingStart();
            var consumed = scan;
            try
            {
                int chFirst;
                int chSecond;
                while (!scan.IsEnd)
                {
                    var beginName = scan;
                    scan.Seek(ref _vectorColons, ref _vectorCRs);
                    var endName = scan;

                    chFirst = scan.Take();
                    var beginValue = scan;
                    chSecond = scan.Take();

                    if (chFirst == -1 || chSecond == -1)
                    {
                        return false;
                    }
                    if (chFirst == '\r')
                    {
                        if (chSecond == '\n')
                        {
                            consumed = scan;
                            return true;
                        }
                        throw new InvalidDataException("Malformed request");
                    }

                    while (
                        chSecond == ' ' ||
                        chSecond == '\t' ||
                        chSecond == '\r' ||
                        chSecond == '\n')
                    {
                        if (chSecond == '\r')
                        {
                            var scanAhead = scan;
                            var chAhead = scanAhead.Take();
                            if (chAhead == '\n')
                            {
                                chAhead = scanAhead.Take();
                                // If the "\r\n" isn't part of "linear whitespace",
                                // then this header has no value.
                                if (chAhead != ' ' && chAhead != '\t')
                                {
                                    break;
                                }
                            }
                        }

                        beginValue = scan;
                        chSecond = scan.Take();
                    }
                    scan = beginValue;

                    var wrapping = false;
                    while (!scan.IsEnd)
                    {
                        if (scan.Seek(ref _vectorCRs) == -1)
                        {
                            // no "\r" in sight, burn used bytes and go back to await more data
                            return false;
                        }

                        var endValue = scan;
                        chFirst = scan.Take(); // expecting: /r
                        chSecond = scan.Take(); // expecting: /n

                        if (chSecond != '\n')
                        {
                            // "\r" was all by itself, move just after it and try again
                            scan = endValue;
                            scan.Take();
                            continue;
                        }

                        var chThird = scan.Peek();
                        if (chThird == ' ' || chThird == '\t')
                        {
                            // special case, "\r\n " or "\r\n\t".
                            // this is considered wrapping"linear whitespace" and is actually part of the header value
                            // continue past this for the next
                            wrapping = true;
                            continue;
                        }

                        var name = beginName.GetArraySegment(endName);
                        var value = beginValue.GetAsciiString(endValue);
                        if (wrapping)
                        {
                            value = value.Replace("\r\n", " ");
                        }

                        consumed = scan;
                        requestHeaders.Append(name.Array, name.Offset, name.Count, value);
                        break;
                    }
                }
                return false;
            }
            finally
            {
                input.ConsumingComplete(consumed, scan);
            }
        }