Merge remote-tracking branch 'origin/release/3.1'

This commit is contained in:
Pranav K 2020-06-11 15:52:06 -07:00
commit ea4b52ccba
No known key found for this signature in database
GPG Key ID: F748807460A27E91
9 changed files with 123 additions and 30 deletions

View File

@ -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.
}
}
}

View File

@ -163,7 +163,7 @@
<WriteLinesToFile
File="$(_CombinedHashIntermediatePath)"
Lines="@(_ServiceWorkerAssetsManifestItemWithHash->'%(FileHash)')"
Lines="@(_ServiceWorkerAssetsManifestItemWithHash->'%(Integrity)')"
WriteOnlyWhenDifferent="true"
Overwrite="true" />

View File

@ -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);
}
}
}

View File

@ -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);

View File

@ -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);

View File

@ -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>

View File

@ -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>

View File

@ -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)

View File

@ -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",