public ProxyConfigManager( ILogger <ProxyConfigManager> logger, IProxyConfigProvider provider, IClusterManager clusterManager, IRouteManager routeManager, IEnumerable <IProxyConfigFilter> filters, IConfigValidator configValidator, ProxyEndpointFactory proxyEndpointFactory, ITransformBuilder transformBuilder, IProxyHttpClientFactory httpClientFactory, IActiveHealthCheckMonitor activeHealthCheckMonitor) { _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _provider = provider ?? throw new ArgumentNullException(nameof(provider)); _clusterManager = clusterManager ?? throw new ArgumentNullException(nameof(clusterManager)); _routeManager = routeManager ?? throw new ArgumentNullException(nameof(routeManager)); _filters = filters ?? throw new ArgumentNullException(nameof(filters)); _configValidator = configValidator ?? throw new ArgumentNullException(nameof(configValidator)); _proxyEndpointFactory = proxyEndpointFactory ?? throw new ArgumentNullException(nameof(proxyEndpointFactory)); _transformBuilder = transformBuilder ?? throw new ArgumentNullException(nameof(transformBuilder)); _httpClientFactory = httpClientFactory ?? throw new ArgumentNullException(nameof(httpClientFactory)); _activeHealthCheckMonitor = activeHealthCheckMonitor ?? throw new ArgumentNullException(nameof(activeHealthCheckMonitor)); _conventions = new List <Action <EndpointBuilder> >(); DefaultBuilder = new ReverseProxyConventionBuilder(_conventions); _changeToken = new CancellationChangeToken(_cancellationTokenSource.Token); }
/// <summary> /// Proxies the incoming request to the upstream server, and the response back to our client. /// </summary> /// <remarks> /// In what follows, as well as throughout in Reverse Proxy, we consider /// the following picture as illustrative of the Proxy. /// <code> /// +-------------------+ /// | Upstream server + /// +-------------------+ /// ▲ | /// (b) | | (c) /// | ▼ /// +-------------------+ /// | Proxy + /// +-------------------+ /// ▲ | /// (a) | | (d) /// | ▼ /// +-------------------+ /// | Downstream client + /// +-------------------+ /// </code> /// /// (a) and (b) show the *request* path, going *upstream* from the client to the target. /// (c) and (d) show the *response* path, going *downstream* from the target back to the client. /// </remarks> /// <param name="longCancellation">This should be linked to a client disconnect notification like <see cref="HttpContext.RequestAborted"/> /// to avoid leaking long running requests.</param> public Task ProxyAsync( HttpContext context, string destinationPrefix, Transforms transforms, IProxyHttpClientFactory httpClientFactory, ProxyTelemetryContext proxyTelemetryContext, CancellationToken shortCancellation, CancellationToken longCancellation) { Contracts.CheckValue(context, nameof(context)); Contracts.CheckValue(destinationPrefix, nameof(destinationPrefix)); Contracts.CheckValue(transforms, nameof(transforms)); Contracts.CheckValue(httpClientFactory, nameof(httpClientFactory)); // ::::::::::::::::::::::::::::::::::::::::::::: // :: Step 1: Create outgoing HttpRequestMessage var upgradeFeature = context.Features.Get <IHttpUpgradeFeature>(); var isUpgrade = upgradeFeature?.IsUpgradableRequest ?? false; // Default to HTTP/1.1 for proxying upgradable requests. This is already the default as of .NET Core 3.1 // Otherwise request HTTP/2 and let HttpClient fallback to HTTP/1.1 if it cannot establish HTTP/2 with the target. // This is done without extra round-trips thanks to ALPN. We can detect a downgrade after calling HttpClient.SendAsync // (see Step 3 below). TBD how this will change when HTTP/3 is supported. var version = isUpgrade ? ProtocolHelper.Http11Version : ProtocolHelper.Http2Version; var request = CreateRequestMessage(context, destinationPrefix, version, transforms.RequestTransforms); if (isUpgrade) { return(UpgradableProxyAsync(context, upgradeFeature, request, transforms, httpClientFactory.CreateUpgradableClient(), proxyTelemetryContext, shortCancellation, longCancellation)); } else { return(NormalProxyAsync(context, request, transforms, httpClientFactory.CreateNormalClient(), proxyTelemetryContext, shortCancellation, longCancellation)); } }
public ClusterInfo(string clusterId, IDestinationManager destinationManager, IProxyHttpClientFactory proxyHttpClientFactory) { ClusterId = clusterId ?? throw new ArgumentNullException(nameof(clusterId)); DestinationManager = destinationManager ?? throw new ArgumentNullException(nameof(destinationManager)); ProxyHttpClientFactory = proxyHttpClientFactory ?? throw new ArgumentNullException(nameof(proxyHttpClientFactory)); DynamicState = CreateDynamicStateQuery(); }
public BackendInfo(string backendId, IEndpointManager endpointManager, IProxyHttpClientFactory proxyHttpClientFactory) { Contracts.CheckNonEmpty(backendId, nameof(backendId)); Contracts.CheckValue(endpointManager, nameof(endpointManager)); Contracts.CheckValue(proxyHttpClientFactory, nameof(proxyHttpClientFactory)); BackendId = backendId; EndpointManager = endpointManager; ProxyHttpClientFactory = proxyHttpClientFactory; DynamicState = CreateDynamicStateQuery(); }
public BackendInfo(string backendId, IDestinationManager destinationManager, IProxyHttpClientFactory proxyHttpClientFactory) { Contracts.CheckNonEmpty(backendId, nameof(backendId)); Contracts.CheckValue(destinationManager, nameof(destinationManager)); Contracts.CheckValue(proxyHttpClientFactory, nameof(proxyHttpClientFactory)); BackendId = backendId; DestinationManager = destinationManager; ProxyHttpClientFactory = proxyHttpClientFactory; DynamicState = CreateDynamicStateQuery(); }
public DynamicHttpProxyInterceptor( DynamicHttpProxyInterceptorClientProxy <TService> interceptorClientProxy, IOptions <AbpHttpClientOptions> clientOptions, IProxyHttpClientFactory httpClientFactory, IRemoteServiceConfigurationProvider remoteServiceConfigurationProvider, IApiDescriptionFinder apiDescriptionFinder) { InterceptorClientProxy = interceptorClientProxy; HttpClientFactory = httpClientFactory; RemoteServiceConfigurationProvider = remoteServiceConfigurationProvider; ApiDescriptionFinder = apiDescriptionFinder; ClientOptions = clientOptions.Value; Logger = NullLogger <DynamicHttpProxyInterceptor <TService> > .Instance; }
public ProxyConfigManager( ILogger <ProxyConfigManager> logger, IProxyConfigProvider provider, IRuntimeRouteBuilder routeEndpointBuilder, IClusterManager clusterManager, IRouteManager routeManager, IEnumerable <IProxyConfigFilter> filters, IConfigValidator configValidator, IProxyHttpClientFactory httpClientFactory) { _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _provider = provider ?? throw new ArgumentNullException(nameof(provider)); _routeEndpointBuilder = routeEndpointBuilder ?? throw new ArgumentNullException(nameof(routeEndpointBuilder)); _clusterManager = clusterManager ?? throw new ArgumentNullException(nameof(clusterManager)); _routeManager = routeManager ?? throw new ArgumentNullException(nameof(routeManager)); _filters = filters ?? throw new ArgumentNullException(nameof(filters)); _configValidator = configValidator ?? throw new ArgumentNullException(nameof(configValidator)); _httpClientFactory = httpClientFactory ?? throw new ArgumentNullException(nameof(httpClientFactory)); _changeToken = new CancellationChangeToken(_cancellationTokenSource.Token); }
/// <summary> /// Proxies the incoming request to the upstream server, and the response back to our client. /// </summary> /// <remarks> /// In what follows, as well as throughout in Reverse Proxy, we consider /// the following picture as illustrative of the Proxy. /// <code> /// +-------------------+ /// | Upstream server + /// +-------------------+ /// ▲ | /// (b) | | (c) /// | ▼ /// +-------------------+ /// | Proxy + /// +-------------------+ /// ▲ | /// (a) | | (d) /// | ▼ /// +-------------------+ /// | Downstream client + /// +-------------------+ /// </code> /// /// (a) and (b) show the *request* path, going *upstream* from the client to the target. /// (c) and (d) show the *response* path, going *downstream* from the target back to the client. /// </remarks> /// <param name="longCancellation">This should be linked to a client disconnect notification like <see cref="HttpContext.RequestAborted"/> /// to avoid leaking long running requests.</param> public Task ProxyAsync( HttpContext context, Uri targetUri, IProxyHttpClientFactory httpClientFactory, ProxyTelemetryContext proxyTelemetryContext, CancellationToken shortCancellation, CancellationToken longCancellation) { Contracts.CheckValue(context, nameof(context)); Contracts.CheckValue(targetUri, nameof(targetUri)); Contracts.CheckValue(httpClientFactory, nameof(httpClientFactory)); var upgradeFeature = context.Features.Get <IHttpUpgradeFeature>(); if (upgradeFeature == null || !upgradeFeature.IsUpgradableRequest) { return(NormalProxyAsync(context, targetUri, httpClientFactory.CreateNormalClient(), proxyTelemetryContext, shortCancellation, longCancellation)); } else { return(UpgradableProxyAsync(context, upgradeFeature, targetUri, httpClientFactory.CreateUpgradableClient(), proxyTelemetryContext, shortCancellation, longCancellation)); } }
/// <summary> /// Proxies the incoming request to the upstream server, and the response back to our client. /// </summary> /// <remarks> /// In what follows, as well as throughout in Reverse Proxy, we consider /// the following picture as illustrative of the Proxy. /// <code> /// +-------------------+ /// | Upstream server + /// +-------------------+ /// ▲ | /// (b) | | (c) /// | ▼ /// +-------------------+ /// | Proxy + /// +-------------------+ /// ▲ | /// (a) | | (d) /// | ▼ /// +-------------------+ /// | Downstream client + /// +-------------------+ /// </code> /// /// (a) and (b) show the *request* path, going *upstream* from the client to the target. /// (c) and (d) show the *response* path, going *downstream* from the target back to the client. /// </remarks> /// <param name="longCancellation">This should be linked to a client disconnect notification like <see cref="HttpContext.RequestAborted"/> /// to avoid leaking long running requests.</param> public Task ProxyAsync( HttpContext context, string destinationPrefix, Transforms transforms, IProxyHttpClientFactory httpClientFactory, ProxyTelemetryContext proxyTelemetryContext, CancellationToken shortCancellation, CancellationToken longCancellation) { _ = context ?? throw new ArgumentNullException(nameof(context)); _ = destinationPrefix ?? throw new ArgumentNullException(nameof(destinationPrefix)); _ = transforms ?? throw new ArgumentNullException(nameof(transforms)); _ = httpClientFactory ?? throw new ArgumentNullException(nameof(httpClientFactory)); // ::::::::::::::::::::::::::::::::::::::::::::: // :: Step 1: Create outgoing HttpRequestMessage var upgradeFeature = context.Features.Get <IHttpUpgradeFeature>(); var isUpgrade = (upgradeFeature?.IsUpgradableRequest ?? false) // Mitigate https://github.com/microsoft/reverse-proxy/issues/255, IIS considers all requests upgradeable. && string.Equals("WebSocket", context.Request.Headers[HeaderNames.Upgrade], StringComparison.OrdinalIgnoreCase); // Default to HTTP/1.1 for proxying upgradeable requests. This is already the default as of .NET Core 3.1 // Otherwise request HTTP/2 and let HttpClient fallback to HTTP/1.1 if it cannot establish HTTP/2 with the target. // This is done without extra round-trips thanks to ALPN. We can detect a downgrade after calling HttpClient.SendAsync // (see Step 3 below). TBD how this will change when HTTP/3 is supported. var version = isUpgrade ? ProtocolHelper.Http11Version : ProtocolHelper.Http2Version; var request = CreateRequestMessage(context, destinationPrefix, version, transforms.RequestTransforms); if (isUpgrade) { return(UpgradableProxyAsync(context, upgradeFeature, request, transforms, httpClientFactory.CreateClient(), proxyTelemetryContext, shortCancellation, longCancellation)); } else { return(NormalProxyAsync(context, request, transforms, httpClientFactory.CreateClient(), proxyTelemetryContext, shortCancellation, longCancellation)); } }
public ProxyMiddleware(RequestDelegate nextMiddleware, T serviceProxy, ILogger <ProxyMiddleware <T> > logger, IProxyHttpClientFactory clientFactory) { _nextMiddleware = nextMiddleware; _serviceProxy = serviceProxy; _logger = logger; _httpClient = clientFactory.Create(serviceProxy.DisableTlsVerification()); }