gpt4 book ai didi

c# - 仅针对一个请求在现有 HttpClient 中将 AllowAutoRedirect 设置为 false

转载 作者:行者123 更新时间:2023-12-05 01:13:12 27 4
gpt4 key购买 nike

This answer关于如何使 HttpClient 不遵循重定向的问题提供了在创建实际客户端时设置的解决方案:

var handler = new HttpClientHandler { AllowAutoRedirect = false };    
var client = new HttpClient(handler);

答案下方的评论是我的实际问题:

Is it possible to do this on a per-request basis without needing two separate HttpClient instances (i.e. one that allows redirects and one that does not)?

我现在想要单独的客户端也有一个特定的原因:我希望客户端保留其来自早期请求的 cookie。我正在尝试首先执行一些请求,其中包括有效的重定向,但只有 last 链中的一个我不想成为重定向。

我搜索过,查看了.GetAsync(url, ...)的重载,查看了HttpClient的属性和方法,但是发现还没有解决办法。

这可能吗?

最佳答案

问题询问是否可以逐案进行以下重定向。虽然对于许多常见情况肯定有用,但我发现现有的答案在这方面缺乏。

以下实现允许通过谓词根据具体情况来决定是否遵循重定向。解决方法是重写HttpClientHandler的SendAsync()方法。

using System;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

namespace HttpClientCustomRedirectBehavior
{
static class Program
{
private const string REDIRECTING_URL = "http://stackoverflow.com/";

static async Task Main(string[] args)
{
HttpMessageHandler followRedirectAlwaysHandler = new RestrictedRedirectFollowingHttpClientHandler(
response => true);
HttpMessageHandler followRedirectOnlyToSpecificHostHandler = new RestrictedRedirectFollowingHttpClientHandler(
response => response.Headers.Location.Host == "example.com");

HttpResponseMessage response;
using (HttpClient followRedirectAlwaysHttpClient = new HttpClient(followRedirectAlwaysHandler))
{
response = await followRedirectAlwaysHttpClient.GetAsync(REDIRECTING_URL);
Console.WriteLine(response.StatusCode); // OK
}

using (HttpClient followRedirectOnlyToSpecificHostHttpClient = new HttpClient(followRedirectOnlyToSpecificHostHandler))
{
response = await followRedirectOnlyToSpecificHostHttpClient.GetAsync(REDIRECTING_URL);
Console.WriteLine(response.StatusCode); // Moved
}

followRedirectOnlyToSpecificHostHandler = new RestrictedRedirectFollowingHttpClientHandler(
response => response.Headers.Location.Host == "stackoverflow.com");
using (HttpClient followRedirectOnlyToSpecificHostHttpClient = new HttpClient(followRedirectOnlyToSpecificHostHandler))
{
response = await followRedirectOnlyToSpecificHostHttpClient.GetAsync(REDIRECTING_URL);
Console.WriteLine(response.StatusCode); // OK
}
}
}

public class RestrictedRedirectFollowingHttpClientHandler : HttpClientHandler
{
private static readonly HttpStatusCode[] redirectStatusCodes = new[] {
HttpStatusCode.Moved,
HttpStatusCode.Redirect,
HttpStatusCode.RedirectMethod,
HttpStatusCode.TemporaryRedirect,
HttpStatusCode.PermanentRedirect
};

private readonly Predicate<HttpResponseMessage> isRedirectAllowed;

public override bool SupportsRedirectConfiguration { get; }

public RestrictedRedirectFollowingHttpClientHandler(Predicate<HttpResponseMessage> isRedirectAllowed)
{
AllowAutoRedirect = false;
SupportsRedirectConfiguration = false;
this.isRedirectAllowed = response => {
return Array.BinarySearch(redirectStatusCodes, response.StatusCode) >= 0
&& isRedirectAllowed.Invoke(response);
};
}

protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
int redirectCount = 0;
HttpResponseMessage response = await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
while (isRedirectAllowed.Invoke(response)
&& (response.Headers.Location != request.RequestUri || response.StatusCode == HttpStatusCode.RedirectMethod && request.Method != HttpMethod.Get)
&& redirectCount < this.MaxAutomaticRedirections)
{
if (response.StatusCode == HttpStatusCode.RedirectMethod)
{
request.Method = HttpMethod.Get;
}
request.RequestUri = response.Headers.Location;
response = await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
++redirectCount;
}
return response;
}
}
}

Main 方法显示了对 http://stackoverflow.com 的三个示例请求。 (这是一个重定向到 https://stackoverflow.com 的 URI):

  1. 第一个 GET 请求将跟随重定向,因此我们看到对重定向请求的响应的状态代码 OK,因为处理程序配置为跟随所有重定向。
  2. 第二个 GET 请求不会跟随重定向,因此我们会看到状态代码 Moved,因为处理程序配置为仅跟随重定向到主机 example.com。
  3. 第三个 GET 请求将跟随重定向,因此我们看到对重定向请求的响应的状态代码 OK,因为处理程序被配置为仅跟随重定向到主机 stackoverflow.com。

当然,您可以用任何自定义逻辑替换谓词。

关于c# - 仅针对一个请求在现有 HttpClient 中将 AllowAutoRedirect 设置为 false,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60800849/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com