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

2023-12-04

这个答案关于如何制作的问题HttpClient不遵循重定向给出了在创建实际客户端时设置的解决方案:

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

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

是否可以根据每个请求执行此操作不需要两个单独的 HttpClient 实例(即一个允许重定向,一个不允许重定向)?

我现在也有一个具体的原因想要单独的客户端:我希望客户端保留早期请求中的 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(这是一个重定向到的 URIhttps://stackoverflow.com):

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

仅针对一个请求在现有 HttpClient 中将 AllowAutoRedirect 设置为 false 的相关文章

  • BASIC 中的 C 语言中的 PeekInt、PokeInt、Peek、Poke 等效项

    我想知道该命令的等效项是什么Peek and Poke 基本和其他变体 用 C 语言 类似PeekInt PokeInt 整数 涉及内存条的东西 我知道在 C 语言中有很多方法可以做到这一点 我正在尝试将基本程序移植到 C 语言 这只是使用
  • 类型中的属性名称必须是唯一的

    我正在使用 Entity Framework 5 并且有以下实体 public class User public Int32 Id get set public String Username get set public virtual
  • C++11 删除重写方法

    Preface 这是一个关于最佳实践的问题 涉及 C 11 中引入的删除运算符的新含义 当应用于覆盖继承父类的虚拟方法的子类时 背景 根据标准 引用的第一个用例是明确禁止调用某些类型的函数 否则转换将是隐式的 例如最新版本第 8 4 3 节
  • -webkit-box-shadow 与 QtWebKit 模糊?

    当时有什么方法可以实现 webkit box shadow 的工作模糊吗 看完这篇评论错误报告 https bugs webkit org show bug cgi id 23291 我认识到这仍然是一个问题 尽管错误报告被标记为RESOL
  • C++ 多行字符串原始文字[重复]

    这个问题在这里已经有答案了 我们可以像这样定义一个多行字符串 const char text1 part 1 part 2 part 3 part 4 const char text2 part 1 part 2 part 3 part 4
  • 需要帮助优化算法 - 两百万以下所有素数的总和

    我正在尝试做一个欧拉计划 http projecteuler net问题 我正在寻找 2 000 000 以下所有素数的总和 这就是我所拥有的 int main int argc char argv unsigned long int su
  • 访问外部窗口句柄

    我当前正在处理的程序有问题 这是由于 vista Windows 7 中增强的安全性引起的 特别是 UIPI 它阻止完整性级别较低的窗口与较高完整性级别的窗口 对话 就我而言 我想告诉具有高完整性级别的窗口进入我们的应用程序 它在 XP 或
  • ASP.NET Core 3.1登录后如何获取用户信息

    我试图在登录 ASP NET Core 3 1 后获取用户信息 如姓名 电子邮件 id 等信息 这是我在登录操作中的代码 var claims new List
  • 使用 C# 中的 CsvHelper 将不同文化的 csv 解析为十进制

    C 中 CsvHelper 解析小数的问题 我创建了一个从 byte 而不是文件获取 csv 文件的类 并且它工作正常 public static List
  • 两个静态变量同名(两个不同的文件),并在任何其他文件中 extern 其中一个

    在一个文件中将变量声明为 static 并在另一个文件中进行 extern 声明 我认为这会在链接时出现错误 因为 extern 变量不会在任何对象中看到 因为在其他文件中声明的变量带有限定符 static 但不知何故 链接器 瑞萨 没有显
  • C 编程:带有数组的函数

    我正在尝试编写一个函数 该函数查找行为 4 列为 4 的二维数组中的最大值 其中二维数组填充有用户输入 我知道我的主要错误是函数中的数组 但我不确定它是什么 如果有人能够找到我出错的地方而不是编写新代码 我将不胜感激 除非我刚去南方 我的尝
  • 空指针与 int 等价

    Bjarne 在 C 编程语言 中写道 空指针与整数零不同 但 0 可以用作空指针的指针初始值设定项 这是否意味着 void voidPointer 0 int zero 0 int castPointer reinterpret cast
  • 如何在 Android 中使用 C# 生成的 RSA 公钥?

    我想在无法假定 HTTPS 可用的情况下确保 Android 应用程序和 C ASP NET 服务器之间的消息隐私 我想使用 RSA 来加密 Android 设备首次联系服务器时传输的对称密钥 RSA密钥对已在服务器上生成 私钥保存在服务器
  • 在 WPF 中使用 ReactiveUI 提供长时间运行命令反馈的正确方法

    我有一个 C WPF NET 4 5 应用程序 用户将用它来打开某些文件 然后 应用程序将经历很多动作 读取文件 通过许多插件和解析器传递它 这些文件可能相当大 gt 100MB 因此这可能需要一段时间 我想让用户了解 UI 中发生的情况
  • 相当于Linux中的导入库

    在 Windows C 中 当您想要链接 DLL 时 您必须提供导入库 但是在 GNU 构建系统中 当您想要链接 so 文件 相当于 dll 时 您就不需要链接 为什么是这样 是否有等效的 Windows 导入库 注意 我不会谈论在 Win
  • C# 中的 IPC 机制 - 用法和最佳实践

    不久前我在 Win32 代码中使用了 IPC 临界区 事件和信号量 NET环境下场景如何 是否有任何教程解释所有可用选项以及何时使用以及为什么 微软最近在IPC方面的东西是Windows 通信基础 http en wikipedia org
  • 为什么C++代码执行速度比java慢?

    我最近用 Java 编写了一个计算密集型算法 然后将其翻译为 C 令我惊讶的是 C 的执行速度要慢得多 我现在已经编写了一个更短的 Java 测试程序和一个相应的 C 程序 见下文 我的原始代码具有大量数组访问功能 测试代码也是如此 C 的
  • C# 使用“?” if else 语句设置值这叫什么

    嘿 我刚刚看到以下声明 return name null name NA 我只是想知道这在 NET 中叫什么 是吗 代表即然后执行此操作 这是一个俗称的 条件运算符 三元运算符 http en wikipedia org wiki Tern
  • 类型或命名空间“MyNamespace”不存在等

    我有通常的类型或命名空间名称不存在错误 除了我引用了程序集 using 语句没有显示为不正确 并且我引用的类是公共的 事实上 我在不同的解决方案中引用并使用相同的程序集来执行相同的操作 并且效果很好 顺便说一句 这是VS2010 有人有什么
  • Mono 应用程序在非阻塞套接字发送时冻结

    我在 debian 9 上的 mono 下运行一个服务器应用程序 大约有 1000 2000 个客户端连接 并且应用程序经常冻结 CPU 使用率达到 100 我执行 kill QUIT pid 来获取线程堆栈转储 但它总是卡在这个位置

随机推荐

  • CSS 中的 + 是什么意思? [复制]

    这个问题在这里已经有答案了 什么是 这个CSS规则是什么意思 h2 p font size 1 4em font weight bold color 777 is the 相邻兄弟组合器 这意味着选择器h2 p只选择p那来了之后立马 an
  • 如何使用正则表达式删除美元格式

    我试图从字符串 1 109 889 23 中删除美元格式 我尝试使用正则表达式 d 但后来我得到了逗号 有什么帮助吗 提前致谢 您不需要为此使用正则表达式 只需使用lsParseCurrency numericValue lsParseCu
  • 如何将 IMFSample 发送到 EVR 媒体接收器

    我想独立使用 EVR 但无法向其发送 IMFSample 下面列出了代码 create the video render IMFActivate pActive NULL hr MFCreateVideoRendererActivate m
  • 如何在shell中检查字符串是否包含正则表达式模式中的字符?

    如何检查变量是否包含字符 regex other than 0 9a z and 在纯bash中 我需要有条件检查 如果字符串包含除上述可接受的字符之外的字符exit 1 一种方法是使用grep命令 像这样 grep qv 0 9a z l
  • 用于双向关联的 @ManyToMany/@OneToMany 映射属性

    我正在为实习开发 JPA 合规性套件 该套件的一部分涉及测试极端情况的正确实现 ManyToMany有一个mappedBy属性 JPA 指出 字符串mappedBy 拥有关系的字段或属性 必需的 除非关系是单向的 未给出默认值 默认列为空
  • PHP $_GET 和 .htaccess 重写

    我知道这可能是一个常见问题 并且之前已被问过 但 htaccess 对我来说看起来很陌生 而且我似乎无法通过查看以前的问题来解决这个问题 我有一个用于搜索的索引脚本 语法是 listing field property type query
  • 获取函数的返回类型

    我有以下功能 function test number return 42 我可以通过使用获取函数的类型typeof type t typeof test Here t将 gt number 有没有办法获取函数的返回类型 我想t to be
  • C++ 仿函数作为函数指针

    我有一个函子 我需要将其发送到一个接收函数指针作为参数的函数 例如CreateThread 我可以以某种方式将其转换为静态方法地址吗 如果没有 我该怎么做 不 您不能将类类型对象转换为函数指针 但是 您可以编写一个非成员包装函数来调用正确实
  • 确定 .class 文件中引用的类

    以编程方式 解析已编译的 Java class 文件并生成它引用的任何和所有其他 Java 类的列表的最佳方法是什么 如果你知道的话 自己做很容易the spec 这是一个快速而肮脏的演示程序如何做到这一点 package test imp
  • 在 IIS7 中启用 net.tcp

    我怎样才能让IIS句柄net tcp连接 你需要添加net tcp到您站点启用的协议 转到 IIS 管理器 右键单击您的网站 转到 管理网站 或 管理应用程序 然后转到 高级设置 在那里您会看到 启用的协议 它可能说http 将其更改为ht
  • 从集合/数组/列表创建逗号分隔字符串的最复杂方法?

    在使用数据库期间 我注意到我编写了查询字符串 并且在该字符串中 我必须在列表 数组 集合的 where 子句中添加一些限制 应该看起来像这样 select from customer where customer id in 34 26 2
  • 电报无法使用 ndk 18 编译

    当我尝试使用 android studio 3 2 编译 telegram 时 出现错误 Android NDK 无效的 NDK TOOLCHAIN VERSION 值 4 9 不再支持海湾合作委员会 我知道 从 android ndk 1
  • R:按 n 分割数据集

    我有一个像这样的数据集 day group1 group2 group3 1 12 23 23 2 23 12 21 3 17 19 8 4 16 32 32 5 10 13 12 我想将数据集分成几天1 7 8 14 14 20等等 并对
  • AWS Glue - 如何使用 BOTO3 更改 Glue Catalog 表中的列名称?

    我正在使用 AWS Glue 爬网程序读取 S3 zip 文件 无标头 并填充 Glue 目录 列默认命名为 col 0 col 1 如何使用例如更改这些列名称python boto3 模块并直接与 AWS Glue 目录交互 有执行此操作
  • 如何在流式传输 PDF 附件时强制显示“另存为”对话框

    我使用以下代码将 pdf 流式传输到浏览器 header Cache Control must revalidate post check 0 pre check 0 header Pragma public header Content
  • 如何避免 JavaScript 中的异步函数?

    function CanPurchase return new Promise function resolve reject var name document getElementById name value var civilNum
  • 将图例添加到 Altair 图表中的折线图和条形图,而不使用尺寸/颜色

    我正在使用 Altair 创建一个包含多条线的图表 每条线都有多个波段 代表不同的 CI 并且我正在努力了解如何添加图例 例如 在这个相当简单的示例中 import altair as alt import pandas as pd df
  • JSP自定义标签库(传递属性)

    我尝试在自定义标签中使用多个属性 例如
  • Firefox 中 href="file://///..." 的解决方法

    在 Intranet 站点上 假设我想使用 UNC 链接到共享上的文件 地址为 servername foldername filename rtf 执行此操作的正确方法似乎是使用如下标记 a href filename rtf a 这是五
  • 仅针对一个请求在现有 HttpClient 中将 AllowAutoRedirect 设置为 false

    这个答案关于如何制作的问题HttpClient不遵循重定向给出了在创建实际客户端时设置的解决方案 var handler new HttpClientHandler AllowAutoRedirect false var client ne