/
githubmirror
/
aspnetcore
Обзор
Документация
Войти
/
githubmirror
/
aspnetcore
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Middleware/StaticFiles/test/FunctionalTests/StaticFileMiddlewareTests.cs
307 строк
12 KB
William Godbe
Rename Microsoft.Aspnetcore.Testing to Microsoft.AspNetCore.InternalTesting (#51713)
02 ноя 2023, 03:15
Не верифицирован
02 ноя 2023, 03:15
fc8deca
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Net; using System.Net.Http; using System.Net.Sockets; using System.Text; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Server.IntegrationTesting; using Microsoft.AspNetCore.Server.IntegrationTesting.Common; using Microsoft.AspNetCore.InternalTesting; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; namespace Microsoft.AspNetCore.StaticFiles; public class StaticFileMiddlewareTests : LoggedTest { [Fact] public async Task ReturnsNotFoundWithoutWwwroot() { using var host = new HostBuilder() .ConfigureWebHost(webHostBuilder => { webHostBuilder .ConfigureServices(services => services.AddSingleton(LoggerFactory)) .UseKestrel() .UseUrls(TestUrlHelper.GetTestUrl(ServerType.Kestrel)) .Configure(app => app.UseStaticFiles()); }).Build(); await host.StartAsync(); using (var client = new HttpClient { BaseAddress = new Uri(Helpers.GetAddress(host)) }) { var response = await client.GetAsync("TestDocument.txt"); Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); } } [Fact] public async Task Endpoint_PassesThrough() { using var host = new HostBuilder() .ConfigureWebHost(webHostBuilder => { webHostBuilder .ConfigureServices(services => { services.AddSingleton(LoggerFactory); services.AddRouting(); }) .UseKestrel() .UseUrls(TestUrlHelper.GetTestUrl(ServerType.Kestrel)) .UseWebRoot(AppContext.BaseDirectory) .Configure(app => { // Routing first => static files noops app.UseRouting(); app.Use(next => context => { // Assign an endpoint, this will make the default files noop. context.SetEndpoint(new Endpoint((c) => { return context.Response.WriteAsync("Hi from endpoint."); }, new EndpointMetadataCollection(), "test")); return next(context); }); app.UseStaticFiles(); app.UseEndpoints(endpoints => { }); }); }).Build(); await host.StartAsync(); using (var client = new HttpClient { BaseAddress = new Uri(Helpers.GetAddress(host)) }) { var response = await client.GetAsync("TestDocument.txt"); Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal("Hi from endpoint.", await response.Content.ReadAsStringAsync()); } } [Fact] public async Task FoundFile_LastModifiedTrimsSeconds() { using var host = new HostBuilder() .ConfigureWebHost(webHostBuilder => { webHostBuilder .ConfigureServices(services => services.AddSingleton(LoggerFactory)) .UseKestrel() .UseUrls(TestUrlHelper.GetTestUrl(ServerType.Kestrel)) .UseWebRoot(AppContext.BaseDirectory) .Configure(app => app.UseStaticFiles()); }).Build(); await host.StartAsync(); using (var client = new HttpClient { BaseAddress = new Uri(Helpers.GetAddress(host)) }) { var last = File.GetLastWriteTimeUtc(Path.Combine(AppContext.BaseDirectory, "TestDocument.txt")); var response = await client.GetAsync("TestDocument.txt"); var trimmed = new DateTimeOffset(last.Year, last.Month, last.Day, last.Hour, last.Minute, last.Second, TimeSpan.Zero).ToUniversalTime(); Assert.Equal(response.Content.Headers.LastModified.Value, trimmed); } } [Theory] [MemberData(nameof(ExistingFiles))] public async Task FoundFile_Served_All(string baseUrl, string baseDir, string requestUrl) { await FoundFile_Served(baseUrl, baseDir, requestUrl); } [ConditionalTheory] [OSSkipCondition(OperatingSystems.Linux)] [OSSkipCondition(OperatingSystems.MacOSX)] [InlineData("", @".", "/testDocument.Txt")] [InlineData("/somedir", @".", "/somedir/Testdocument.TXT")] [InlineData("/SomeDir", @".", "/soMediR/testdocument.txT")] [InlineData("/somedir", @"SubFolder", "/somedir/Ranges.tXt")] public async Task FoundFile_Served_Windows(string baseUrl, string baseDir, string requestUrl) { await FoundFile_Served(baseUrl, baseDir, requestUrl); } private async Task FoundFile_Served(string baseUrl, string baseDir, string requestUrl) { using var host = new HostBuilder() .ConfigureWebHost(webHostBuilder => { webHostBuilder .ConfigureServices(services => services.AddSingleton(LoggerFactory)) .UseKestrel() .UseUrls(TestUrlHelper.GetTestUrl(ServerType.Kestrel)) .UseWebRoot(Path.Combine(AppContext.BaseDirectory, baseDir)) .Configure(app => app.UseStaticFiles(new StaticFileOptions { RequestPath = new PathString(baseUrl), })); }).Build(); await host.StartAsync(); var hostingEnvironment = host.Services.GetService<IWebHostEnvironment>(); using (var client = new HttpClient { BaseAddress = new Uri(Helpers.GetAddress(host)) }) { var fileInfo = hostingEnvironment.WebRootFileProvider.GetFileInfo(Path.GetFileName(requestUrl)); var response = await client.GetAsync(requestUrl); var responseContent = await response.Content.ReadAsByteArrayAsync(); Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal("text/plain", response.Content.Headers.ContentType.ToString()); Assert.True(response.Content.Headers.ContentLength == fileInfo.Length); Assert.Equal(response.Content.Headers.ContentLength, responseContent.Length); using (var stream = fileInfo.CreateReadStream()) { var fileContents = new byte[stream.Length]; stream.Read(fileContents, 0, (int)stream.Length); Assert.True(responseContent.SequenceEqual(fileContents)); } } } [Theory] [MemberData(nameof(ExistingFiles))] public async Task HeadFile_HeadersButNotBodyServed(string baseUrl, string baseDir, string requestUrl) { using var host = new HostBuilder() .ConfigureWebHost(webHostBuilder => { webHostBuilder .ConfigureServices(services => services.AddSingleton(LoggerFactory)) .UseKestrel() .UseUrls(TestUrlHelper.GetTestUrl(ServerType.Kestrel)) .UseWebRoot(Path.Combine(AppContext.BaseDirectory, baseDir)) .Configure(app => app.UseStaticFiles(new StaticFileOptions { RequestPath = new PathString(baseUrl), })); }).Build(); await host.StartAsync(); var hostingEnvironment = host.Services.GetService<IWebHostEnvironment>(); using (var client = new HttpClient { BaseAddress = new Uri(Helpers.GetAddress(host)) }) { var fileInfo = hostingEnvironment.WebRootFileProvider.GetFileInfo(Path.GetFileName(requestUrl)); var request = new HttpRequestMessage(HttpMethod.Head, requestUrl); var response = await client.SendAsync(request); Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal("text/plain", response.Content.Headers.ContentType.ToString()); Assert.True(response.Content.Headers.ContentLength == fileInfo.Length); Assert.Empty((await response.Content.ReadAsByteArrayAsync())); } } public static IEnumerable<object[]> ExistingFiles => new[] { new[] {"", @".", "/TestDocument.txt"}, new[] {"/somedir", @".", "/somedir/TestDocument.txt"}, new[] {"/SomeDir", @".", "/soMediR/TestDocument.txt"}, new[] {"", @"SubFolder", "/ranges.txt"}, new[] {"/somedir", @"SubFolder", "/somedir/ranges.txt"}, new[] {"", @"SubFolder", "/Empty.txt"} }; [Fact] public Task ClientDisconnect_Kestrel_NoWriteExceptionThrown() { return ClientDisconnect_NoWriteExceptionThrown(ServerType.Kestrel); } [ConditionalFact] [OSSkipCondition(OperatingSystems.Linux)] [OSSkipCondition(OperatingSystems.MacOSX)] public Task ClientDisconnect_WebListener_NoWriteExceptionThrown() { return ClientDisconnect_NoWriteExceptionThrown(ServerType.HttpSys); } private async Task ClientDisconnect_NoWriteExceptionThrown(ServerType serverType) { var interval = TimeSpan.FromSeconds(15); var requestReceived = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); var requestCancelled = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); var responseComplete = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); Exception exception = null; using var host = new HostBuilder() .ConfigureWebHost(webHostBuilder => { webHostBuilder .ConfigureServices(services => services.AddSingleton(LoggerFactory)) .UseWebRoot(Path.Combine(AppContext.BaseDirectory)) .Configure(app => { app.Use(async (context, next) => { try { requestReceived.SetResult(); await requestCancelled.Task.TimeoutAfter(interval); Assert.True(context.RequestAborted.WaitHandle.WaitOne(interval), "not aborted"); await next(context); } catch (Exception ex) { exception = ex; } responseComplete.SetResult(); }); app.UseStaticFiles(); }) .UseUrls(TestUrlHelper.GetTestUrl(serverType)); if (serverType == ServerType.HttpSys) { webHostBuilder.UseHttpSys(); } else if (serverType == ServerType.Kestrel) { webHostBuilder.UseKestrel(); } }).Build(); await host.StartAsync(); // We don't use HttpClient here because it's disconnect behavior varies across platforms. var socket = SendSocketRequestAsync(Helpers.GetAddress(host), "/TestDocument1MB.txt"); await requestReceived.Task.TimeoutAfter(interval); socket.LingerState = new LingerOption(true, 0); socket.Dispose(); requestCancelled.SetResult(); await responseComplete.Task.TimeoutAfter(interval); Assert.Null(exception); } private Socket SendSocketRequestAsync(string address, string path, string method = "GET") { var uri = new Uri(address); var builder = new StringBuilder(); builder.Append(FormattableString.Invariant($"{method} {path} HTTP/1.1\r\n")); builder.Append(FormattableString.Invariant($"HOST: {uri.Authority}\r\n\r\n")); byte[] request = Encoding.ASCII.GetBytes(builder.ToString()); var socket = new Socket(SocketType.Stream, ProtocolType.Tcp); socket.Connect(IPAddress.Loopback, uri.Port); socket.Send(request); return socket; } }