如何使用Go指定IP请求http(s)网址

旧街凉风 提交于 2020-12-28 02:54:22
我们公司产品是典型三层架构,前端是一个类似CDN的cache节点,后面挂着有N个proxy做高可用,proxy后面是真正的代码服务器,随着机器越来越多,偶尔会出现部分机器状态不一致而导致的问题,比较难以排查,比如:部分cache节点客户证书安装失败,导致客户反馈他们访问提示证书有问题,而我们无法重现。之前还遇到过,因为机房WAF更改规则,导致客户说访问网站提示域名未备案,于是我开发了这个小工具,开发后运维同事一使用,很快就找到了有问题的机房。

 

工具的使用非常简单,工具目录下新建一个requests.txt,填入如下信息:

 

url:https://www.baidu.com/
user-agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36
header-output:1
body-output:1
cookie:BIDUPSID=xxxx;
202.108.22.5
180.101.49.11
双击exe文件即可。
简单介绍下工具的参数:
  • url: 后面是需要请求的网址,这个参数是必填的
  • user-agent:可以自定义http Request UserAgent,可不填,默认是chrome的user agent
  • header-output:是否将返回的Respond Header 写入 result 目录下,默认不写入,可不填
  • body-output:是否将返回的Respond Body 写入 result 目录下,默认不写入,可不填
  • cookie:自定义Request Cookie,可不填
  • IP列表,每行一个,如果不填IP,直接DNS域名请求HTTP网址,相当于普通http request。
这个工具,之前的版本,只支持顺序执行,后来我做了一次重构,现在已经支持多IP并发请求。
代码我开源到我的github上了
可以直接git clone下载源码,并使用go build生成可执行文件。
不想自己编译的,也可以通过百度网盘,直接下载可执行文件运行
提取码: f9tt
 
如果你想在自己的Go代码中,实现指定IP请求http(s)网站,可以参考SimpleHttpTester的源代码,但是SimpleHttpTester的代码经过了一定的封装,剥离起来不太容易,我之前写过一个简单的版本,可以供大家参考:
func RequestIP(requrl string, ip string) error {
    urlValue, err := url.Parse(requrl)
    if err != nil {
        return err
    }
    host := urlValue.Host
    if ip == "" {
        ip = host
    }
    newrequrl := strings.Replace(requrl, host, ip, 1)
    client := &http.Client{
        Transport: &http.Transport{
            TLSClientConfig: &tls.Config{ServerName: host},
        },
        CheckRedirect: func(req *http.Request, via []*http.Request) error { return http.ErrUseLastResponse },
        Timeout:       5 * time.Second,
    }
    req, err := http.NewRequest("GET", newrequrl, nil)
    if err != nil {
        return errors.New(strings.ReplaceAll(err.Error(), newrequrl, requrl))
    }
    req.Host = host
    req.Header.Set("USER-AGENT", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36")
    now := time.Now()
    resp, err := client.Do(req)
    if err != nil {
        return errors.New(strings.ReplaceAll(err.Error(), newrequrl, requrl))
    }
    defer resp.Body.Close()
    fmt.Println("Request IP:" + ip)
    fmt.Println("Response Satus:" + resp.Status)
    fmt.Printf("Response Time: %.2f秒\n", time.Since(now).Seconds())
    fmt.Println()
    fmt.Println("----------------------------------")
    ip = strings.ReplaceAll(ip, ":", ".")
    f, err := os.OpenFile("result/"+ip+"_header.txt", os.O_CREATE|os.O_RDWR, 0777)
    if err != nil {
        return err
    }
    defer f.Close()
    fmt.Fprintln(f, resp.Status)
    resp.Header.Write(f)
    f, err = os.OpenFile("result/"+ip+"_body.txt", os.O_CREATE|os.O_RDWR, 0777)
    if err != nil {
        return err
    }
    defer f.Close()
    io.Copy(f, resp.Body)
    return nil
}

 

 

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!