mirror of
https://github.com/kerberos-io/onvif.git
synced 2025-12-24 11:31:03 +08:00
122 lines
2.6 KiB
Go
122 lines
2.6 KiB
Go
package gosoap
|
|
|
|
import (
|
|
"encoding/xml"
|
|
"fmt"
|
|
)
|
|
|
|
type SOAPEnvelope struct {
|
|
XMLName xml.Name `xml:"http://www.w3.org/2003/05/soap-envelope Envelope"`
|
|
Header SOAPHeader
|
|
Body SOAPBody
|
|
}
|
|
|
|
type SOAPHeader struct {
|
|
XMLName xml.Name `xml:"http://www.w3.org/2003/05/soap-envelope Header"`
|
|
|
|
Headers []interface{}
|
|
}
|
|
|
|
type SOAPBody struct {
|
|
XMLName xml.Name `xml:"http://www.w3.org/2003/05/soap-envelope Body"`
|
|
|
|
Fault *SOAPFault `xml:",omitempty"`
|
|
Content interface{} `xml:",omitempty"`
|
|
}
|
|
|
|
type SOAPFault struct {
|
|
XMLName xml.Name `xml:"http://www.w3.org/2003/05/soap-envelope Fault"`
|
|
|
|
Code SOAPFaultCode `xml:",omitempty"`
|
|
Reason SOAPFaultReason `xml:",omitempty"`
|
|
Detail SOAPFaultDetail `xml:",omitempty"`
|
|
}
|
|
|
|
// UnmarshalXML the response body
|
|
// https://github.com/faceterteam/onvif4go/blob/master/soap/types.go#L46
|
|
// https://play.golang.org/p/FRzdAFrXZ1
|
|
func (b *SOAPBody) UnmarshalXML(d *xml.Decoder, _ 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://www.w3.org/2003/05/soap-envelope" && se.Name.Local == "Fault" {
|
|
b.Fault = &SOAPFault{}
|
|
b.Content = nil
|
|
|
|
err = d.DecodeElement(b.Fault, &se)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
consumed = true
|
|
} else {
|
|
if err = d.DecodeElement(b.Content, &se); err != nil {
|
|
return err
|
|
}
|
|
|
|
consumed = true
|
|
}
|
|
case xml.EndElement:
|
|
break Loop
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
type SOAPFaultCode struct {
|
|
Value string `xml:"Value"`
|
|
Subcode SOAPFaultSubCode `xml:"Subcode,omitempty"`
|
|
}
|
|
|
|
type SOAPFaultSubCode struct {
|
|
Value string `xml:"Value"`
|
|
Subcode *SOAPFaultSubCode `xml:"Subcode,omitempty"`
|
|
}
|
|
|
|
type SOAPFaultReason struct {
|
|
Text string `xml:"Text"`
|
|
}
|
|
|
|
type SOAPFaultDetail struct {
|
|
Text string `xml:"Text"`
|
|
}
|
|
|
|
func (fault *SOAPFault) String() string {
|
|
msg := fmt.Sprintf("fault reason: %s, fault detail: %s, fault code: %v %v ",
|
|
fault.Reason.Text, fault.Detail.Text, fault.Code.Value, fault.Code.Subcode.Value)
|
|
if fault.Code.Subcode.Subcode != nil {
|
|
msg += fault.Code.Subcode.Subcode.Value
|
|
}
|
|
return msg
|
|
}
|
|
|
|
func NewSOAPEnvelope(content interface{}) *SOAPEnvelope {
|
|
return &SOAPEnvelope{
|
|
Body: SOAPBody{
|
|
Content: content,
|
|
},
|
|
}
|
|
}
|