使用Socket连接时如何实现类似AllowAutoRedirect的重定向控制功能
Socket实现HTTP请求自动重定向启停的方案
核心实现逻辑
HTTP协议的重定向完全基于响应状态码和Location响应头,你可以通过自定义开关变量和响应后处理逻辑实现和HttpWebRequest.AllowAutoRedirect完全一致的控制效果:
- 先定义请求级别的控制开关变量
allowAutoRedirect,布尔类型,赋值为false时对应关闭自动重定向,赋值为true时对应开启自动重定向,这就是你启停控制的核心入口。 - 关闭自动重定向的处理逻辑非常简单:通过Socket拿到完整的HTTP响应后,不需要做任何额外处理,直接将原始响应返回给上层调用逻辑即可,不管响应携带的是3xx重定向状态码还是其他状态码都不做特殊处理。
- 开启自动重定向时,需要在拿到HTTP响应后增加以下处理流程:
- 首先解析响应首行的状态码,仅当状态码为301/302/303/307/308这几个标准重定向码时进入重定向流程,其余状态码直接返回原始响应
- 遍历解析得到的响应头,提取
Location字段的取值作为重定向目标地址 - 解析目标地址的协议、域名、端口、资源路径:如果目标地址和原请求的域名/端口/协议不一致,需要销毁当前Socket连接,重新和目标地址的域名+端口建立Socket连接;如果是HTTPS协议还需要额外完成TLS握手流程
- 根据重定向状态码调整请求方法:301/302/303状态码默认将原POST请求转为GET请求,丢弃原请求体;307/308状态码保留原请求方法和请求体
- 构造新的HTTP请求报文,通过Socket发送到目标服务端,等待新的响应返回
- 额外建议新增
maxRedirectCount变量限制最大重定向次数,默认可设置为5~10,超过次数后直接返回最后一次的响应,避免循环重定向导致程序死循环
关键注意事项
- 解析HTTP响应时要正确拆分响应头和响应体,二者以
\r\n\r\n为分隔符,不要将响应体内容误判为响应头导致Location字段提取失败 - 注意处理
Location为相对路径的场景,需要和原请求的域名、根路径拼接得到完整的目标地址,不能直接使用相对路径建立Socket连接 - 重定向时如果需要携带Cookie,要自行实现Cookie存储和匹配逻辑,将符合域名/路径规则的Cookie放到新请求的请求头中
内容的提问来源于stack exchange,提问作者99Boboster99
相关产品推荐
相关产品推荐

