public void TryAddWithoutValidation_AddSingleValue_ValueParsed() { MockHeaders headers = new MockHeaders(); headers.TryAddWithoutValidation(knownHeader, rawPrefix); Assert.Equal(1, headers.Count()); Assert.Equal(1, headers.First().Value.Count()); Assert.Equal(parsedPrefix, headers.First().Value.First()); Assert.Equal(1, headers.Parser.TryParseValueCallCount); }
public void TryAddWithoutValidation_AddTwoSingleValues_BothValuesParsed() { MockHeaders headers = new MockHeaders(); headers.TryAddWithoutValidation(knownHeader, rawPrefix + "1"); headers.TryAddWithoutValidation(knownHeader, rawPrefix + "2"); Assert.Equal(0, headers.Parser.TryParseValueCallCount); Assert.Equal(1, headers.Count()); Assert.Equal(2, headers.First().Value.Count()); Assert.Equal(parsedPrefix + "1", headers.First().Value.ElementAt(0)); Assert.Equal(parsedPrefix + "2", headers.First().Value.ElementAt(1)); Assert.Equal(2, headers.Parser.TryParseValueCallCount); }
public void TryAddWithoutValidation_AddTwoValidValuesAsOneString_BothValuesParsed() { MockHeaders headers = new MockHeaders(); headers.TryAddWithoutValidation(knownHeader, rawPrefix + "1," + rawPrefix + "2"); Assert.Equal(0, headers.Parser.TryParseValueCallCount); Assert.Equal(1, headers.Count()); Assert.Equal(2, headers.First().Value.Count()); Assert.Equal(parsedPrefix + "1", headers.First().Value.ElementAt(0)); Assert.Equal(parsedPrefix + "2", headers.First().Value.ElementAt(1)); // The parser gets called for each value in the raw string. I.e. if we have 1 raw string containing two // values, the parser gets called twice. Assert.Equal(2, headers.Parser.TryParseValueCallCount); }
public void TryAddWithoutValidation_AddValueContainingNewLine_NewLineFollowedByWhitespaceIsOKButNewLineFollowedByNonWhitespaceIsRejected() { MockHeaders headers = new MockHeaders(); // The header parser rejects both of the following values. Both values contain new line chars. According // to the RFC, LWS supports newlines followed by whitespaces. I.e. the first value gets rejected by the // parser, but added to the list of invalid values. headers.TryAddWithoutValidation(knownHeader, invalidHeaderValue + "\r\n other: value"); // OK, LWS is allowed Assert.Equal(1, headers.Count()); Assert.Equal(1, headers.First().Value.Count()); Assert.Equal(invalidHeaderValue + "\r\n other: value", headers.First().Value.First()); Assert.Equal(1, headers.Parser.TryParseValueCallCount); // This value is considered invalid (newline char followed by non-whitepace). However, since // TryAddWithoutValidation() only causes the header value to be analyzed when it gets actually accessed, no // exception is thrown. Instead the value is discarded and a warning is logged. headers.Clear(); headers.TryAddWithoutValidation(knownHeader, invalidHeaderValue + "\r\nother:value"); Assert.False(headers.Contains(knownHeader)); Assert.Equal(0, headers.Count()); // Adding newline followed by whitespace to a custom header is OK. headers.Clear(); headers.TryAddWithoutValidation("custom", "value\r\n other: value"); // OK, LWS is allowed Assert.Equal(1, headers.Count()); Assert.Equal(1, headers.First().Value.Count()); Assert.Equal("value\r\n other: value", headers.First().Value.First()); // Adding newline followed by non-whitespace chars is invalid. The value is discarded and a warning is // logged. headers.Clear(); headers.TryAddWithoutValidation("custom", "value\r\nother: value"); Assert.False(headers.Contains("custom")); Assert.Equal(0, headers.Count()); // Also ending a value with newline is invalid. Verify that valid values are added. headers.Clear(); headers.Parser.TryParseValueCallCount = 0; headers.TryAddWithoutValidation(knownHeader, rawPrefix + "\rvalid"); headers.TryAddWithoutValidation(knownHeader, invalidHeaderValue + "\r\n"); headers.TryAddWithoutValidation(knownHeader, rawPrefix + "\n," + invalidHeaderValue + "\r\nother"); Assert.Equal(1, headers.Count()); Assert.Equal(1, headers.First().Value.Count()); Assert.Equal(parsedPrefix + "\rvalid", headers.First().Value.First()); Assert.Equal(4, headers.Parser.TryParseValueCallCount); headers.Clear(); headers.TryAddWithoutValidation("custom", "value\r\ninvalid"); headers.TryAddWithoutValidation("custom", "value\r\n valid"); headers.TryAddWithoutValidation("custom", "validvalue, invalid\r\nvalue"); Assert.Equal(1, headers.Count()); Assert.Equal(1, headers.First().Value.Count()); Assert.Equal("value\r\n valid", headers.First().Value.First()); }
public void Add_MultipleAddValidValueThenAddInvalidValuesToNonExistingHeader_ThrowAndDontAddHeader() { MockHeaders headers = new MockHeaders(); Assert.Throws<FormatException>(() => { headers.Add(knownHeader, new string[] { rawPrefix + "1", invalidHeaderValue }); }); // Make sure the header got added due to the valid add. Note that the first value in the array // is valid, so it gets added. Assert.True(headers.Contains(knownHeader), "Header was not added even though we added 1 valid value."); Assert.Equal(1, headers.First().Value.Count()); Assert.Equal(parsedPrefix + "1", headers.First().Value.ElementAt(0)); }
public void AddParsedValue_UseDifferentAddMethods_AllValuesAddedCorrectly() { MockHeaders headers = new MockHeaders(); headers.Add(knownHeader, rawPrefix + "1"); headers.TryAddWithoutValidation(knownHeader, rawPrefix + "2"); Assert.Equal(1, headers.Parser.TryParseValueCallCount); headers.AddParsedValue(knownHeader, parsedPrefix + "3"); // Adding a parsed value, will trigger all raw values to be parsed. Assert.Equal(2, headers.Parser.TryParseValueCallCount); Assert.Equal(3, headers.GetValues(knownHeader).Count()); Assert.Equal(parsedPrefix + "1", headers.First().Value.ElementAt(0)); Assert.Equal(parsedPrefix + "2", headers.First().Value.ElementAt(1)); Assert.Equal(parsedPrefix + "3", headers.First().Value.ElementAt(2)); }
public void TryAddWithoutValidation_AddTwoValuesOneValidOneInvalidAsOneString_RawStringAddedAsInvalid() { MockHeaders headers = new MockHeaders(); headers.TryAddWithoutValidation(knownHeader, rawPrefix + "1," + invalidHeaderValue); Assert.Equal(0, headers.Parser.TryParseValueCallCount); Assert.Equal(1, headers.Count()); Assert.Equal(1, headers.First().Value.Count()); // We expect the value to be returned without change since it couldn't be parsed in its entirety. Assert.Equal(rawPrefix + "1," + invalidHeaderValue, headers.First().Value.ElementAt(0)); // The parser gets called twice, but the second time it returns false, because it tries to parse // 'invalidHeaderValue'. Assert.Equal(2, headers.Parser.TryParseValueCallCount); }
public void Add_SingleAddCustomHeaderWithNullValue_HeaderIsAddedWithEmptyStringValue() { MockHeaders headers = new MockHeaders(); headers.Add(customHeader, (string)null); Assert.Equal(0, headers.Parser.TryParseValueCallCount); Assert.Equal(1, headers.Count()); Assert.Equal(1, headers.First().Value.Count()); Assert.Equal(string.Empty, headers.First().Value.ElementAt(0)); // We're using a custom header. No parsing should be triggered. Assert.Equal(0, headers.Parser.TryParseValueCallCount); }
public void Add_SingleFirstAddThenTryAddWithoutValidationToSingleValueHeader_BothParsedAndInvalidValue() { MockHeaderParser parser = new MockHeaderParser(false); // doesn't support multiple values. MockHeaders headers = new MockHeaders(parser); headers.Add(knownHeader, rawPrefix + "1"); headers.TryAddWithoutValidation(knownHeader, rawPrefix + "2"); Assert.Equal(1, headers.Parser.TryParseValueCallCount); // Add() succeeds since we don't have a value added yet. TryAddWithoutValidation() also succeeds, however // the value is added to the 'invalid values' list when retrieved. Assert.Equal(1, headers.Count()); Assert.Equal(2, headers.First().Value.Count()); Assert.Equal(parsedPrefix + "1", headers.First().Value.ElementAt(0)); Assert.Equal(rawPrefix + "2", headers.First().Value.ElementAt(1)); // Note that TryParseValue() is not called because HttpHeaders sees that there is already a value // so it adds the raw value to 'invalid values'. Assert.Equal(1, headers.Parser.TryParseValueCallCount); }
public void Add_SingleAddTwoValidValuesToHeaderWithSingleValue_Throw() { MockHeaderParser parser = new MockHeaderParser(false); // doesn't support multiple values. MockHeaders headers = new MockHeaders(parser); try { headers.Add(knownHeader, rawPrefix + "1"); } catch (Exception e) { Assert.True(false, string.Format("Adding the first header already threw exception: {0}", e)); } Assert.Throws<FormatException>(() => { headers.Add(knownHeader, rawPrefix + "2"); }); // Verify that the first header value is still there. Assert.Equal(1, headers.First().Value.Count()); }
public void Add_SingleFirstAddThenTryAddWithoutValidation_TwoParsedValuesAdded() { MockHeaders headers = new MockHeaders(); headers.Add(knownHeader, rawPrefix + "1"); headers.TryAddWithoutValidation(knownHeader, rawPrefix + "2"); // Add() should trigger parsing. Since TryAddWithoutValidation() is called afterwards the second value is // not parsed yet. Assert.Equal(1, headers.Parser.TryParseValueCallCount); Assert.Equal(1, headers.Count()); Assert.Equal(2, headers.First().Value.Count()); Assert.Equal(parsedPrefix + "1", headers.First().Value.ElementAt(0)); Assert.Equal(parsedPrefix + "2", headers.First().Value.ElementAt(1)); // Value is already parsed. There shouldn't be additional calls to the parser. Assert.Equal(2, headers.Parser.TryParseValueCallCount); }
public void TryAddWithoutValidation_AddMultipleValueToSingleValueHeaders_FirstHeaderAddedOthersAreInvalid() { MockHeaderParser parser = new MockHeaderParser(false); // doesn't support multiple values. MockHeaders headers = new MockHeaders(parser); headers.TryAddWithoutValidation(knownHeader, rawPrefix + "1"); headers.TryAddWithoutValidation(knownHeader, rawPrefix + "2"); Assert.Equal(0, headers.Parser.TryParseValueCallCount); Assert.Equal(1, headers.Count()); Assert.Equal(2, headers.First().Value.Count()); // Note that the first value was parsed and added to the 'parsed values' list. The second value however // was added to the 'invalid values' list since the header doesn't support multiple values. Assert.Equal(parsedPrefix + "1", headers.First().Value.ElementAt(0)); Assert.Equal(rawPrefix + "2", headers.First().Value.ElementAt(1)); // The parser is only called once for the first value. HttpHeaders doesn't invoke the parser for // additional values if the parser only supports one value. Assert.Equal(1, headers.Parser.TryParseValueCallCount); }
public void TryAddWithoutValidation_AddMultipleValueStringToSingleValueHeaders_MultipleValueStringAddedAsInvalid() { MockHeaderParser parser = new MockHeaderParser(false); // doesn't support multiple values. MockHeaders headers = new MockHeaders(parser); headers.TryAddWithoutValidation(knownHeader, rawPrefix + "1," + rawPrefix + "2"); Assert.Equal(0, headers.Parser.TryParseValueCallCount); // Since parsing the header value fails because it is composed of 2 values, the original string is added // to the list of 'invalid values'. Therefore we only have 1 header value (the original string). Assert.Equal(1, headers.Count()); Assert.Equal(1, headers.First().Value.Count()); Assert.Equal(rawPrefix + "1," + rawPrefix + "2", headers.First().Value.First()); Assert.Equal(1, headers.Parser.TryParseValueCallCount); }
public void TryAddWithoutValidation_AddNullAndEmptyValuesToUnknownHeader_TwoEmptyStringsAddedAsValues() { MockHeaders headers = new MockHeaders(); headers.TryAddWithoutValidation(customHeader, (string)null); headers.TryAddWithoutValidation(customHeader, string.Empty); Assert.Equal(1, headers.Count()); Assert.Equal(2, headers.First().Value.Count()); // TryAddWithoutValidation() adds 'null' as string.empty to distinguish between an empty raw value and no raw // value. For custom headers we just add what the user gives us. I.e. the result is a header with two empty // values. Assert.Equal(string.Empty, headers.First().Value.ElementAt(0)); Assert.Equal(string.Empty, headers.First().Value.ElementAt(1)); }
public void TryAddWithoutValidation_AddValueForUnknownHeader_ValueAddedToStore() { MockHeaders headers = new MockHeaders(); headers.TryAddWithoutValidation(customHeader, "custom value"); Assert.Equal(1, headers.Count()); Assert.Equal(1, headers.First().Value.Count()); Assert.Equal("custom value", headers.First().Value.First()); Assert.Equal(0, headers.Parser.TryParseValueCallCount); }
public void TryAddWithoutValidation_AddNullValueForUnknownHeader_EmptyStringAddedAsValue() { MockHeaders headers = new MockHeaders(); headers.TryAddWithoutValidation(customHeader, (string)null); Assert.Equal(1, headers.Count()); Assert.Equal(1, headers.First().Value.Count()); // 'null' values are internally stored as string.Empty. Since we added a custom header, there is no // parser and the empty string is just added to the list of 'parsed values'. Assert.Equal(string.Empty, headers.First().Value.First()); Assert.Equal(0, headers.Parser.TryParseValueCallCount); }
public void SetParsedValue_SetValueAfterAddingMultipleValues_SetValueReplacesOtherValues() { MockHeaders headers = new MockHeaders(); headers.Add(knownHeader, rawPrefix + "1"); headers.TryAddWithoutValidation(knownHeader, rawPrefix + "2"); Assert.Equal(1, headers.Parser.TryParseValueCallCount); headers.SetParsedValue(knownHeader, parsedPrefix + "3"); // Adding a parsed value, will trigger all raw values to be parsed. Assert.Equal(2, headers.Parser.TryParseValueCallCount); Assert.Equal(1, headers.GetValues(knownHeader).Count()); Assert.Equal(parsedPrefix + "3", headers.First().Value.ElementAt(0)); }
public void TryAddWithoutValidation_AddValidAndInvalidValueString_BothValuesParsed() { MockHeaders headers = new MockHeaders(); headers.TryAddWithoutValidation(knownHeader, invalidHeaderValue); headers.TryAddWithoutValidation(knownHeader, rawPrefix); Assert.Equal(0, headers.Parser.TryParseValueCallCount); Assert.Equal(1, headers.Count()); Assert.Equal(2, headers.First().Value.Count()); // If you compare this test with the previous one: Note that we reversed the order of adding the invalid // string and the valid string. However, when enumerating header values the order is still the same as in // the previous test. // We don't keep track of the order if we have both invalid & valid values. This would add complexity // and additional memory to store the information. Given how rare this scenario is we consider this // by design. Note that this scenario is only an issue if: // - The header value has an invalid format (very rare for standard headers) AND // - There are multiple header values (some valid, some invalid) AND // - The order of the headers matters (e.g. Transfer-Encoding) Assert.Equal(parsedPrefix, headers.First().Value.ElementAt(0)); Assert.Equal(invalidHeaderValue, headers.First().Value.ElementAt(1)); Assert.Equal(2, headers.Parser.TryParseValueCallCount); string expected = knownHeader + ": " + parsedPrefix + ", " + invalidHeaderValue + "\r\n"; Assert.Equal(expected, headers.ToString()); }
public void Add_SingleFirstTryAddWithoutValidationForEmptyValueThenAdd_OneParsedValueAddedEmptyIgnored() { MockHeaders headers = new MockHeaders(); headers.TryAddWithoutValidation(knownHeader, string.Empty); headers.Add(knownHeader, rawPrefix + "1"); // Add() should trigger parsing. TryAddWithoutValidation() doesn't trigger parsing, but Add() triggers // parsing of raw header values (TryParseValue() is called) Assert.Equal(2, headers.Parser.TryParseValueCallCount); Assert.Equal(1, headers.Count()); Assert.Equal(1, headers.First().Value.Count()); Assert.Equal(parsedPrefix + "1", headers.First().Value.ElementAt(0)); // Value is already parsed. There shouldn't be additional calls to the parser. Assert.Equal(2, headers.Parser.TryParseValueCallCount); }
public void TryAddWithoutValidation_MultipleAddInvalidValuesToNonExistingHeader_AddHeader() { MockHeaders headers = new MockHeaders(); headers.TryAddWithoutValidation(knownHeader, new string[] { invalidHeaderValue }); // Make sure the header did not get added since we just tried to add an invalid value. Assert.True(headers.Contains(knownHeader)); Assert.Equal(1, headers.First().Value.Count()); Assert.Equal(invalidHeaderValue, headers.First().Value.ElementAt(0)); }
public void Add_SingleAddThenTryAddWithoutValidationThenAdd_ThreeParsedValuesAdded() { MockHeaders headers = new MockHeaders(); headers.Add(knownHeader, rawPrefix + "1"); headers.TryAddWithoutValidation(knownHeader, rawPrefix + "2"); headers.Add(knownHeader, rawPrefix + "3"); // The second Add() triggers also parsing of the value added by TryAddWithoutValidation() Assert.Equal(3, headers.Parser.TryParseValueCallCount); Assert.Equal(1, headers.Count()); Assert.Equal(3, headers.First().Value.Count()); Assert.Equal(parsedPrefix + "1", headers.First().Value.ElementAt(0)); Assert.Equal(parsedPrefix + "2", headers.First().Value.ElementAt(1)); Assert.Equal(parsedPrefix + "3", headers.First().Value.ElementAt(2)); // Value is already parsed. There shouldn't be additional calls to the parser. Assert.Equal(3, headers.Parser.TryParseValueCallCount); }
public void TryAddWithoutValidation_MultipleAddValidValueThenAddInvalidValuesToNonExistingHeader_AddHeader() { MockHeaders headers = new MockHeaders(); headers.TryAddWithoutValidation(knownHeader, new string[] { rawPrefix + "1", invalidHeaderValue }); Assert.True(headers.Contains(knownHeader)); Assert.Equal(2, headers.First().Value.Count()); Assert.Equal(parsedPrefix + "1", headers.First().Value.ElementAt(0)); Assert.Equal(invalidHeaderValue, headers.First().Value.ElementAt(1)); }
public void Add_MultipleAddThreeValidValuesWithOneCall_ValuesParsedCorrectly() { MockHeaders headers = new MockHeaders(); string[] values = new string[] { rawPrefix + "1", rawPrefix + "2", rawPrefix + "3" }; headers.Add(knownHeader, values); // Add() should trigger parsing. Assert.Equal(3, headers.Parser.TryParseValueCallCount); Assert.Equal(1, headers.Count()); Assert.Equal(3, headers.First().Value.Count()); Assert.Equal(parsedPrefix + "1", headers.First().Value.ElementAt(0)); Assert.Equal(parsedPrefix + "2", headers.First().Value.ElementAt(1)); Assert.Equal(parsedPrefix + "3", headers.First().Value.ElementAt(2)); // Value is already parsed. There shouldn't be additional calls to the parser. Assert.Equal(3, headers.Parser.TryParseValueCallCount); }
public void Add_SingleAddValidValue_ValueParsedCorrectly() { MockHeaders headers = new MockHeaders(); headers.Add(knownHeader, rawPrefix); // Add() should trigger parsing. Assert.Equal(1, headers.Parser.TryParseValueCallCount); Assert.Equal(1, headers.Count()); Assert.Equal(1, headers.First().Value.Count()); Assert.Equal(parsedPrefix, headers.First().Value.ElementAt(0)); // Value is already parsed. There shouldn't be additional calls to the parser. Assert.Equal(1, headers.Parser.TryParseValueCallCount); }
public void Add_MultipleAddThreeValidValuesAsOneString_BothValuesParsed() { MockHeaders headers = new MockHeaders(); headers.Add(knownHeader, rawPrefix + "1," + rawPrefix + "2," + rawPrefix + "3"); Assert.Equal(3, headers.Parser.TryParseValueCallCount); Assert.Equal(1, headers.Count()); Assert.Equal(3, headers.First().Value.Count()); Assert.Equal(parsedPrefix + "1", headers.First().Value.ElementAt(0)); Assert.Equal(parsedPrefix + "2", headers.First().Value.ElementAt(1)); Assert.Equal(parsedPrefix + "3", headers.First().Value.ElementAt(2)); }
public void Add_SingleAddValidValueThenAddInvalidValue_ThrowAndHeaderContainsValidValue() { MockHeaders headers = new MockHeaders(); headers.Add(knownHeader, rawPrefix); Assert.Throws<FormatException>(() => { headers.Add(knownHeader, invalidHeaderValue); }); // Make sure the header did not get removed due to the failed add. Assert.True(headers.Contains(knownHeader), "Header was removed even if there is a valid header value."); Assert.Equal(1, headers.First().Value.Count()); Assert.Equal(parsedPrefix, headers.First().Value.ElementAt(0)); }
public void Add_AddValueContainingNewLine_NewLineFollowedByWhitespaceIsOKButNewLineFollowedByNonWhitespaceIsRejected() { MockHeaders headers = new MockHeaders(); headers.Clear(); headers.Add("custom", "value\r"); Assert.Equal(1, headers.Count()); Assert.Equal(1, headers.First().Value.Count()); Assert.Equal("value\r", headers.First().Value.First()); headers.Clear(); Assert.Throws<FormatException>(() => { headers.Add("custom", new string[] { "valid\n", "invalid\r\nother" }); }); Assert.Equal(1, headers.Count()); Assert.Equal(1, headers.First().Value.Count()); Assert.Equal("valid\n", headers.First().Value.First()); }
public void Add_MultipleAddValidValueThenAddInvalidValuesToExistingHeader_ThrowAndDontAddHeader() { MockHeaders headers = new MockHeaders(); headers.Add(knownHeader, rawPrefix + "1"); Assert.Throws<FormatException>(() => { headers.Add(knownHeader, new string[] { rawPrefix + "2", invalidHeaderValue }); }); // Make sure the header did not get removed due to the failed add. Note that the first value in the array // is valid, so it gets added. I.e. we have 2 values. Assert.True(headers.Contains(knownHeader), "Header was removed even if there is a valid header value."); Assert.Equal(2, headers.First().Value.Count()); Assert.Equal(parsedPrefix + "1", headers.First().Value.ElementAt(0)); Assert.Equal(parsedPrefix + "2", headers.First().Value.ElementAt(1)); }
public void RemoveParsedValue_AddTwoValuesAndRemoveSecondOne_FirstValueRemains() { MockHeaders headers = new MockHeaders(); headers.Add(knownHeader, rawPrefix + "1"); headers.Add(knownHeader, rawPrefix + "2"); // Remove the parsed value (note the original string 'raw2' was "parsed" to 'parsed2') Assert.True(headers.RemoveParsedValue(knownHeader, parsedPrefix + "2")); Assert.Equal(2, headers.Parser.TryParseValueCallCount); // Note that when the last value of a header gets removed, the whole header gets removed. Assert.Equal(1, headers.Count()); Assert.Equal(1, headers.First().Value.Count()); Assert.Equal(parsedPrefix + "1", headers.First().Value.ElementAt(0)); Assert.Equal(2, headers.Parser.TryParseValueCallCount); }
public void TryAddWithoutValidation_AddEmptyValueString_HeaderWithNoValueAfterParsing() { MockHeaders headers = new MockHeaders(); // The parser returns 'true' to indicate that it could parse the value (empty values allowed) and an // value of 'null'. HttpHeaders will remove the header from the collection since the known header doesn't // have a value. headers.TryAddWithoutValidation(knownHeader, string.Empty); Assert.Equal(0, headers.Parser.TryParseValueCallCount); Assert.Equal(0, headers.Count()); headers.Clear(); headers.TryAddWithoutValidation("custom", (string)null); Assert.Equal(1, headers.Count()); Assert.Equal(1, headers.First().Value.Count()); Assert.Equal(string.Empty, headers.GetValues("custom").First()); }