Merge pull request #22840 from dotnet-maestro-bot/merge/release/3.1-to-master
[automated] Merge branch 'release/3.1' => 'master'
This commit is contained in:
commit
0343af108a
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -85,7 +85,14 @@ export class WebAssemblyResourceLoader {
|
|||
const cacheKey = toAbsoluteUri(`${url}.${contentHash}`);
|
||||
this.usedCacheKeys[cacheKey] = true;
|
||||
|
||||
const cachedResponse = await cache.match(cacheKey);
|
||||
let cachedResponse: Response | undefined;
|
||||
try {
|
||||
cachedResponse = await cache.match(cacheKey);
|
||||
} catch {
|
||||
// Be tolerant to errors reading from the cache. This is a guard for https://bugs.chromium.org/p/chromium/issues/detail?id=968444 where
|
||||
// chromium browsers may sometimes throw when working with the cache.
|
||||
}
|
||||
|
||||
if (cachedResponse) {
|
||||
// It's in the cache.
|
||||
const responseBytes = parseInt(cachedResponse.headers.get('content-length') || '0');
|
||||
|
|
@ -136,12 +143,19 @@ export class WebAssemblyResourceLoader {
|
|||
|
||||
// Add to cache as a custom response object so we can track extra data such as responseBytes
|
||||
// We can't rely on the server sending content-length (ASP.NET Core doesn't by default)
|
||||
await cache.put(cacheKey, new Response(responseData, {
|
||||
const responseToCache = new Response(responseData, {
|
||||
headers: {
|
||||
'content-type': response.headers.get('content-type') || '',
|
||||
'content-length': (responseBytes || response.headers.get('content-length') || '').toString()
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
||||
try {
|
||||
await cache.put(cacheKey, responseToCache);
|
||||
} catch {
|
||||
// Be tolerant to errors writing to the cache. This is a guard for https://bugs.chromium.org/p/chromium/issues/detail?id=968444 where
|
||||
// chromium browsers may sometimes throw when performing cache operations.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@
|
|||
|
||||
<WriteLinesToFile
|
||||
File="$(_CombinedHashIntermediatePath)"
|
||||
Lines="@(_ServiceWorkerAssetsManifestItemWithHash->'%(FileHash)')"
|
||||
Lines="@(_ServiceWorkerAssetsManifestItemWithHash->'%(Integrity)')"
|
||||
WriteOnlyWhenDifferent="true"
|
||||
Overwrite="true" />
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -41,5 +42,77 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Build
|
|||
var entries = assets.EnumerateArray().Select(e => e.GetProperty("url").GetString()).OrderBy(e => e).ToArray();
|
||||
Assert.All(entries, e => expectedExtensions.Contains(Path.GetExtension(e)));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Publish_UpdatesServiceWorkerVersionHash_WhenSourcesChange()
|
||||
{
|
||||
// Arrange
|
||||
using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" });
|
||||
var result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish", args: "/bl:initial.binlog /p:ServiceWorkerAssetsManifest=service-worker-assets.js");
|
||||
|
||||
Assert.BuildPassed(result);
|
||||
|
||||
var publishOutputDirectory = project.PublishOutputDirectory;
|
||||
|
||||
var serviceWorkerFile = Assert.FileExists(result, publishOutputDirectory, "wwwroot", "serviceworkers", "my-service-worker.js");
|
||||
var version = File.ReadAllLines(serviceWorkerFile).Last();
|
||||
var match = Regex.Match(version, "\\/\\* Manifest version: (.{8}) \\*\\/");
|
||||
Assert.True(match.Success);
|
||||
Assert.Equal(2, match.Groups.Count);
|
||||
Assert.NotNull(match.Groups[1].Value);
|
||||
var capture = match.Groups[1].Value;
|
||||
|
||||
// Act
|
||||
var cssFile = Path.Combine(project.DirectoryPath, "LinkToWebRoot", "css", "app.css");
|
||||
File.WriteAllText(cssFile, ".updated { }");
|
||||
|
||||
// Assert
|
||||
var updatedResult = await MSBuildProcessManager.DotnetMSBuild(project, "Publish", args: "/bl:updated.binlog /p:ServiceWorkerAssetsManifest=service-worker-assets.js");
|
||||
|
||||
Assert.BuildPassed(result);
|
||||
|
||||
var updatedVersion = File.ReadAllLines(serviceWorkerFile).Last();
|
||||
var updatedMatch = Regex.Match(updatedVersion, "\\/\\* Manifest version: (.{8}) \\*\\/");
|
||||
Assert.True(updatedMatch.Success);
|
||||
Assert.Equal(2, updatedMatch.Groups.Count);
|
||||
Assert.NotNull(updatedMatch.Groups[1].Value);
|
||||
var updatedCapture = updatedMatch.Groups[1].Value;
|
||||
|
||||
Assert.NotEqual(capture, updatedCapture);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Publish_DeterministicAcrossBuilds_WhenNoSourcesChange()
|
||||
{
|
||||
// Arrange
|
||||
using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" });
|
||||
var result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish", args: "/bl:initial.binlog /p:ServiceWorkerAssetsManifest=service-worker-assets.js");
|
||||
|
||||
Assert.BuildPassed(result);
|
||||
|
||||
var publishOutputDirectory = project.PublishOutputDirectory;
|
||||
|
||||
var serviceWorkerFile = Assert.FileExists(result, publishOutputDirectory, "wwwroot", "serviceworkers", "my-service-worker.js");
|
||||
var version = File.ReadAllLines(serviceWorkerFile).Last();
|
||||
var match = Regex.Match(version, "\\/\\* Manifest version: (.{8}) \\*\\/");
|
||||
Assert.True(match.Success);
|
||||
Assert.Equal(2, match.Groups.Count);
|
||||
Assert.NotNull(match.Groups[1].Value);
|
||||
var capture = match.Groups[1].Value;
|
||||
|
||||
// Act && Assert
|
||||
var updatedResult = await MSBuildProcessManager.DotnetMSBuild(project, "Publish", args: "/bl:updated.binlog /p:ServiceWorkerAssetsManifest=service-worker-assets.js");
|
||||
|
||||
Assert.BuildPassed(result);
|
||||
|
||||
var updatedVersion = File.ReadAllLines(serviceWorkerFile).Last();
|
||||
var updatedMatch = Regex.Match(updatedVersion, "\\/\\* Manifest version: (.{8}) \\*\\/");
|
||||
Assert.True(updatedMatch.Success);
|
||||
Assert.Equal(2, updatedMatch.Groups.Count);
|
||||
Assert.NotNull(updatedMatch.Groups[1].Value);
|
||||
var updatedCapture = updatedMatch.Groups[1].Value;
|
||||
|
||||
Assert.Equal(capture, updatedCapture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -143,6 +143,8 @@ namespace Microsoft.AspNetCore.Mvc.Formatters
|
|||
}
|
||||
|
||||
readStream = new FileBufferingReadStream(request.Body, memoryThreshold);
|
||||
// Ensure the file buffer stream is always disposed at the end of a request.
|
||||
request.HttpContext.Response.RegisterForDispose(readStream);
|
||||
|
||||
await readStream.DrainAsync(CancellationToken.None);
|
||||
readStream.Seek(0L, SeekOrigin.Begin);
|
||||
|
|
|
|||
|
|
@ -124,6 +124,8 @@ namespace Microsoft.AspNetCore.Mvc.Formatters
|
|||
}
|
||||
|
||||
readStream = new FileBufferingReadStream(request.Body, memoryThreshold);
|
||||
// Ensure the file buffer stream is always disposed at the end of a request.
|
||||
request.HttpContext.Response.RegisterForDispose(readStream);
|
||||
|
||||
await readStream.DrainAsync(CancellationToken.None);
|
||||
readStream.Seek(0L, SeekOrigin.Begin);
|
||||
|
|
|
|||
|
|
@ -153,6 +153,8 @@ namespace Microsoft.AspNetCore.Mvc.Formatters
|
|||
}
|
||||
|
||||
readStream = new FileBufferingReadStream(request.Body, memoryThreshold);
|
||||
// Ensure the file buffer stream is always disposed at the end of a request.
|
||||
request.HttpContext.Response.RegisterForDispose(readStream);
|
||||
|
||||
await readStream.DrainAsync(CancellationToken.None);
|
||||
readStream.Seek(0L, SeekOrigin.Begin);
|
||||
|
|
@ -278,7 +280,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters
|
|||
|
||||
/// <summary>
|
||||
/// Called during deserialization to get the <see cref="JsonSerializer"/>. The formatter context
|
||||
/// that is passed gives an ability to create serializer specific to the context.
|
||||
/// that is passed gives an ability to create serializer specific to the context.
|
||||
/// </summary>
|
||||
/// <returns>The <see cref="JsonSerializer"/> used during deserialization.</returns>
|
||||
/// <remarks>
|
||||
|
|
@ -297,7 +299,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters
|
|||
|
||||
/// <summary>
|
||||
/// Called during deserialization to get the <see cref="JsonSerializer"/>. The formatter context
|
||||
/// that is passed gives an ability to create serializer specific to the context.
|
||||
/// that is passed gives an ability to create serializer specific to the context.
|
||||
/// </summary>
|
||||
/// <param name="context">A context object used by an input formatter for deserializing the request body into an object.</param>
|
||||
/// <returns>The <see cref="JsonSerializer"/> used during deserialization.</returns>
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
@page "/error"
|
||||
|
||||
|
||||
<h1 class="text-danger">Error.</h1>
|
||||
<h2 class="text-danger">An error occurred while processing your request.</h2>
|
||||
|
||||
<h3>Development Mode</h3>
|
||||
<p>
|
||||
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
|
||||
</p>
|
||||
<p>
|
||||
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
|
||||
It can result in displaying sensitive information from exceptions to end users.
|
||||
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
|
||||
and restarting the app.
|
||||
</p>
|
||||
@page
|
||||
|
||||
|
||||
<h1 class="text-danger">Error.</h1>
|
||||
<h2 class="text-danger">An error occurred while processing your request.</h2>
|
||||
|
||||
<h3>Development Mode</h3>
|
||||
<p>
|
||||
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
|
||||
</p>
|
||||
<p>
|
||||
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
|
||||
It can result in displaying sensitive information from exceptions to end users.
|
||||
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
|
||||
and restarting the app.
|
||||
</p>
|
||||
|
|
@ -25,13 +25,13 @@ namespace ComponentsWebAssembly_CSharp
|
|||
builder.RootComponents.Add<App>("app");
|
||||
|
||||
#if (!Hosted || NoAuth)
|
||||
builder.Services.AddTransient(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
|
||||
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
|
||||
#else
|
||||
builder.Services.AddHttpClient("ComponentsWebAssembly_CSharp.ServerAPI", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
|
||||
.AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
|
||||
|
||||
// Supply HttpClient instances that include access tokens when making requests to the server project
|
||||
builder.Services.AddTransient(sp => sp.GetRequiredService<IHttpClientFactory>().CreateClient("ComponentsWebAssembly_CSharp.ServerAPI"));
|
||||
builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>().CreateClient("ComponentsWebAssembly_CSharp.ServerAPI"));
|
||||
#endif
|
||||
#if(!NoAuth)
|
||||
|
||||
|
|
|
|||
|
|
@ -914,7 +914,7 @@
|
|||
"Data/Migrations/00000000000000_CreateIdentitySchema.Designer.cs",
|
||||
"Data/Migrations/ApplicationDbContextModelSnapshot.cs",
|
||||
"Pages/Counter.razor",
|
||||
"Pages/Error.razor",
|
||||
"Pages/Error.cshtml",
|
||||
"Pages/FetchData.razor",
|
||||
"Pages/Index.razor",
|
||||
"Pages/_Host.cshtml",
|
||||
|
|
@ -951,7 +951,7 @@
|
|||
"Data/WeatherForecast.cs",
|
||||
"Data/WeatherForecastService.cs",
|
||||
"Pages/Counter.razor",
|
||||
"Pages/Error.razor",
|
||||
"Pages/Error.cshtml",
|
||||
"Pages/FetchData.razor",
|
||||
"Pages/Index.razor",
|
||||
"Pages/_Host.cshtml",
|
||||
|
|
@ -988,7 +988,7 @@
|
|||
"Data/WeatherForecast.cs",
|
||||
"Data/WeatherForecastService.cs",
|
||||
"Pages/Counter.razor",
|
||||
"Pages/Error.razor",
|
||||
"Pages/Error.cshtml",
|
||||
"Pages/FetchData.razor",
|
||||
"Pages/Index.razor",
|
||||
"Pages/_Host.cshtml",
|
||||
|
|
@ -1024,7 +1024,7 @@
|
|||
"_Imports.razor",
|
||||
"Data/WeatherForecast.cs",
|
||||
"Data/WeatherForecastService.cs",
|
||||
"Pages/Error.razor",
|
||||
"Pages/Error.cshtml",
|
||||
"Pages/Counter.razor",
|
||||
"Pages/FetchData.razor",
|
||||
"Pages/Index.razor",
|
||||
|
|
@ -1061,7 +1061,7 @@
|
|||
"Data/WeatherForecast.cs",
|
||||
"Data/WeatherForecastService.cs",
|
||||
"Pages/Counter.razor",
|
||||
"Pages/Error.razor",
|
||||
"Pages/Error.cshtml",
|
||||
"Pages/FetchData.razor",
|
||||
"Pages/Index.razor",
|
||||
"Pages/_Host.cshtml",
|
||||
|
|
@ -1098,7 +1098,7 @@
|
|||
"Data/WeatherForecast.cs",
|
||||
"Data/WeatherForecastService.cs",
|
||||
"Pages/Counter.razor",
|
||||
"Pages/Error.razor",
|
||||
"Pages/Error.cshtml",
|
||||
"Pages/FetchData.razor",
|
||||
"Pages/Index.razor",
|
||||
"Pages/_Host.cshtml",
|
||||
|
|
|
|||
Loading…
Reference in New Issue