如何通过HTTPS在Golang中进行SOAP调用

时间:2019-04-18 17:29:04

标签: go soap https

我正在尝试通过https进行SOAP调用。

我尝试使用gosoap [“ github.com/tiaguinho/gosoap”]库。

func main() {
    if soap, err := gosoap.SoapClient("https://domain:port/path?WSDL"); err != nil {
        fmt.Println(err)
        return
    } else {
        params := gosoap.Params{
            "param1": "abc",
            "param2":   "def",
            "param3":     "123",
        }

        if res, err := soap.Call("MethodName", params); err != nil {
            fmt.Println(err)
            return
        } else {
            fmt.Println(res)
            return
        }
    }
}

这是我遇到的错误:

Get https://domain:port/path?WSDL: x509: certificate signed by unknown authority
  1. 如何发送标题?
  2. 如何解决证书问题?

1 个答案:

答案 0 :(得分:0)

正如Berkant的评论所述,“这意味着您的应用运行所在的已安装CA无法确认证书”。

最好是检查主机证书是否有效并正确配置。如果主机使用自己的证书,则最好将其添加到知道您的系统/环境的证书中。您也可以将其添加到golang本身,或忽略它。

要将您自己的证书添加到golang,请参见以下答案:

How to send a https request with a certificate golang

然后按如下所示设置客户端:

要忽略它,gosoap.Client的“客户端”字段允许设置http.Client,但仅在调用gosoap.SoapClient之后,因此您需要模拟gosoap.SoapClient:

func SoapClient(wsdl string) (*gosoap.Client, error) {
    _, err := url.Parse(wsdl)
    if err != nil {
        return nil, err
    }

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

    //client := &http.Client{Transport: tr}//1: if you wanna add only soap headers
    client := &http.Client{Transport: NewAddHeaderTransport(tr)}//1: if you wanna add http headers

    //2: if you wann add soap headers, soap.Client has HeaderName and HeaderParams field

   soapClient := &gosoap.Client{
        HttpClient:      client,
        WSDL:        wsdl,
        URL:         strings.TrimSuffix(d.TargetNamespace, "/"),
    }

    err := getWsdlDefinitions(wsdl, &soapClient.Definitions, client)
    if err != nil {
        return nil, err
    }

    return soapClient, nil
}

//we use interface{} since gosoap.wsdlDefinitions is unexported
func getWsdlDefinitions(u string, wsdl interface{}, client *http.Client) (err error) {
    r, err := client.Get(u)
    if err != nil {
        return err
    }
    defer r.Body.Close()

    decoder := xml.NewDecoder(r.Body)
    decoder.CharsetReader = charset.NewReaderLabel
    return decoder.Decode(wsdl)
}

type AddHeaderTransport struct {
    T http.RoundTripper
}

func (adt *AddHeaderTransport) RoundTrip(req *http.Request) (*http.Response, error) {
    req.Header.Add("Your-Header", "your header value")
    return adt.T.RoundTrip(req)
}

func NewAddHeaderTransport(T http.RoundTripper) *AddHeaderTransport {
    if T == nil {
        T = http.DefaultTransport
    }
    return &AddHeaderTransport{T}
}