Add extension methods for adding direct forwarding to the ASP.NET Core request pipeline (#1972) (#1979)
This commit is contained in:
Родитель
f26d0f1d32
Коммит
b9b2bb4dbe
|
@ -98,6 +98,23 @@ private class CustomTransformer : HttpTransformer
|
|||
}
|
||||
```
|
||||
|
||||
There are also [extension methods](xref:Microsoft.AspNetCore.Builder.DirectForwardingIEndpointRouteBuilderExtensions) available that simplify the mapping of IHttpForwarder to endpoints.
|
||||
|
||||
```C#
|
||||
...
|
||||
|
||||
public void Configure(IApplicationBuilder app, IHttpForwarder forwarder)
|
||||
{
|
||||
...
|
||||
|
||||
app.UseRouting();
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapForwarder("/{**catch-all}", "https://localhost:10000/", requestConfig, transformer, httpClient);
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### The HTTP Client
|
||||
|
||||
The http client may be customized, but the above example is recommended for common proxy scenarios.
|
||||
|
|
|
@ -48,6 +48,9 @@ namespace Yarp.Sample
|
|||
var requestOptions = new ForwarderRequestConfig { ActivityTimeout = TimeSpan.FromSeconds(100) };
|
||||
|
||||
app.UseRouting();
|
||||
|
||||
// When using IHttpForwarder for direct forwarding you are responsible for routing, destination discovery, load balancing, affinity, etc..
|
||||
// For an alternate example that includes those features see BasicYarpSample.
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.Map("/test/{**catch-all}", async httpContext =>
|
||||
|
@ -78,18 +81,8 @@ namespace Yarp.Sample
|
|||
});
|
||||
|
||||
|
||||
// When using IHttpForwarder for direct forwarding you are responsible for routing, destination discovery, load balancing, affinity, etc..
|
||||
// For an alternate example that includes those features see BasicYarpSample.
|
||||
endpoints.Map("/{**catch-all}", async httpContext =>
|
||||
{
|
||||
var error = await forwarder.SendAsync(httpContext, "https://example.com", httpClient, requestOptions, transformer);
|
||||
// Check if the proxy operation was successful
|
||||
if (error != ForwarderError.None)
|
||||
{
|
||||
var errorFeature = httpContext.Features.Get<IForwarderErrorFeature>();
|
||||
var exception = errorFeature.Exception;
|
||||
}
|
||||
});
|
||||
// When using extension methods for registering IHttpForwarder providing configuration, transforms, and HttpMessageInvoker is optional (defaults will be used).
|
||||
endpoints.MapForwarder("/{**catch-all}", "https://example.com", requestOptions, transformer, httpClient);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System.Net.Http;
|
||||
using Yarp.ReverseProxy.Configuration;
|
||||
|
||||
namespace Yarp.ReverseProxy.Forwarder;
|
||||
|
||||
internal sealed class DirectForwardingHttpClientProvider
|
||||
{
|
||||
public HttpMessageInvoker HttpClient { get; }
|
||||
|
||||
public DirectForwardingHttpClientProvider() : this(new ForwarderHttpClientFactory()) { }
|
||||
|
||||
public DirectForwardingHttpClientProvider(IForwarderHttpClientFactory factory)
|
||||
{
|
||||
HttpClient = factory.CreateClient(new ForwarderHttpClientContext
|
||||
{
|
||||
NewConfig = HttpClientConfig.Empty
|
||||
});
|
||||
}
|
||||
}
|
|
@ -31,6 +31,9 @@ public static class ReverseProxyServiceCollectionExtensions
|
|||
services.TryAddSingleton<IClock, Clock>();
|
||||
services.TryAddSingleton<IHttpForwarder, HttpForwarder>();
|
||||
services.TryAddSingleton<ITransformBuilder, TransformBuilder>();
|
||||
|
||||
services.AddSingleton<DirectForwardingHttpClientProvider>();
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Yarp.ReverseProxy.Forwarder;
|
||||
|
||||
namespace Microsoft.AspNetCore.Builder;
|
||||
|
||||
/// <summary>
|
||||
/// Extension methods for <see cref="IEndpointRouteBuilder"/> used to add direct forwarding to the ASP.NET Core request pipeline.
|
||||
/// </summary>
|
||||
public static class DirectForwardingIEndpointRouteBuilderExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds direct forwarding of HTTP requests that match the specified pattern to a specific destination using default configuration for the outgoing request, default transforms, and default HTTP client.
|
||||
/// </summary>
|
||||
public static IEndpointConventionBuilder MapForwarder(this IEndpointRouteBuilder endpoints, string pattern, string destinationPrefix)
|
||||
{
|
||||
return endpoints.MapForwarder(pattern, destinationPrefix, ForwarderRequestConfig.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds direct forwarding of HTTP requests that match the specified pattern to a specific destination using customized configuration for the outgoing request, default transforms, and default HTTP client.
|
||||
/// </summary>
|
||||
public static IEndpointConventionBuilder MapForwarder(this IEndpointRouteBuilder endpoints, string pattern, string destinationPrefix, ForwarderRequestConfig requestConfig)
|
||||
{
|
||||
return endpoints.MapForwarder(pattern, destinationPrefix, requestConfig, HttpTransformer.Default);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds direct forwarding of HTTP requests that match the specified pattern to a specific destination using customized configuration for the outgoing request, customized transforms, and default HTTP client.
|
||||
/// </summary>
|
||||
public static IEndpointConventionBuilder MapForwarder(this IEndpointRouteBuilder endpoints, string pattern, string destinationPrefix, ForwarderRequestConfig requestConfig, HttpTransformer transformer)
|
||||
{
|
||||
var httpClientProvider = endpoints.ServiceProvider.GetRequiredService<DirectForwardingHttpClientProvider>();
|
||||
|
||||
return endpoints.MapForwarder(pattern, destinationPrefix, requestConfig, transformer, httpClientProvider.HttpClient);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds direct forwarding of HTTP requests that match the specified pattern to a specific destination using customized configuration for the outgoing request, customized transforms, and customized HTTP client.
|
||||
/// </summary>
|
||||
public static IEndpointConventionBuilder MapForwarder(this IEndpointRouteBuilder endpoints, string pattern, string destinationPrefix, ForwarderRequestConfig requestConfig, HttpTransformer transformer, HttpMessageInvoker httpClient)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(endpoints);
|
||||
ArgumentNullException.ThrowIfNull(destinationPrefix);
|
||||
ArgumentNullException.ThrowIfNull(httpClient);
|
||||
ArgumentNullException.ThrowIfNull(requestConfig);
|
||||
ArgumentNullException.ThrowIfNull(transformer);
|
||||
|
||||
var forwarder = endpoints.ServiceProvider.GetRequiredService<IHttpForwarder>();
|
||||
|
||||
return endpoints.Map(pattern, async httpContext =>
|
||||
{
|
||||
await forwarder.SendAsync(httpContext, destinationPrefix, httpClient, requestConfig, transformer);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -30,7 +30,7 @@ public class Startup
|
|||
/// <summary>
|
||||
/// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
/// </summary>
|
||||
public void Configure(IApplicationBuilder app, IHttpForwarder httpProxy)
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
var httpClient = new HttpMessageInvoker(new SocketsHttpHandler()
|
||||
{
|
||||
|
@ -56,16 +56,7 @@ public class Startup
|
|||
app.UseRouting();
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.Map("/{**catch-all}", async httpContext =>
|
||||
{
|
||||
await httpProxy.SendAsync(httpContext, "https://example.com", httpClient, requestConfig, transformer);
|
||||
var errorFeature = httpContext.GetForwarderErrorFeature();
|
||||
if (errorFeature is not null)
|
||||
{
|
||||
var error = errorFeature.Error;
|
||||
var exception = errorFeature.Exception;
|
||||
}
|
||||
});
|
||||
endpoints.MapForwarder("/{**catch-all}", "https://example.com", requestConfig, transformer, httpClient);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче