Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add HttpHeaders.NonValidated #53555

Merged
merged 1 commit into from
Jun 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions src/libraries/System.Net.Http/ref/System.Net.Http.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
// Changes to this file must follow the https://aka.ms/api-review process.
// ------------------------------------------------------------------------------

using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;

namespace System.Net.Http
Expand Down Expand Up @@ -520,6 +521,26 @@ public EntityTagHeaderValue(string tag, bool isWeak) { }
public override string ToString() { throw null; }
public static bool TryParse([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] string? input, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Net.Http.Headers.EntityTagHeaderValue? parsedValue) { throw null; }
}
public readonly partial struct HeaderStringValues : System.Collections.Generic.IEnumerable<string>, System.Collections.Generic.IReadOnlyCollection<string>, System.Collections.IEnumerable
{
private readonly object _dummy;
private readonly int _dummyPrimitive;
public int Count { get { throw null; } }
public System.Net.Http.Headers.HeaderStringValues.Enumerator GetEnumerator() { throw null; }
System.Collections.Generic.IEnumerator<string> System.Collections.Generic.IEnumerable<string>.GetEnumerator() { throw null; }
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
public override string ToString() { throw null; }
public partial struct Enumerator : System.Collections.Generic.IEnumerator<string>, System.Collections.IEnumerator, System.IDisposable
{
private object _dummy;
private int _dummyPrimitive;
public string Current { get { throw null; } }
object System.Collections.IEnumerator.Current { get { throw null; } }
public void Dispose() { }
public bool MoveNext() { throw null; }
void System.Collections.IEnumerator.Reset() { }
}
}
public sealed partial class HttpContentHeaders : System.Net.Http.Headers.HttpHeaders
{
internal HttpContentHeaders() { }
Expand All @@ -538,6 +559,7 @@ internal HttpContentHeaders() { }
public abstract partial class HttpHeaders : System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, System.Collections.Generic.IEnumerable<string>>>, System.Collections.IEnumerable
{
protected HttpHeaders() { }
public System.Net.Http.Headers.HttpHeadersNonValidated NonValidated { get { throw null; } }
public void Add(string name, System.Collections.Generic.IEnumerable<string?> values) { }
public void Add(string name, string? value) { }
public void Clear() { }
Expand All @@ -551,6 +573,32 @@ public void Clear() { }
public bool TryAddWithoutValidation(string name, string? value) { throw null; }
public bool TryGetValues(string name, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Collections.Generic.IEnumerable<string>? values) { throw null; }
}
public readonly partial struct HttpHeadersNonValidated : System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, System.Net.Http.Headers.HeaderStringValues>>, System.Collections.Generic.IReadOnlyCollection<System.Collections.Generic.KeyValuePair<string, System.Net.Http.Headers.HeaderStringValues>>, System.Collections.Generic.IReadOnlyDictionary<string, System.Net.Http.Headers.HeaderStringValues>, System.Collections.IEnumerable
{
private readonly object _dummy;
private readonly int _dummyPrimitive;
public int Count { get { throw null; } }
public System.Net.Http.Headers.HeaderStringValues this[string headerName] { get { throw null; } }
System.Collections.Generic.IEnumerable<string> System.Collections.Generic.IReadOnlyDictionary<string, System.Net.Http.Headers.HeaderStringValues>.Keys { get { throw null; } }
System.Collections.Generic.IEnumerable<System.Net.Http.Headers.HeaderStringValues> System.Collections.Generic.IReadOnlyDictionary<string, System.Net.Http.Headers.HeaderStringValues>.Values { get { throw null; } }
public bool Contains(string headerName) { throw null; }
bool System.Collections.Generic.IReadOnlyDictionary<string, System.Net.Http.Headers.HeaderStringValues>.ContainsKey(string key) { throw null; }
public System.Net.Http.Headers.HttpHeadersNonValidated.Enumerator GetEnumerator() { throw null; }
System.Collections.Generic.IEnumerator<System.Collections.Generic.KeyValuePair<string, System.Net.Http.Headers.HeaderStringValues>> System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, System.Net.Http.Headers.HeaderStringValues>>.GetEnumerator() { throw null; }
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
public bool TryGetValues(string headerName, out System.Net.Http.Headers.HeaderStringValues values) { throw null; }
bool System.Collections.Generic.IReadOnlyDictionary<string, System.Net.Http.Headers.HeaderStringValues>.TryGetValue(string key, out System.Net.Http.Headers.HeaderStringValues value) { throw null; }
public partial struct Enumerator : System.Collections.Generic.IEnumerator<System.Collections.Generic.KeyValuePair<string, System.Net.Http.Headers.HeaderStringValues>>, System.Collections.IEnumerator, System.IDisposable
{
private object _dummy;
private int _dummyPrimitive;
public System.Collections.Generic.KeyValuePair<string, System.Net.Http.Headers.HeaderStringValues> Current { get { throw null; } }
object System.Collections.IEnumerator.Current { get { throw null; } }
public void Dispose() { }
public bool MoveNext() { throw null; }
void System.Collections.IEnumerator.Reset() { }
}
}
public sealed partial class HttpHeaderValueCollection<T> : System.Collections.Generic.ICollection<T>, System.Collections.Generic.IEnumerable<T>, System.Collections.IEnumerable where T : class
{
internal HttpHeaderValueCollection() { }
Expand Down
2 changes: 2 additions & 0 deletions src/libraries/System.Net.Http/src/System.Net.Http.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,13 @@
<Compile Include="System\Net\Http\Headers\EntityTagHeaderValue.cs" />
<Compile Include="System\Net\Http\Headers\GenericHeaderParser.cs" />
<Compile Include="System\Net\Http\Headers\HeaderDescriptor.cs" />
<Compile Include="System\Net\Http\Headers\HeaderStringValues.cs" />
<Compile Include="System\Net\Http\Headers\HeaderUtilities.cs" />
<Compile Include="System\Net\Http\Headers\HttpContentHeaders.cs" />
<Compile Include="System\Net\Http\Headers\HttpGeneralHeaders.cs" />
<Compile Include="System\Net\Http\Headers\HttpHeaderParser.cs" />
<Compile Include="System\Net\Http\Headers\HttpHeaders.cs" />
<Compile Include="System\Net\Http\Headers\HttpHeadersNonValidated.cs" />
<Compile Include="System\Net\Http\Headers\HttpHeaderValueCollection.cs" />
<Compile Include="System\Net\Http\Headers\HttpRequestHeaders.cs" />
<Compile Include="System\Net\Http\Headers\HttpResponseHeaders.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections;
using System.Collections.Generic;

namespace System.Net.Http.Headers
{
/// <summary>Provides a collection of header string values.</summary>
public readonly struct HeaderStringValues : IReadOnlyCollection<string>
{
/// <summary>The associated header. This is used only for producing a string from <see cref="_value"/> when it's an array.</summary>
private readonly HeaderDescriptor _header;
/// <summary>A string or string array (or null if the instance is default).</summary>
private readonly object _value;

/// <summary>Initializes the instance.</summary>
/// <param name="descriptor">The header descriptor associated with the header value.</param>
/// <param name="value">The header value.</param>
internal HeaderStringValues(HeaderDescriptor descriptor, string value)
{
_header = descriptor;
_value = value;
}

/// <summary>Initializes the instance.</summary>
/// <param name="descriptor">The header descriptor associated with the header values.</param>
/// <param name="values">The header values.</param>
internal HeaderStringValues(HeaderDescriptor descriptor, string[] values)
{
_header = descriptor;
_value = values;
}

/// <summary>Gets the number of header values in the collection.</summary>
public int Count => _value switch
{
string => 1,
string[] values => values.Length,
_ => 0
};

/// <summary>Gets a string containing all the headers in the collection.</summary>
/// <returns></returns>
public override string ToString() => _value switch
{
string value => value,
string[] values => string.Join(_header.Parser is HttpHeaderParser parser && parser.SupportsMultipleValues ? parser.Separator : HttpHeaderParser.DefaultSeparator, values),
_ => string.Empty,
};

/// <summary>Gets an enumerator for all of the strings in the collection.</summary>
/// <returns></returns>
public Enumerator GetEnumerator() => new Enumerator(_value);

/// <inheritdoc/>
IEnumerator<string> IEnumerable<string>.GetEnumerator() => GetEnumerator();

/// <inheritdoc/>
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();

/// <summary>Enumerates the elements of a <see cref="HeaderStringValues"/>.</summary>
public struct Enumerator : IEnumerator<string>
{
/// <summary>If this wraps a string[], that array. Otherwise, null.</summary>
private readonly string[]? _values;
/// <summary>The current string header value. If this wraps a single string, that string.</summary>
private string? _current;
/// <summary>Current state of the iteration.</summary>
private int _index;

/// <summary>Initializes the enumerator with a string or string[].</summary>
/// <param name="value">The string or string[] value, or null if this collection is empty.</param>
internal Enumerator(object value)
{
if (value is string s)
{
_values = null;
_current = s;
}
else
{
_values = value as string[];
_current = null;
}

_index = 0;
}

/// <inheritdoc/>
public bool MoveNext()
{
int index = _index;
if (index < 0)
{
return false;
}

string[]? values = _values;
if (values != null)
{
if ((uint)index < (uint)values.Length)
{
_index = index + 1;
_current = values[index];
return true;
}

_index = -1;
return false;
}

_index = -1;
return _current != null;
}

/// <inheritdoc/>
public string Current => _current!;

/// <inheritdoc/>
object IEnumerator.Current => Current;

/// <inheritdoc/>
public void Dispose() { }

/// <inheritdoc/>
void IEnumerator.Reset() => throw new NotSupportedException();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ internal static void DumpHeaders(StringBuilder sb, params HttpHeaders?[] headers
{
if (headers[i] is HttpHeaders hh)
{
foreach (KeyValuePair<string, string[]> header in hh.EnumerateWithoutValidation())
foreach (KeyValuePair<string, HeaderStringValues> header in hh.NonValidated)
{
foreach (string headerValue in header.Value)
{
Expand Down
Loading