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); }
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); }
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); } }