duanmei2459 2016-03-31 17:55
浏览 33

如何在Go中测试HTTPS端点?

So I'm trying to mock out a response to an https request using httptest.TLSServer but the http.Client making the request keeps telling me that the server is giving an invalid http response. I bet this is because there's no actual SSL cert. Is there any way I can get the client to ignore tls while still mocking out an https request?

The test code in question

func TestFacebookLogin(t *testing.T) {
    db := glob.db
    server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        resp := `
        {
          "id": "123",
          "email": "blah",
          "first_name": "Ben",
          "last_name": "Botwin"
        }
        `

        w.Write([]byte(resp))
    }))
    defer server.Close()

    transport := &http.Transport{
        Proxy: func(r *http.Request) (*url.URL, error) {
            return url.Parse(server.URL)
        },
    }

    svc := userService{db: db, client: &http.Client{Transport: transport}}

    _, err := svc.FacebookLogin("asdf")

    if err != nil {
        t.Errorf("Error found: %s", err)
    }

}

And the request that I'm trying to make:

url := "https://<Some facebook api endpoint>"
req, err := http.NewRequest("GET", url, nil)
resp, err := client.Do(req)
if err != nil {
    return nil, err
}
defer resp.Body.Close()
  • 写回答

1条回答 默认 最新

  • dongxian8272 2016-03-31 19:21
    关注

    The test server uses a self signed certificate. There are two ways to avoid errors. The first is to use an HTTP client configured with the test server's certificates:

    certs := x509.NewCertPool()
    for _, c := range server.TLS.Certificates {
        roots, err := x509.ParseCertificates(c.Certificate[len(c.Certificate)-1])
        if err != nil {
            log.Fatalf("error parsing server's root cert: %v", err)
        }
        for _, root := range roots {
            certs.AddCert(root)
        }
    }
    client := http.Client{
        Transport: &http.Transport{
            TLSClientConfig: &tls.Config{
                RootCAs: certs,
            },
        },
    }
    

    playground example

    An easier option is to skip cert verification:

    client := http.Client{
        Transport: &http.Transport{
            TLSClientConfig: &tls.Config{
                InsecureSkipVerify: true,
            },
        },
    }
    

    playground example

    There's an additional issue. The client expects to connect to a proxy server, but the it's actually connecting to the test server directly. Try hooking the dial function instead of the proxy:

    client := http.Client{
        Transport: &http.Transport{
            Dial: func(network, addr string) (net.Conn, error) {
                return net.Dial("tcp", server.URL[strings.LastIndex(server.URL, "/")+1:])
            },
            TLSClientConfig: &tls.Config{
                InsecureSkipVerify: true,
            },
        },
    }
    

    playground example

    评论

报告相同问题?

悬赏问题

  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度
  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测
  • ¥15 ETLCloud 处理json多层级问题
  • ¥15 matlab中使用gurobi时报错
  • ¥15 这个主板怎么能扩出一两个sata口
  • ¥15 不是,这到底错哪儿了😭
  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么