golang开发:http请求redirect的问题
这两天在开发项目的时候遇到了一个问题,请求了一个URL,它会302到另一个地址,本意上只是想检查这个URL是否会做3XX的redirect跳转,结果每次reqeust都会返回最后一跳的结果。后来就看了下源码,了解下请求跳转的机制
实现代码
看下实现的简单代码
func main() {
client := &http.Client{}
url := "http://www.qq.com"
reqest, err := http.NewRequest("GET", url, nil)
if err != nil {
panic(err)
}
response, _ := client.Do(reqest)
fmt.Println(response.Status)
}
curl http://www.qq.com
<html>
<head><title>302 Found</title></head>
<body bgcolor="white">
<center><h1>302 Found</h1></center>
<hr><center>stgw/1.3.12.4_1.13.5</center>
</body>
</html>
我们知道在浏览器里面输入http://www.qq.com会302跳转到https://www.qq.com。我们使用curl可以看到使用302的跳转。
可是我只想获取第一跳的的response 的状态码。发现没法实现了,所以看了下源码。
http请求为什么可以做到多次redirect
看了下 client.Do 源码实现
607 err = c.checkRedirect(req, reqs)
代码的上下文,可以看出 req是将要请求的request,reqs已经请求过的request
主要看下checkRedirect
func (c *Client) checkRedirect(req *Request, via []*Request) error {
fn := c.CheckRedirect
if fn == nil {
fn = defaultCheckRedirect
}
return fn(req, via)
}
可以看到如果设置了checkRedirect就执行checkRedirect,如果没有设置就执行 defaultCheckRedirect。
再看下 defaultCheckRedirect
func defaultCheckRedirect(req *Request, via []*Request) error {
if len(via) >= 10 {
return errors.New("stopped after 10 redirects")
}
return nil
}
可以看到最多可以redirect 10次,如果大于10的跳转就抛出错误结束这次请求了。
大体上流程已经搞明白。只要设置checkRedirect返回error,理论上就能实现只请求一次的目的。
func main() {
client := &http.Client{}
url := "http://www.qq.com"
reqest, err := http.NewRequest("GET", url, nil)
if err != nil {
panic(err)
}
client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
return fmt.Errorf("first response")
}
response, _ := client.Do(reqest)
fmt.Println(response.StatusCode)
}
/private/var/folders/4h/lrsc4fyd12v9ctl31ggk5ckc0000gp/T/___go_build_main_go #gosetup
302
基本实现了。
其实,在CheckRedirect方法上面有一行说明,
ErrUseLastResponse can be returned by Client.CheckRedirect hooks to control how redirects are processed. If returned, the next request is not sent and the most recent response is returned with its body unclosed.
Client.CheckRedirect挂钩可以返回ErrUseLastResponse,以控制如何处理重定向。 如果返回,则不发送下一个请求,并且返回最近的响应且其主体未关闭。
可以看到返回 ErrUseLastResponse是官方的建议的设置
最终的代码实现应该是这样的。
```bash
func main() {
client := &http.Client{}
url := "http://www.qq.com"
reqest, err := http.NewRequest("GET", url, nil)
if err != nil {
panic(err)
}
client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
}
response, _ := client.Do(reqest)
fmt.Println(response.StatusCode)
}
golang开发:http请求redirect的问题的更多相关文章
- Golang开发支持平滑升级(优雅重启)的HTTP服务
Golang开发支持平滑升级(优雅重启)的HTTP服务 - tabalt的博客 http://tabalt.net/blog/graceful-http-server-for-golang/ http ...
- golang开发:环境篇(五)实时加载工具gin的使用
gin 工具是golang开发中非常有用且有效的工具,有效的提高了开发调试go程序的效率. 为什么要使用gin 我们知道golang是编译型语言,这就表示go程序的每次改动,如果需要查看改动结果都必须 ...
- 十分钟学会Golang开发gRPC服务
gRPC是Google发起的一个开源RPC框架,使用HTTP/2传输协议,使用Protocol Buffers编码协议,相比RESTful框架的程序性能提高不少,而且当前流行的编程语言基本都已经支持. ...
- 使用golang 开发的 andriod应用
最近在捣鼓一个东东,就是使用golang开发andriod应用.说起来简单操作起来还挺麻烦,中间又学习了很多东西.比如ubuntu,docker,angular,ionic,jquery mobile ...
- golang开发android环境搭建_window
golang开发android环境搭建介绍 一 安装依赖软件: git:版本管理 go: go开发环境(版本>=1.5),可直接下载window版的go安装包. android studio: ...
- Windows下visual studio code搭建golang开发环境
Windows下visual studio code搭建golang开发环境 序幕 其实环境搭建没什么难的,但是遇到一些问题,主要是有些网站资源访问不了(如:golang.org),导致一些包无法安装 ...
- linux golang开发环境配置(离线方式)
<获取开发工具> 到https://www.golangtc.com/download 下载安装包, 根据自己的系统选择合适的开发包,这里选择go.1.9.2.linux-amd6 ...
- miniblink+golang开发windows gui应用
golang的优点自不必说了,这么好的语言怎么能缺少界面库呢?所以我使用miniblink开发了一个可以用html,css,js开发界面的浏览器,通过它你能为你的golang开发简单的界面.说白了其实 ...
- Linux下golang开发环境搭建
对于golang开发来说,Windows下可以用vscode或者liteide都不错,但是Linux下的开发也就只有vim了,所以怎么搞笑的利用vim进行golang开发呢? 参考官方推荐的一个插件: ...
随机推荐
- MySQL分区 (分区介绍与实际使用)
分区介绍: 一.什么是分区? 所谓分区,就是将一个表分成多个区块进行操作和保存,从而降低每次操作的数据,提高性能.而对于应用来说则是透明的,从逻辑上看只有一张表,但在物理上这个表可能是由多个物理分区组 ...
- C 类型限定符
C 类型限定符 1. Introduction C 语言中的大部分类型都可以用称为限定符(qualifier)的关键字 const. volatile. restrict. _Atomic 加以限定. ...
- 解析Vue-router相关干货及工作原理
本文主要介绍了vue-router相关基础知识及单页面应用的工作原理,写的十分的全面细致,具有一定的参考价值,对此有需要的朋友可以参考学习下.如有不足之处,欢迎批评指正. 单页面工作原理是通过浏览器U ...
- (转载)什么是B+树?
本文转载自网络. 如有侵权,请联系处理!
- Python-如何在一个for循环中迭代多个可迭代对象?
案例: 某班学生期末考试成绩,语文.数学.英语分别存储在3个列表中,同时迭代三个列表.,计算每个学生的总分(并行) 某年级有4个班,某次英语成绩分别记录在4个列表中,依次迭代每个列表,统计全年级高于9 ...
- 2.1 java语言概述
链接:https://pan.baidu.com/s/1ab2_KapIW-ZaT8kedNODug 提取码:miao
- Java知识系统回顾整理01基础05控制流程01if
一.if if(表达式1){ 表达式2: } 如果表达式1的值是true, 就执行表达式2 public class HelloWorld { public static void main(Stri ...
- Java知识系统回顾整理01基础04操作符07Scanner
一.Scanner 需要用到从控制台输入数据时,使用Scanner类. 二.使用Scanner读取整数 注意: 使用Scanner类,需要在最前面加上 import java.util.Scanner ...
- 【原创】经验分享:一个小小emoji尽然牵扯出来这么多东西?
前言 之前也分享过很多工作中踩坑的经验: 一个线上问题的思考:Eureka注册中心集群如何实现客户端请求负载及故障转移? [原创]经验分享:一个Content-Length引发的血案(almost.. ...
- VS Code对Golang的基准测试研究
初心 想要在VS Code比较方便的调试Go代码的性能,了解到基准测试对此很有帮助,但默认VS Code执行 Go 的基准测试默认的benchtime为1秒,但测试性能时需要设置为更多秒 办法 在VS ...