mirror of
https://github.com/aspnet/JavaScriptServices.git
synced 2025-12-22 17:47:53 +00:00
Revert "Webpack HMR EventSource requests are now proxied (rather than redirected) to the local HMR server" because of 'ECANCELED'/'EPIPE broken pipe' issues. Awaiting feedback from Kestrel team.
This commit is contained in:
@@ -30,7 +30,6 @@ namespace Microsoft.AspNetCore.SpaServices.Webpack
|
|||||||
_pathPrefix = pathPrefix;
|
_pathPrefix = pathPrefix;
|
||||||
_options = options;
|
_options = options;
|
||||||
_httpClient = new HttpClient(new HttpClientHandler());
|
_httpClient = new HttpClient(new HttpClientHandler());
|
||||||
_httpClient.Timeout = _options.RequestTimeout;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Invoke(HttpContext context)
|
public async Task Invoke(HttpContext context)
|
||||||
|
|||||||
@@ -1,20 +1,16 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.SpaServices.Webpack
|
namespace Microsoft.AspNetCore.SpaServices.Webpack
|
||||||
{
|
{
|
||||||
internal class ConditionalProxyMiddlewareOptions
|
internal class ConditionalProxyMiddlewareOptions
|
||||||
{
|
{
|
||||||
public ConditionalProxyMiddlewareOptions(string scheme, string host, string port, TimeSpan requestTimeout)
|
public ConditionalProxyMiddlewareOptions(string scheme, string host, string port)
|
||||||
{
|
{
|
||||||
Scheme = scheme;
|
Scheme = scheme;
|
||||||
Host = host;
|
Host = host;
|
||||||
Port = port;
|
Port = port;
|
||||||
RequestTimeout = requestTimeout;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Scheme { get; }
|
public string Scheme { get; }
|
||||||
public string Host { get; }
|
public string Host { get; }
|
||||||
public string Port { get; }
|
public string Port { get; }
|
||||||
public TimeSpan RequestTimeout { get; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,7 +7,6 @@ using Microsoft.AspNetCore.Builder;
|
|||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.Extensions.PlatformAbstractions;
|
using Microsoft.Extensions.PlatformAbstractions;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System.Threading;
|
|
||||||
|
|
||||||
// Putting in this namespace so it's always available whenever MapRoute is
|
// Putting in this namespace so it's always available whenever MapRoute is
|
||||||
|
|
||||||
@@ -15,6 +14,8 @@ namespace Microsoft.AspNetCore.Builder
|
|||||||
{
|
{
|
||||||
public static class WebpackDevMiddleware
|
public static class WebpackDevMiddleware
|
||||||
{
|
{
|
||||||
|
private const string WebpackDevMiddlewareScheme = "http";
|
||||||
|
private const string WebpackHotMiddlewareEndpoint = "/__webpack_hmr";
|
||||||
private const string DefaultConfigFile = "webpack.config.js";
|
private const string DefaultConfigFile = "webpack.config.js";
|
||||||
|
|
||||||
public static void UseWebpackDevMiddleware(
|
public static void UseWebpackDevMiddleware(
|
||||||
@@ -61,27 +62,30 @@ namespace Microsoft.AspNetCore.Builder
|
|||||||
JsonConvert.SerializeObject(devServerOptions)).Result;
|
JsonConvert.SerializeObject(devServerOptions)).Result;
|
||||||
|
|
||||||
// Proxy the corresponding requests through ASP.NET and into the Node listener
|
// Proxy the corresponding requests through ASP.NET and into the Node listener
|
||||||
// Anything under /<publicpath> (e.g., /dist) is proxied as a normal HTTP request with a typical timeout (100s is the default from HttpClient),
|
|
||||||
// plus /__webpack_hmr is proxied with infinite timeout, because it's an EventSource (long-lived request).
|
|
||||||
appBuilder.UseProxyToLocalWebpackDevMiddleware(devServerInfo.PublicPath, devServerInfo.Port, TimeSpan.FromSeconds(100));
|
|
||||||
appBuilder.UseProxyToLocalWebpackDevMiddleware("/__webpack_hmr", devServerInfo.Port, Timeout.InfiniteTimeSpan);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void UseProxyToLocalWebpackDevMiddleware(this IApplicationBuilder appBuilder, string publicPath, int proxyToPort, TimeSpan requestTimeout)
|
|
||||||
{
|
|
||||||
// Note that this is hardcoded to make requests to "localhost" regardless of the hostname of the
|
// Note that this is hardcoded to make requests to "localhost" regardless of the hostname of the
|
||||||
// server as far as the client is concerned. This is because ConditionalProxyMiddlewareOptions is
|
// server as far as the client is concerned. This is because ConditionalProxyMiddlewareOptions is
|
||||||
// the one making the internal HTTP requests, and it's going to be to some port on this machine
|
// the one making the internal HTTP requests, and it's going to be to some port on this machine
|
||||||
// because aspnet-webpack hosts the dev server there. We can't use the hostname that the client
|
// because aspnet-webpack hosts the dev server there. We can't use the hostname that the client
|
||||||
// sees, because that could be anything (e.g., some upstream load balancer) and we might not be
|
// sees, because that could be anything (e.g., some upstream load balancer) and we might not be
|
||||||
// able to make outbound requests to it from here.
|
// able to make outbound requests to it from here.
|
||||||
// Also note that the webpack HMR service always uses HTTP, even if your app server uses HTTPS,
|
var proxyOptions = new ConditionalProxyMiddlewareOptions(WebpackDevMiddlewareScheme,
|
||||||
// because the HMR service has no need for HTTPS (the client doesn't see it directly - all traffic
|
"localhost", devServerInfo.Port.ToString());
|
||||||
// to it is proxied), and the HMR service couldn't use HTTPS anyway (in general it wouldn't have
|
appBuilder.UseMiddleware<ConditionalProxyMiddleware>(devServerInfo.PublicPath, proxyOptions);
|
||||||
// the necessary certificate).
|
|
||||||
var proxyOptions = new ConditionalProxyMiddlewareOptions(
|
// While it would be nice to proxy the /__webpack_hmr requests too, these return an EventStream,
|
||||||
"http", "localhost", proxyToPort.ToString(), requestTimeout);
|
// and the Microsoft.AspNetCore.Proxy code doesn't handle that entirely - it throws an exception after
|
||||||
appBuilder.UseMiddleware<ConditionalProxyMiddleware>(publicPath, proxyOptions);
|
// a while. So, just serve a 302 for those. But note that we must use the hostname that the client
|
||||||
|
// sees, not "localhost", so that it works even when you're not running on localhost (e.g., Docker).
|
||||||
|
appBuilder.Map(WebpackHotMiddlewareEndpoint, builder =>
|
||||||
|
{
|
||||||
|
builder.Use(next => ctx =>
|
||||||
|
{
|
||||||
|
var hostname = ctx.Request.Host.Host;
|
||||||
|
ctx.Response.Redirect(
|
||||||
|
$"{WebpackDevMiddlewareScheme}://{hostname}:{devServerInfo.Port.ToString()}{WebpackHotMiddlewareEndpoint}");
|
||||||
|
return Task.FromResult(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma warning disable CS0649
|
#pragma warning disable CS0649
|
||||||
|
|||||||
Reference in New Issue
Block a user