432 lines
24 KiB
C#
432 lines
24 KiB
C#
// 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.Net;
|
|
using System.Net.Http;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.AspNetCore.TestHost;
|
|
using Xunit;
|
|
|
|
namespace Microsoft.AspNetCore.StaticFiles
|
|
{
|
|
public class RangeHeaderTests
|
|
{
|
|
// 14.27 If-Range
|
|
// If the entity tag given in the If-Range header matches the current entity tag for the entity, then the server SHOULD
|
|
// provide the specified sub-range of the entity using a 206 (Partial content) response.
|
|
[Fact]
|
|
public async Task IfRangeWithCurrentEtagShouldServePartialContent()
|
|
{
|
|
TestServer server = StaticFilesTestServer.Create(app => app.UseFileServer());
|
|
HttpResponseMessage original = await server.CreateClient().GetAsync("http://localhost/SubFolder/ranges.txt");
|
|
|
|
var req = new HttpRequestMessage(HttpMethod.Get, "http://localhost/SubFolder/ranges.txt");
|
|
req.Headers.Add("If-Range", original.Headers.ETag.ToString());
|
|
req.Headers.Add("Range", "bytes=0-10");
|
|
HttpResponseMessage resp = await server.CreateClient().SendAsync(req);
|
|
Assert.Equal(HttpStatusCode.PartialContent, resp.StatusCode);
|
|
Assert.Equal("bytes 0-10/62", resp.Content.Headers.ContentRange.ToString());
|
|
Assert.Equal(11, resp.Content.Headers.ContentLength);
|
|
Assert.Equal("0123456789a", await resp.Content.ReadAsStringAsync());
|
|
}
|
|
|
|
// 14.27 If-Range
|
|
// If the entity tag given in the If-Range header matches the current entity tag for the entity, then the server SHOULD
|
|
// provide the specified sub-range of the entity using a 206 (Partial content) response.
|
|
// HEAD requests should ignore the Range header
|
|
[Fact]
|
|
public async Task HEADIfRangeWithCurrentEtagShouldReturn200Ok()
|
|
{
|
|
TestServer server = StaticFilesTestServer.Create(app => app.UseFileServer());
|
|
HttpResponseMessage original = await server.CreateClient().GetAsync("http://localhost/SubFolder/ranges.txt");
|
|
|
|
var req = new HttpRequestMessage(HttpMethod.Head, "http://localhost/SubFolder/ranges.txt");
|
|
req.Headers.Add("If-Range", original.Headers.ETag.ToString());
|
|
req.Headers.Add("Range", "bytes=0-10");
|
|
HttpResponseMessage resp = await server.CreateClient().SendAsync(req);
|
|
|
|
Assert.Equal(HttpStatusCode.OK, resp.StatusCode);
|
|
Assert.Equal(original.Headers.ETag, resp.Headers.ETag);
|
|
Assert.Null(resp.Content.Headers.ContentRange);
|
|
Assert.Equal(62, resp.Content.Headers.ContentLength);
|
|
Assert.Equal(string.Empty, await resp.Content.ReadAsStringAsync());
|
|
}
|
|
|
|
// 14.27 If-Range
|
|
// If the client has no entity tag for an entity, but does have a Last- Modified date, it MAY use that date in an If-Range header.
|
|
[Fact]
|
|
public async Task IfRangeWithCurrentDateShouldServePartialContent()
|
|
{
|
|
TestServer server = StaticFilesTestServer.Create(app => app.UseFileServer());
|
|
HttpResponseMessage original = await server.CreateClient().GetAsync("http://localhost/SubFolder/ranges.txt");
|
|
|
|
var req = new HttpRequestMessage(HttpMethod.Get, "http://localhost/SubFolder/ranges.txt");
|
|
req.Headers.Add("If-Range", original.Content.Headers.LastModified.Value.ToString("r"));
|
|
req.Headers.Add("Range", "bytes=0-10");
|
|
HttpResponseMessage resp = await server.CreateClient().SendAsync(req);
|
|
Assert.Equal(HttpStatusCode.PartialContent, resp.StatusCode);
|
|
Assert.Equal("bytes 0-10/62", resp.Content.Headers.ContentRange.ToString());
|
|
Assert.Equal(11, resp.Content.Headers.ContentLength);
|
|
Assert.Equal("0123456789a", await resp.Content.ReadAsStringAsync());
|
|
}
|
|
|
|
[Fact]
|
|
public async Task IfModifiedSinceWithPastDateShouldServePartialContent()
|
|
{
|
|
TestServer server = StaticFilesTestServer.Create(app => app.UseFileServer());
|
|
HttpResponseMessage original = await server.CreateClient().GetAsync("http://localhost/SubFolder/ranges.txt");
|
|
|
|
var req = new HttpRequestMessage(HttpMethod.Get, "http://localhost/SubFolder/ranges.txt");
|
|
req.Headers.Add("If-Modified-Since", original.Content.Headers.LastModified.Value.AddHours(-1).ToString("r"));
|
|
req.Headers.Add("Range", "bytes=0-10");
|
|
HttpResponseMessage resp = await server.CreateClient().SendAsync(req);
|
|
Assert.Equal(HttpStatusCode.PartialContent, resp.StatusCode);
|
|
Assert.Equal("bytes 0-10/62", resp.Content.Headers.ContentRange.ToString());
|
|
Assert.Equal(11, resp.Content.Headers.ContentLength);
|
|
Assert.Equal("0123456789a", await resp.Content.ReadAsStringAsync());
|
|
}
|
|
|
|
[Fact]
|
|
public async Task IfModifiedSinceWithCurrentDateShouldReturn304()
|
|
{
|
|
TestServer server = StaticFilesTestServer.Create(app => app.UseFileServer());
|
|
HttpResponseMessage original = await server.CreateClient().GetAsync("http://localhost/SubFolder/ranges.txt");
|
|
|
|
var req = new HttpRequestMessage(HttpMethod.Get, "http://localhost/SubFolder/ranges.txt");
|
|
req.Headers.Add("If-Modified-Since", original.Content.Headers.LastModified.Value.ToString("r"));
|
|
req.Headers.Add("Range", "bytes=0-10");
|
|
HttpResponseMessage resp = await server.CreateClient().SendAsync(req);
|
|
Assert.Equal(HttpStatusCode.NotModified, resp.StatusCode);
|
|
}
|
|
|
|
// 14.27 If-Range
|
|
// If the client has no entity tag for an entity, but does have a Last- Modified date, it MAY use that date in an If-Range header.
|
|
// HEAD requests should ignore the Range header
|
|
[Fact]
|
|
public async Task HEADIfRangeWithCurrentDateShouldReturn200Ok()
|
|
{
|
|
TestServer server = StaticFilesTestServer.Create(app => app.UseFileServer());
|
|
HttpResponseMessage original = await server.CreateClient().GetAsync("http://localhost/SubFolder/ranges.txt");
|
|
|
|
var req = new HttpRequestMessage(HttpMethod.Head, "http://localhost/SubFolder/ranges.txt");
|
|
req.Headers.Add("If-Range", original.Content.Headers.LastModified.Value.ToString("r"));
|
|
req.Headers.Add("Range", "bytes=0-10");
|
|
HttpResponseMessage resp = await server.CreateClient().SendAsync(req);
|
|
|
|
Assert.Equal(HttpStatusCode.OK, resp.StatusCode);
|
|
Assert.Equal(original.Content.Headers.LastModified, resp.Content.Headers.LastModified);
|
|
Assert.Null(resp.Content.Headers.ContentRange);
|
|
Assert.Equal(62, resp.Content.Headers.ContentLength);
|
|
Assert.Equal(string.Empty, await resp.Content.ReadAsStringAsync());
|
|
}
|
|
|
|
// 14.27 If-Range
|
|
// If the entity tag does not match, then the server SHOULD return the entire entity using a 200 (OK) response.
|
|
[Fact]
|
|
public async Task IfRangeWithOldEtagShouldServeFullContent()
|
|
{
|
|
TestServer server = StaticFilesTestServer.Create(app => app.UseFileServer());
|
|
var req = new HttpRequestMessage(HttpMethod.Get, "http://localhost/SubFolder/ranges.txt");
|
|
req.Headers.Add("If-Range", "\"OldEtag\"");
|
|
req.Headers.Add("Range", "bytes=0-10");
|
|
HttpResponseMessage resp = await server.CreateClient().SendAsync(req);
|
|
Assert.Equal(HttpStatusCode.OK, resp.StatusCode);
|
|
Assert.Null(resp.Content.Headers.ContentRange);
|
|
Assert.Equal(62, resp.Content.Headers.ContentLength);
|
|
Assert.Equal("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", await resp.Content.ReadAsStringAsync());
|
|
}
|
|
|
|
// 14.27 If-Range
|
|
// If the entity tag does not match, then the server SHOULD return the entire entity using a 200 (OK) response.
|
|
[Fact]
|
|
public async Task HEADIfRangeWithOldEtagShouldServeFullContent()
|
|
{
|
|
TestServer server = StaticFilesTestServer.Create(app => app.UseFileServer());
|
|
var req = new HttpRequestMessage(HttpMethod.Head, "http://localhost/SubFolder/ranges.txt");
|
|
req.Headers.Add("If-Range", "\"OldEtag\"");
|
|
req.Headers.Add("Range", "bytes=0-10");
|
|
HttpResponseMessage resp = await server.CreateClient().SendAsync(req);
|
|
Assert.Equal(HttpStatusCode.OK, resp.StatusCode);
|
|
Assert.Null(resp.Content.Headers.ContentRange);
|
|
Assert.Equal(62, resp.Content.Headers.ContentLength);
|
|
Assert.Equal(string.Empty, await resp.Content.ReadAsStringAsync());
|
|
}
|
|
|
|
// 14.27 If-Range
|
|
// If the entity tag/date does not match, then the server SHOULD return the entire entity using a 200 (OK) response.
|
|
[Fact]
|
|
public async Task IfRangeWithOldDateShouldServeFullContent()
|
|
{
|
|
TestServer server = StaticFilesTestServer.Create(app => app.UseFileServer());
|
|
HttpResponseMessage original = await server.CreateClient().GetAsync("http://localhost/SubFolder/ranges.txt");
|
|
|
|
var req = new HttpRequestMessage(HttpMethod.Get, "http://localhost/SubFolder/ranges.txt");
|
|
req.Headers.Add("If-Range", original.Content.Headers.LastModified.Value.Subtract(TimeSpan.FromDays(1)).ToString("r"));
|
|
req.Headers.Add("Range", "bytes=0-10");
|
|
HttpResponseMessage resp = await server.CreateClient().SendAsync(req);
|
|
Assert.Equal(HttpStatusCode.OK, resp.StatusCode);
|
|
Assert.Null(resp.Content.Headers.ContentRange);
|
|
Assert.Equal(62, resp.Content.Headers.ContentLength);
|
|
Assert.Equal("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", await resp.Content.ReadAsStringAsync());
|
|
}
|
|
|
|
// 14.27 If-Range
|
|
// If the entity tag/date does not match, then the server SHOULD return the entire entity using a 200 (OK) response.
|
|
[Fact]
|
|
public async Task HEADIfRangeWithOldDateShouldServeFullContent()
|
|
{
|
|
TestServer server = StaticFilesTestServer.Create(app => app.UseFileServer());
|
|
HttpResponseMessage original = await server.CreateClient().GetAsync("http://localhost/SubFolder/ranges.txt");
|
|
|
|
var req = new HttpRequestMessage(HttpMethod.Head, "http://localhost/SubFolder/ranges.txt");
|
|
req.Headers.Add("If-Range", original.Content.Headers.LastModified.Value.Subtract(TimeSpan.FromDays(1)).ToString("r"));
|
|
req.Headers.Add("Range", "bytes=0-10");
|
|
HttpResponseMessage resp = await server.CreateClient().SendAsync(req);
|
|
Assert.Equal(HttpStatusCode.OK, resp.StatusCode);
|
|
Assert.Null(resp.Content.Headers.ContentRange);
|
|
Assert.Equal(62, resp.Content.Headers.ContentLength);
|
|
Assert.Equal(string.Empty, await resp.Content.ReadAsStringAsync());
|
|
}
|
|
|
|
// 14.27 If-Range
|
|
// The If-Range header SHOULD only be used together with a Range header, and MUST be ignored if the request
|
|
// does not include a Range header, or if the server does not support the sub-range operation.
|
|
[Fact]
|
|
public async Task IfRangeWithoutRangeShouldServeFullContent()
|
|
{
|
|
TestServer server = StaticFilesTestServer.Create(app => app.UseFileServer());
|
|
HttpResponseMessage original = await server.CreateClient().GetAsync("http://localhost/SubFolder/ranges.txt");
|
|
|
|
var req = new HttpRequestMessage(HttpMethod.Get, "http://localhost/SubFolder/ranges.txt");
|
|
req.Headers.Add("If-Range", original.Headers.ETag.ToString());
|
|
HttpResponseMessage resp = await server.CreateClient().SendAsync(req);
|
|
Assert.Equal(HttpStatusCode.OK, resp.StatusCode);
|
|
Assert.Null(resp.Content.Headers.ContentRange);
|
|
Assert.Equal(62, resp.Content.Headers.ContentLength);
|
|
Assert.Equal("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", await resp.Content.ReadAsStringAsync());
|
|
|
|
req = new HttpRequestMessage(HttpMethod.Get, "http://localhost/SubFolder/ranges.txt");
|
|
req.Headers.Add("If-Range", original.Content.Headers.LastModified.Value.ToString("r"));
|
|
resp = await server.CreateClient().SendAsync(req);
|
|
Assert.Equal(HttpStatusCode.OK, resp.StatusCode);
|
|
Assert.Null(resp.Content.Headers.ContentRange);
|
|
Assert.Equal(62, resp.Content.Headers.ContentLength);
|
|
Assert.Equal("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", await resp.Content.ReadAsStringAsync());
|
|
}
|
|
|
|
// 14.27 If-Range
|
|
// The If-Range header SHOULD only be used together with a Range header, and MUST be ignored if the request
|
|
// does not include a Range header, or if the server does not support the sub-range operation.
|
|
[Fact]
|
|
public async Task HEADIfRangeWithoutRangeShouldServeFullContent()
|
|
{
|
|
TestServer server = StaticFilesTestServer.Create(app => app.UseFileServer());
|
|
HttpResponseMessage original = await server.CreateClient().GetAsync("http://localhost/SubFolder/ranges.txt");
|
|
|
|
var req = new HttpRequestMessage(HttpMethod.Head, "http://localhost/SubFolder/ranges.txt");
|
|
req.Headers.Add("If-Range", original.Headers.ETag.ToString());
|
|
HttpResponseMessage resp = await server.CreateClient().SendAsync(req);
|
|
Assert.Equal(HttpStatusCode.OK, resp.StatusCode);
|
|
Assert.Null(resp.Content.Headers.ContentRange);
|
|
Assert.Equal(62, resp.Content.Headers.ContentLength);
|
|
Assert.Equal(string.Empty, await resp.Content.ReadAsStringAsync());
|
|
|
|
req = new HttpRequestMessage(HttpMethod.Head, "http://localhost/SubFolder/ranges.txt");
|
|
req.Headers.Add("If-Range", original.Content.Headers.LastModified.Value.ToString("r"));
|
|
resp = await server.CreateClient().SendAsync(req);
|
|
Assert.Equal(HttpStatusCode.OK, resp.StatusCode);
|
|
Assert.Null(resp.Content.Headers.ContentRange);
|
|
Assert.Equal(62, resp.Content.Headers.ContentLength);
|
|
Assert.Equal(string.Empty, await resp.Content.ReadAsStringAsync());
|
|
}
|
|
|
|
// 14.35 Range
|
|
[Theory]
|
|
[InlineData("0-0", "0-0", 1, "0")]
|
|
[InlineData("0- 9", "0-9", 10, "0123456789")]
|
|
[InlineData("0 -9", "0-9", 10, "0123456789")]
|
|
[InlineData("0 - 9", "0-9", 10, "0123456789")]
|
|
[InlineData("10-35", "10-35", 26, "abcdefghijklmnopqrstuvwxyz")]
|
|
[InlineData("36-61", "36-61", 26, "ABCDEFGHIJKLMNOPQRSTUVWXYZ")]
|
|
[InlineData("36-", "36-61", 26, "ABCDEFGHIJKLMNOPQRSTUVWXYZ")] // Last 26
|
|
[InlineData("-26", "36-61", 26, "ABCDEFGHIJKLMNOPQRSTUVWXYZ")] // Last 26
|
|
[InlineData("0-", "0-61", 62, "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")]
|
|
[InlineData("-1001", "0-61", 62, "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")]
|
|
public async Task SingleValidRangeShouldServePartialContent(string range, string expectedRange, int length, string expectedData)
|
|
{
|
|
TestServer server = StaticFilesTestServer.Create(app => app.UseFileServer());
|
|
var req = new HttpRequestMessage(HttpMethod.Get, "http://localhost/SubFolder/ranges.txt");
|
|
req.Headers.Add("Range", "bytes=" + range);
|
|
HttpResponseMessage resp = await server.CreateClient().SendAsync(req);
|
|
Assert.Equal(HttpStatusCode.PartialContent, resp.StatusCode);
|
|
Assert.NotNull(resp.Content.Headers.ContentRange);
|
|
Assert.Equal("bytes " + expectedRange + "/62", resp.Content.Headers.ContentRange.ToString());
|
|
Assert.Equal(length, resp.Content.Headers.ContentLength);
|
|
Assert.Equal(expectedData, await resp.Content.ReadAsStringAsync());
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("0-0", "0-0", 1, "A")]
|
|
[InlineData("0-", "0-0", 1, "A")]
|
|
[InlineData("-1", "0-0", 1, "A")]
|
|
[InlineData("-2", "0-0", 1, "A")]
|
|
[InlineData("0-1", "0-0", 1, "A")]
|
|
[InlineData("0-2", "0-0", 1, "A")]
|
|
public async Task SingleValidRangeShouldServePartialContentSingleByteFile(string range, string expectedRange, int length, string expectedData)
|
|
{
|
|
TestServer server = StaticFilesTestServer.Create(app => app.UseFileServer());
|
|
var req = new HttpRequestMessage(HttpMethod.Get, "http://localhost/SubFolder/SingleByte.txt");
|
|
req.Headers.Add("Range", "bytes=" + range);
|
|
HttpResponseMessage resp = await server.CreateClient().SendAsync(req);
|
|
Assert.Equal(HttpStatusCode.PartialContent, resp.StatusCode);
|
|
Assert.NotNull(resp.Content.Headers.ContentRange);
|
|
Assert.Equal("bytes " + expectedRange + "/1", resp.Content.Headers.ContentRange.ToString());
|
|
Assert.Equal(length, resp.Content.Headers.ContentLength);
|
|
Assert.Equal(expectedData, await resp.Content.ReadAsStringAsync());
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("0-0")]
|
|
[InlineData("0-")]
|
|
[InlineData("-1")]
|
|
[InlineData("-2")]
|
|
[InlineData("0-1")]
|
|
[InlineData("0-2")]
|
|
public async Task SingleValidRangeShouldServeRequestedRangeNotSatisfiableEmptyFile(string range)
|
|
{
|
|
TestServer server = StaticFilesTestServer.Create(app => app.UseFileServer());
|
|
var req = new HttpRequestMessage(HttpMethod.Get, "http://localhost/SubFolder/Empty.txt");
|
|
req.Headers.Add("Range", "bytes=" + range);
|
|
HttpResponseMessage resp = await server.CreateClient().SendAsync(req);
|
|
Assert.Equal(HttpStatusCode.RequestedRangeNotSatisfiable, resp.StatusCode);
|
|
}
|
|
|
|
// 14.35 Range
|
|
// HEAD ignores range headers
|
|
[Theory]
|
|
[InlineData("10-35")]
|
|
public async Task HEADSingleValidRangeShouldReturnOk(string range)
|
|
{
|
|
TestServer server = StaticFilesTestServer.Create(app => app.UseFileServer());
|
|
var req = new HttpRequestMessage(HttpMethod.Head, "http://localhost/SubFolder/ranges.txt");
|
|
req.Headers.Add("Range", "bytes=" + range);
|
|
HttpResponseMessage resp = await server.CreateClient().SendAsync(req);
|
|
Assert.Equal(HttpStatusCode.OK, resp.StatusCode);
|
|
Assert.Null(resp.Content.Headers.ContentRange);
|
|
Assert.Equal(62, resp.Content.Headers.ContentLength);
|
|
Assert.Equal(string.Empty, await resp.Content.ReadAsStringAsync());
|
|
}
|
|
|
|
// 14.35 Range
|
|
[Theory]
|
|
[InlineData("100-")] // Out of range
|
|
[InlineData("1000-1001")] // Out of range
|
|
[InlineData("-0")] // Suffix range must be non-zero
|
|
public async Task SingleNotSatisfiableRange(string range)
|
|
{
|
|
TestServer server = StaticFilesTestServer.Create(app => app.UseFileServer());
|
|
var req = new HttpRequestMessage(HttpMethod.Get, "http://localhost/SubFolder/ranges.txt");
|
|
req.Headers.TryAddWithoutValidation("Range", "bytes=" + range);
|
|
HttpResponseMessage resp = await server.CreateClient().SendAsync(req);
|
|
Assert.Equal(HttpStatusCode.RequestedRangeNotSatisfiable, resp.StatusCode);
|
|
Assert.Equal("bytes */62", resp.Content.Headers.ContentRange.ToString());
|
|
}
|
|
|
|
// 14.35 Range
|
|
// HEAD ignores range headers
|
|
[Theory]
|
|
[InlineData("1000-1001")] // Out of range
|
|
public async Task HEADSingleNotSatisfiableRangeReturnsOk(string range)
|
|
{
|
|
TestServer server = StaticFilesTestServer.Create(app => app.UseFileServer());
|
|
var req = new HttpRequestMessage(HttpMethod.Head, "http://localhost/SubFolder/ranges.txt");
|
|
req.Headers.TryAddWithoutValidation("Range", "bytes=" + range);
|
|
HttpResponseMessage resp = await server.CreateClient().SendAsync(req);
|
|
Assert.Equal(HttpStatusCode.OK, resp.StatusCode);
|
|
Assert.Null(resp.Content.Headers.ContentRange);
|
|
}
|
|
|
|
// 14.35 Range
|
|
[Theory]
|
|
[InlineData("")]
|
|
[InlineData("0")]
|
|
[InlineData("1-0")]
|
|
[InlineData("-")]
|
|
[InlineData("a-")]
|
|
[InlineData("-b")]
|
|
[InlineData("a-b")]
|
|
public async Task SingleInvalidRangeIgnored(string range)
|
|
{
|
|
TestServer server = StaticFilesTestServer.Create(app => app.UseFileServer());
|
|
var req = new HttpRequestMessage(HttpMethod.Get, "http://localhost/SubFolder/ranges.txt");
|
|
req.Headers.TryAddWithoutValidation("Range", "bytes=" + range);
|
|
HttpResponseMessage resp = await server.CreateClient().SendAsync(req);
|
|
Assert.Equal(HttpStatusCode.OK, resp.StatusCode);
|
|
Assert.Null(resp.Content.Headers.ContentRange);
|
|
Assert.Equal(62, resp.Content.Headers.ContentLength);
|
|
Assert.Equal("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", await resp.Content.ReadAsStringAsync());
|
|
}
|
|
|
|
// 14.35 Range
|
|
[Theory]
|
|
[InlineData("")]
|
|
[InlineData("0")]
|
|
[InlineData("1-0")]
|
|
[InlineData("-")]
|
|
[InlineData("a-")]
|
|
[InlineData("-b")]
|
|
[InlineData("a-b")]
|
|
public async Task HEADSingleInvalidRangeIgnored(string range)
|
|
{
|
|
TestServer server = StaticFilesTestServer.Create(app => app.UseFileServer());
|
|
var req = new HttpRequestMessage(HttpMethod.Head, "http://localhost/SubFolder/ranges.txt");
|
|
req.Headers.TryAddWithoutValidation("Range", "bytes=" + range);
|
|
HttpResponseMessage resp = await server.CreateClient().SendAsync(req);
|
|
Assert.Equal(HttpStatusCode.OK, resp.StatusCode);
|
|
Assert.Null(resp.Content.Headers.ContentRange);
|
|
Assert.Equal(62, resp.Content.Headers.ContentLength);
|
|
Assert.Equal(string.Empty, await resp.Content.ReadAsStringAsync());
|
|
}
|
|
|
|
// 14.35 Range
|
|
[Theory]
|
|
[InlineData("0-0,2-2")]
|
|
[InlineData("0-0,60-")]
|
|
[InlineData("0-0,-2")]
|
|
[InlineData("2-2,0-0")]
|
|
[InlineData("0-0,2-2,4-4,6-6,8-8")]
|
|
[InlineData("0-0,6-6,8-8,2-2,4-4")]
|
|
public async Task MultipleValidRangesShouldServeFullContent(string ranges)
|
|
{
|
|
TestServer server = StaticFilesTestServer.Create(app => app.UseFileServer());
|
|
var req = new HttpRequestMessage(HttpMethod.Get, "http://localhost/SubFolder/ranges.txt");
|
|
req.Headers.Add("Range", "bytes=" + ranges);
|
|
HttpResponseMessage resp = await server.CreateClient().SendAsync(req);
|
|
Assert.Equal(HttpStatusCode.OK, resp.StatusCode);
|
|
Assert.Equal("text/plain", resp.Content.Headers.ContentType.ToString());
|
|
Assert.Null(resp.Content.Headers.ContentRange);
|
|
Assert.Equal(62, resp.Content.Headers.ContentLength);
|
|
Assert.Equal("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", await resp.Content.ReadAsStringAsync());
|
|
}
|
|
|
|
// 14.35 Range
|
|
[Theory]
|
|
[InlineData("0-0,2-2")]
|
|
[InlineData("0-0,60-")]
|
|
[InlineData("0-0,-2")]
|
|
[InlineData("2-2,0-0")] // SHOULD send in the requested order.
|
|
public async Task HEADMultipleValidRangesShouldServeFullContent(string range)
|
|
{
|
|
TestServer server = StaticFilesTestServer.Create(app => app.UseFileServer());
|
|
var req = new HttpRequestMessage(HttpMethod.Head, "http://localhost/SubFolder/ranges.txt");
|
|
req.Headers.Add("Range", "bytes=" + range);
|
|
HttpResponseMessage resp = await server.CreateClient().SendAsync(req);
|
|
Assert.Equal(HttpStatusCode.OK, resp.StatusCode);
|
|
Assert.Equal("text/plain", resp.Content.Headers.ContentType.ToString());
|
|
Assert.Equal(string.Empty, await resp.Content.ReadAsStringAsync());
|
|
}
|
|
}
|
|
}
|