diff --git a/soap.go b/soap.go index 169d494..dc5dd43 100644 --- a/soap.go +++ b/soap.go @@ -44,6 +44,7 @@ type Client struct { WSDL string URL string Method string + SoapAction string Params Params HeaderName string HeaderParams HeaderParams @@ -65,6 +66,10 @@ func (c *Client) GetLastRequest() []byte { func (c *Client) Call(m string, p Params) (err error) { c.Method = m c.Params = p + c.SoapAction = c.Definitions.GetSoapActionFromWsdlOperation(c.Method) + if c.SoapAction == "" { + c.SoapAction = fmt.Sprintf("%s/%s", c.URL, c.Method) + } c.payload, err = xml.MarshalIndent(c, "", " ") if err != nil { @@ -120,7 +125,7 @@ func (c *Client) doRequest(url string) ([]byte, error) { req.Header.Add("Content-Type", "text/xml;charset=UTF-8") req.Header.Add("Accept", "text/xml") - req.Header.Add("SOAPAction", fmt.Sprintf("%s/%s", c.URL, c.Method)) + req.Header.Add("SOAPAction", c.SoapAction) resp, err := c.HttpClient.Do(req) if err != nil { diff --git a/wsdl.go b/wsdl.go index ff4d1e5..abf3bf1 100644 --- a/wsdl.go +++ b/wsdl.go @@ -167,6 +167,23 @@ func getWsdlDefinitions(u string) (wsdl *wsdlDefinitions, err error) { return wsdl, err } +// the SoapAction of an operation might differ from the action wsdl-operation name +// if any SoapAction name is set in the wsdlOperation binding, use that. +func (wsdl *wsdlDefinitions) GetSoapActionFromWsdlOperation(operation string) string { + // in the future it would be nice to have Operations be map[string]*wsdlOperation, + // where the map key is the wsdlOperation name + if wsdl.Bindings[0] != nil { + for _, o := range wsdl.Bindings[0].Operations { + if o.Name == operation { + if o.SoapOperations[0] != nil { + return o.SoapOperations[0].SoapAction + } + } + } + } + return "" +} + // Fault response type Fault struct { Code string `xml:"faultcode"`