Skip to content

Commit

Permalink
Fix method HttpHeadersNonValidated uses to get HeaderDescriptor (#62194)
Browse files Browse the repository at this point in the history
We have two non-public methods for getting a HeaderDescriptor from a string name, one static on HeaderDescriptor and one instance on HttpHeaders.  HttpHeadersNonValidated was using the former, but this then doesn't take into account custom logic used by HttpHeaders in other methods, like TryAddWithoutValidation, which means some methods on HttpHeadersNonValidated can't find the corresponding headers.

Co-authored-by: Stephen Toub <stoub@microsoft.com>
  • Loading branch information
github-actions[bot] and stephentoub authored Dec 15, 2021
1 parent a4f5b78 commit 24a7935
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1051,7 +1051,7 @@ private HeaderDescriptor GetHeaderDescriptor(string name)
throw new InvalidOperationException(SR.Format(SR.net_http_headers_not_allowed_header_name, name));
}

private bool TryGetHeaderDescriptor(string name, out HeaderDescriptor descriptor)
internal bool TryGetHeaderDescriptor(string name, out HeaderDescriptor descriptor)
{
if (string.IsNullOrEmpty(name))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ namespace System.Net.Http.Headers
/// <returns>true if the collection contains the header; otherwise, false.</returns>
public bool Contains(string headerName) =>
_headers is HttpHeaders headers &&
HeaderDescriptor.TryGet(headerName, out HeaderDescriptor descriptor) &&
headers.TryGetHeaderDescriptor(headerName, out HeaderDescriptor descriptor) &&
headers.TryGetHeaderValue(descriptor, out _);

/// <summary>Gets the values for the specified header name.</summary>
Expand Down Expand Up @@ -62,7 +62,7 @@ public HeaderStringValues this[string headerName]
public bool TryGetValues(string headerName, out HeaderStringValues values)
{
if (_headers is HttpHeaders headers &&
HeaderDescriptor.TryGet(headerName, out HeaderDescriptor descriptor) &&
headers.TryGetHeaderDescriptor(headerName, out HeaderDescriptor descriptor) &&
headers.TryGetHeaderValue(descriptor, out object? info))
{
HttpHeaders.GetStoreValuesAsStringOrStringArray(descriptor, info, out string? singleValue, out string[]? multiValue);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2112,6 +2112,44 @@ public void AddHeaders_SourceHasInvalidHeaderValues_InvalidHeadersRemovedFromSou
Assert.False(destination.Contains("custom"), "destination contains 'custom' header.");
}

[Fact]
public void AddHeaders_ResponseHeaderToRequestHeaders_Success()
{
const string Name = "WWW-Authenticate";
const string Value = "Basic realm=\"Access to the staging site\", charset=\"UTF-8\"";

var request = new HttpRequestMessage();
Assert.True(request.Headers.TryAddWithoutValidation(Name, Value));

Assert.True(request.Headers.Contains(Name));
Assert.True(request.Headers.NonValidated.Contains(Name));

Assert.True(request.Headers.TryGetValues(Name, out IEnumerable<string> values));
Assert.Equal(Value, values.Single());

Assert.True(request.Headers.NonValidated.TryGetValues(Name, out HeaderStringValues nvValues));
Assert.Equal(Value, nvValues.Single());
}

[Fact]
public void AddHeaders_RequestHeaderToResponseHeaders_Success()
{
const string Name = "Referer";
const string Value = "https://dot.net";

var response = new HttpResponseMessage();
Assert.True(response.Headers.TryAddWithoutValidation(Name, Value));

Assert.True(response.Headers.Contains(Name));
Assert.True(response.Headers.NonValidated.Contains(Name));

Assert.True(response.Headers.TryGetValues(Name, out IEnumerable<string> values));
Assert.Equal(Value, values.Single());

Assert.True(response.Headers.NonValidated.TryGetValues(Name, out HeaderStringValues nvValues));
Assert.Equal(Value, nvValues.Single());
}

[Fact]
public void HeaderStringValues_Default_Empty()
{
Expand Down

0 comments on commit 24a7935

Please sign in to comment.