mirror of
https://github.com/foomo/soap.git
synced 2025-10-16 12:45:36 +00:00
130 lines
2.6 KiB
Go
130 lines
2.6 KiB
Go
package soap
|
|
|
|
import (
|
|
"encoding/json"
|
|
"encoding/xml"
|
|
"log"
|
|
)
|
|
|
|
// SOAP 1.1 and SOAP 1.2 must expect different ContentTypes and Namespaces.
|
|
|
|
const (
|
|
SoapVersion11 = "1.1"
|
|
SoapVersion12 = "1.2"
|
|
|
|
SoapContentType11 = "text/xml; charset=\"utf-8\""
|
|
SoapContentType12 = "application/soap+xml; charset=\"utf-8\""
|
|
|
|
NamespaceSoap11 = "http://schemas.xmlsoap.org/soap/envelope/"
|
|
NamespaceSoap12 = "http://www.w3.org/2003/05/soap-envelope"
|
|
)
|
|
|
|
// Verbose be verbose
|
|
var Verbose = false
|
|
|
|
func l(m ...interface{}) {
|
|
if Verbose {
|
|
log.Println(m...)
|
|
}
|
|
}
|
|
|
|
func LogJSON(v interface{}) {
|
|
if Verbose {
|
|
json, err := json.MarshalIndent(v, "", " ")
|
|
if err != nil {
|
|
log.Println("Could not log json...")
|
|
return
|
|
}
|
|
log.Println(string(json))
|
|
}
|
|
}
|
|
|
|
// Envelope type
|
|
type Envelope struct {
|
|
XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Envelope"`
|
|
Header Header
|
|
Body Body
|
|
}
|
|
|
|
// Header type
|
|
type Header struct {
|
|
XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Header"`
|
|
|
|
Header interface{}
|
|
}
|
|
|
|
// Body type
|
|
type Body struct {
|
|
XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Body"`
|
|
|
|
Fault *Fault `xml:",omitempty"`
|
|
Content interface{} `xml:",omitempty"`
|
|
SOAPBodyContentType string `xml:"-"`
|
|
}
|
|
|
|
// Fault type
|
|
type Fault struct {
|
|
XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault"`
|
|
|
|
Code string `xml:"faultcode,omitempty"`
|
|
String string `xml:"faultstring,omitempty"`
|
|
Actor string `xml:"faultactor,omitempty"`
|
|
Detail string `xml:"detail,omitempty"`
|
|
}
|
|
|
|
// UnmarshalXML implement xml.Unmarshaler
|
|
func (b *Body) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
|
if b.Content == nil {
|
|
return xml.UnmarshalError("Content must be a pointer to a struct")
|
|
}
|
|
|
|
var (
|
|
token xml.Token
|
|
err error
|
|
consumed bool
|
|
)
|
|
|
|
Loop:
|
|
for {
|
|
if token, err = d.Token(); err != nil {
|
|
return err
|
|
}
|
|
|
|
if token == nil {
|
|
break
|
|
}
|
|
|
|
switch se := token.(type) {
|
|
case xml.StartElement:
|
|
if consumed {
|
|
return xml.UnmarshalError("Found multiple elements inside SOAP body; not wrapped-document/literal WS-I compliant")
|
|
} else if se.Name.Space == "http://schemas.xmlsoap.org/soap/envelope/" && se.Name.Local == "Fault" {
|
|
b.Fault = &Fault{}
|
|
b.Content = nil
|
|
|
|
err = d.DecodeElement(b.Fault, &se)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
consumed = true
|
|
} else {
|
|
b.SOAPBodyContentType = se.Name.Local
|
|
if err = d.DecodeElement(b.Content, &se); err != nil {
|
|
return err
|
|
}
|
|
|
|
consumed = true
|
|
}
|
|
case xml.EndElement:
|
|
break Loop
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (f *Fault) Error() string {
|
|
return f.String
|
|
}
|