Skip to content

Commit

Permalink
Reduce the size of some Http header values (#83640)
Browse files Browse the repository at this point in the history
* Reduce the size of some Http header values

* PR feedback
  • Loading branch information
MihaZupan authored Mar 20, 2023
1 parent 850a320 commit 1f6fc66
Show file tree
Hide file tree
Showing 8 changed files with 292 additions and 508 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,16 @@

using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Text;

namespace System.Net.Http.Headers
{
public class ContentRangeHeaderValue : ICloneable
{
private string _unit = null!;
private long? _from;
private long? _to;
private long? _length;
private long _from;
private long _to;
private long _length;

public string Unit
{
Expand All @@ -26,30 +24,15 @@ public string Unit
}
}

public long? From
{
get { return _from; }
}
public long? From => HasRange ? _from : null;

public long? To
{
get { return _to; }
}
public long? To => HasRange ? _to : null;

public long? Length
{
get { return _length; }
}
public long? Length => HasLength ? _length : null;

public bool HasLength // e.g. "Content-Range: bytes 12-34/*"
{
get { return _length != null; }
}
public bool HasLength => _length >= 0; // e.g. "Content-Range: bytes 12-34/*"

public bool HasRange // e.g. "Content-Range: bytes */1234"
{
get { return _from != null; }
}
public bool HasRange => _from >= 0; // e.g. "Content-Range: bytes */1234"

public ContentRangeHeaderValue(long from, long to, long length)
{
Expand All @@ -75,6 +58,7 @@ public ContentRangeHeaderValue(long length)

_length = length;
_unit = HeaderUtilities.BytesUnit;
_from = -1;
}

public ContentRangeHeaderValue(long from, long to)
Expand All @@ -88,10 +72,13 @@ public ContentRangeHeaderValue(long from, long to)
_from = from;
_to = to;
_unit = HeaderUtilities.BytesUnit;
_length = -1;
}

private ContentRangeHeaderValue()
{
_from = -1;
_length = -1;
}

private ContentRangeHeaderValue(ContentRangeHeaderValue source)
Expand All @@ -104,35 +91,19 @@ private ContentRangeHeaderValue(ContentRangeHeaderValue source)
_unit = source._unit;
}

public override bool Equals([NotNullWhen(true)] object? obj)
{
ContentRangeHeaderValue? other = obj as ContentRangeHeaderValue;

if (other == null)
{
return false;
}

return ((_from == other._from) && (_to == other._to) && (_length == other._length) &&
string.Equals(_unit, other._unit, StringComparison.OrdinalIgnoreCase));
}

public override int GetHashCode()
{
int result = StringComparer.OrdinalIgnoreCase.GetHashCode(_unit);

if (HasRange)
{
result = result ^ _from.GetHashCode() ^ _to.GetHashCode();
}

if (HasLength)
{
result ^= _length.GetHashCode();
}
public override bool Equals([NotNullWhen(true)] object? obj) =>
obj is ContentRangeHeaderValue other &&
_from == other._from &&
_to == other._to &&
_length == other._length &&
string.Equals(_unit, other._unit, StringComparison.OrdinalIgnoreCase);

return result;
}
public override int GetHashCode() =>
HashCode.Combine(
StringComparer.OrdinalIgnoreCase.GetHashCode(_unit),
_from,
_to,
_length);

