This repository has been archived by the owner on Nov 22, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 72
/
Copy pathRangeHelpers.cs
59 lines (55 loc) · 2.19 KB
/
RangeHelpers.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using Microsoft.Net.Http.Headers;
namespace Microsoft.AspNetCore.StaticFiles.Infrastructure
{
internal static class RangeHelpers
{
// 14.35.1 Byte Ranges - If a syntactically valid byte-range-set includes at least one byte-range-spec whose
// first-byte-pos is less than the current length of the entity-body, or at least one suffix-byte-range-spec
// with a non-zero suffix-length, then the byte-range-set is satisfiable.
// Adjusts ranges to be absolute and within bounds.
internal static IList<RangeItemHeaderValue> NormalizeRanges(ICollection<RangeItemHeaderValue> ranges, long length)
{
IList<RangeItemHeaderValue> normalizedRanges = new List<RangeItemHeaderValue>(ranges.Count);
if (length == 0)
{
return normalizedRanges;
}
foreach (var range in ranges)
{
long? start = range.From;
long? end = range.To;
// X-[Y]
if (start.HasValue)
{
if (start.Value >= length)
{
// Not satisfiable, skip/discard.
continue;
}
if (!end.HasValue || end.Value >= length)
{
end = length - 1;
}
}
else
{
// suffix range "-X" e.g. the last X bytes, resolve
if (end.Value == 0)
{
// Not satisfiable, skip/discard.
continue;
}
long bytes = Math.Min(end.Value, length);
start = length - bytes;
end = start + bytes - 1;
}
normalizedRanges.Add(new RangeItemHeaderValue(start.Value, end.Value));
}
return normalizedRanges;
}
}
}