【问题标题】:How can I test HTTPS endpoints in go?如何在 Go 中测试 HTTPS 端点?
【发布时间】:2016-04-07 06:59:54
【问题描述】:

所以我尝试使用httptest.TLSServer 模拟对https 请求的响应,但发出请求的http.Client 不断告诉我服务器给出的http 响应无效。我敢打赌这是因为没有实际的 SSL 证书。有什么方法可以让客户端忽略 tls,同时仍然模拟 https 请求?

有问题的测试代码

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)
    }

}

以及我试图提出的要求:

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()

【问题讨论】:

标签: ssl testing go


【解决方案1】:

测试服务器使用自签名证书。有两种方法可以避免错误。第一种是使用配置了test server's certificates的HTTP客户端:

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

一个更简单的选择是跳过证书验证:

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

playground example

还有一个问题。客户端希望连接到代理服务器,但它实际上是直接连接到测试服务器。尝试挂钩拨号功能而不是代理:

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

【讨论】:

  • 现在我收到了一个奇怪的 Malformed Response 错误。知道为什么吗?
  • @thecodethinker 我需要更多信息来确定错误可能是什么。我提供了两个测试 https 的工作程序。从其中一个开始。
  • 当我尝试使用InsecureSkipVerify 进行测试时,我收到此错误malformed HTTP response "\x15\x03\x01\x00\x02\x02\x16"。你知道那是什么吗?
  • 哦,这又是一个问题 测试服务器正在响应 TLS 握手,但客户端期待来自代理的 HTTP 响应。请参阅更新的答案以进行修复。
  • 为什么你只想要/ 字符之后的东西来调用Dial
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-05
相关资源
最近更新 更多