Skip to content

Commit

Permalink
[Wasm] Moves wasm reload logic out of ASP.NET Core and into the SDK (d…
Browse files Browse the repository at this point in the history
…otnet#42549)

Moves the logic for setting environment variables from ASP.NET Core to the BrowserRefresh middleware in the SDK for webassembly support.
  • Loading branch information
javiercn authored Aug 7, 2024
1 parent 39c3fc2 commit e001cc1
Show file tree
Hide file tree
Showing 2 changed files with 479 additions and 2 deletions.
95 changes: 93 additions & 2 deletions src/BuiltInTools/BrowserRefresh/BrowserRefreshMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,27 @@ namespace Microsoft.AspNetCore.Watch.BrowserRefresh
public class BrowserRefreshMiddleware
{
private static readonly MediaTypeHeaderValue _textHtmlMediaType = new("text/html");
private static readonly MediaTypeHeaderValue _applicationJsonMediaType = new("application/json");
private readonly string? _dotnetModifiableAssemblies = GetNonEmptyEnvironmentVariableValue("DOTNET_MODIFIABLE_ASSEMBLIES");
private readonly string? _aspnetcoreBrowserTools = GetNonEmptyEnvironmentVariableValue("__ASPNETCORE_BROWSER_TOOLS");

private readonly RequestDelegate _next;
private readonly ILogger _logger;

private static string? GetNonEmptyEnvironmentVariableValue(string name)
=> Environment.GetEnvironmentVariable(name) is { Length: > 0 } value ? value : null;

public BrowserRefreshMiddleware(RequestDelegate next, ILogger<BrowserRefreshMiddleware> logger) =>
(_next, _logger) = (next, logger);

public async Task InvokeAsync(HttpContext context)
{
// We only need to support this for requests that could be initiated by a browser.
if (IsBrowserDocumentRequest(context))
if (IsWebAssemblyBootRequest(context))
{
AttachWebAssemblyHeaders(context);
await _next(context);
}
else if (IsBrowserDocumentRequest(context))
{
// Use a custom StreamWrapper to rewrite output on Write/WriteAsync
using var responseStreamWrapper = new ResponseStreamWrapper(context, _logger);
Expand Down Expand Up @@ -59,6 +70,86 @@ public async Task InvokeAsync(HttpContext context)
}
}

private void AttachWebAssemblyHeaders(HttpContext context)
{
context.Response.OnStarting(() =>
{
if (!context.Response.Headers.ContainsKey("DOTNET-MODIFIABLE-ASSEMBLIES"))
{
if(_dotnetModifiableAssemblies != null)
{
context.Response.Headers.Add("DOTNET-MODIFIABLE-ASSEMBLIES", _dotnetModifiableAssemblies);
}
else
{
_logger.LogDebug("DOTNET_MODIFIABLE_ASSEMBLIES environment variable is not set, likely because hot reload is not enabled. The browser refresh feature may not work as expected.");
}
}
else
{
_logger.LogDebug("DOTNET-MODIFIABLE-ASSEMBLIES header is already set.");
}
if (!context.Response.Headers.ContainsKey("ASPNETCORE-BROWSER-TOOLS"))
{
if (_aspnetcoreBrowserTools != null)
{
context.Response.Headers.Add("ASPNETCORE-BROWSER-TOOLS", _aspnetcoreBrowserTools);
}
else
{
_logger.LogDebug("__ASPNETCORE_BROWSER_TOOLS environment variable is not set. The browser refresh feature may not work as expected.");
}
}
else
{
_logger.LogDebug("ASPNETCORE-BROWSER-TOOLS header is already set.");
}
return Task.CompletedTask;
});
}

internal static bool IsWebAssemblyBootRequest(HttpContext context)
{
var request = context.Request;
if (!HttpMethods.IsGet(request.Method))
{
return false;
}

if (request.Headers.TryGetValue("Sec-Fetch-Dest", out var values) &&
!StringValues.IsNullOrEmpty(values) &&
!string.Equals(values[0], "document", StringComparison.OrdinalIgnoreCase))
{
// See https://github.com/dotnet/aspnetcore/issues/37326.
// Only inject scripts that are destined for a browser page.
return false;
}

if (!request.Path.HasValue ||
!string.Equals(Path.GetFileName(request.Path.Value), "blazor.boot.json", StringComparison.OrdinalIgnoreCase))
{
return false;
}

var typedHeaders = request.GetTypedHeaders();
if (typedHeaders.Accept is not IList<MediaTypeHeaderValue> acceptHeaders)
{
return false;
}

for (var i = 0; i < acceptHeaders.Count; i++)
{
if (acceptHeaders[i].IsSubsetOf(_applicationJsonMediaType))
{
return true;
}
}

return false;
}

internal static bool IsBrowserDocumentRequest(HttpContext context)
{
var request = context.Request;
Expand Down
Loading

0 comments on commit e001cc1

Please sign in to comment.