public override string ToString()
{
Expand All @@ -142,10 +113,9 @@ public override string ToString()

if (HasRange)
{
sb.AppendSpanFormattable(_from!.Value);
sb.AppendSpanFormattable(_from);
sb.Append('-');
Debug.Assert(_to.HasValue);
sb.AppendSpanFormattable(_to.Value);
sb.AppendSpanFormattable(_to);
}
else
{
Expand All @@ -155,7 +125,7 @@ public override string ToString()
sb.Append('/');
if (HasLength)
{
sb.AppendSpanFormattable(_length!.Value);
sb.AppendSpanFormattable(_length);
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,13 @@ namespace System.Net.Http.Headers
{
public class RangeConditionHeaderValue : ICloneable
{
private readonly DateTimeOffset? _date;
// Exactly one of date and entityTag will be set.
private readonly DateTimeOffset _date;
private readonly EntityTagHeaderValue? _entityTag;

public DateTimeOffset? Date
{
get { return _date; }
}
public DateTimeOffset? Date => _entityTag is null ? _date : null;

public EntityTagHeaderValue? EntityTag
{
get { return _entityTag; }
}
public EntityTagHeaderValue? EntityTag => _entityTag;

public RangeConditionHeaderValue(DateTimeOffset date)
{
Expand All @@ -46,45 +41,14 @@ private RangeConditionHeaderValue(RangeConditionHeaderValue source)
_date = source._date;
}

public override string ToString()
{
if (_entityTag == null)
{
Debug.Assert(_date != null);
return _date.GetValueOrDefault().ToString("r");
}

return _entityTag.ToString();
}
public override string ToString() => _entityTag?.ToString() ?? _date.ToString("r");

public override bool Equals([NotNullWhen(true)] object? obj)
{
RangeConditionHeaderValue? other = obj as RangeConditionHeaderValue;
public override bool Equals([NotNullWhen(true)] object? obj) =>
obj is RangeConditionHeaderValue other &&
(_entityTag is null ? other._entityTag is null : _entityTag.Equals(other._entityTag)) &&
_date == other._date;

if (other == null)
{
return false;
}

if (_entityTag == null)
{
Debug.Assert(_date != null);
return (other._date != null) && (_date.Value == other._date.Value);
}

return _entityTag.Equals(other._entityTag);
}

public override int GetHashCode()
{
if (_entityTag == null)
{
Debug.Assert(_date != null);
return _date.Value.GetHashCode();
}

return _entityTag.GetHashCode();
}
public override int GetHashCode() => _entityTag?.GetHashCode() ?? _date.GetHashCode();

public static RangeConditionHeaderValue Parse(string input)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,13 @@ namespace System.Net.Http.Headers
{
public class RangeItemHeaderValue : ICloneable
{
private readonly long? _from;
private readonly long? _to;
// Set to -1 if not set.
private readonly long _from;
private readonly long _to;

public long? From
{
get { return _from; }
}
public long? From => _from >= 0 ? _from : null;

public long? To
{
get { return _to; }
}
public long? To => _to >= 0 ? _to : null;

public RangeItemHeaderValue(long? from, long? to)
{
Expand All @@ -42,8 +37,8 @@ public RangeItemHeaderValue(long? from, long? to)
ArgumentOutOfRangeException.ThrowIfGreaterThan(from.GetValueOrDefault(), to.GetValueOrDefault(), nameof(from));
}

_from = from;
_to = to;
_from = from ?? -1;
_to = to ?? -1;
}

internal RangeItemHeaderValue(RangeItemHeaderValue source)
Expand All @@ -58,43 +53,26 @@ public override string ToString()
{
Span<char> stackBuffer = stackalloc char[128];

if (!_from.HasValue)
if (_from < 0)
{
Debug.Assert(_to != null);
return string.Create(CultureInfo.InvariantCulture, stackBuffer, $"-{_to.Value}");
return string.Create(CultureInfo.InvariantCulture, stackBuffer, $"-{_to}");
}

if (!_to.HasValue)
if (_to < 0)
{
return string.Create(CultureInfo.InvariantCulture, stackBuffer, $"{_from.Value}-"); ;
return string.Create(CultureInfo.InvariantCulture, stackBuffer, $"{_from}-"); ;
}

return string.Create(CultureInfo.InvariantCulture, stackBuffer, $"{_from.Value}-{_to.Value}");
return string.Create(CultureInfo.InvariantCulture, stackBuffer, $"{_from}-{_to}");
}

public override bool Equals([NotNullWhen(true)] object? obj)
{
RangeItemHeaderValue? other = obj as RangeItemHeaderValue;
public override bool Equals([NotNullWhen(true)] object? obj) =>
obj is RangeItemHeaderValue other &&
_from == other._from &&
_to == other._to;

if (other == null)
{
return false;
}
return ((_from == other._from) && (_to == other._to));
}

public override int GetHashCode()
{
if (!_from.HasValue)
{
return _to.GetHashCode();
}
else if (!_to.HasValue)
{
return _from.GetHashCode();
}
return _from.GetHashCode() ^ _to.GetHashCode();
}
public override int GetHashCode() =>
HashCode.Combine(_from, _to);

// Returns the length of a range list. E.g. "1-2, 3-4, 5-6" adds 3 ranges to 'rangeCollection'. Note that empty
// list segments are allowed, e.g. ",1-2, , 3-4,,".
Expand All @@ -118,10 +96,9 @@ internal static int GetRangeItemListLength(string? input, int startIndex,
return 0;
}

RangeItemHeaderValue? range;
while (true)
{
int rangeLength = GetRangeItemLength(input, current, out range);
int rangeLength = GetRangeItemLength(input, current, out RangeItemHeaderValue? range);

if (rangeLength == 0)
{
Expand Down Expand Up @@ -227,8 +204,7 @@ internal static int GetRangeItemLength(string? input, int startIndex, out RangeI
return 0;
}

parsedValue = new RangeItemHeaderValue((fromLength == 0 ? (long?)null : (long?)from),
(toLength == 0 ? (long?)null : (long?)to));
parsedValue = new RangeItemHeaderValue((fromLength == 0 ? null : from), (toLength == 0 ? null : to));
return current - startIndex;
}

Expand Down
Loading

0 comments on commit 1f6fc66

Please sign in to comment.