diff --git a/soap/soap.go b/soap/soap.go
index 0d7a758..689f2a4 100644
--- a/soap/soap.go
+++ b/soap/soap.go
@@ -194,9 +194,13 @@ type soapBody struct {
// SOAPFaultError implements error, and contains SOAP fault information.
type SOAPFaultError struct {
- FaultCode string `xml:"faultCode"`
- FaultString string `xml:"faultString"`
+ FaultCode string `xml:"faultcode"`
+ FaultString string `xml:"faultstring"`
Detail struct {
+ UPnPError struct {
+ Errorcode int `xml:"errorCode"`
+ ErrorDescription string `xml:"errorDescription"`
+ } `xml:"UPnPError"`
Raw []byte `xml:",innerxml"`
} `xml:"detail"`
}
diff --git a/soap/soap_test.go b/soap/soap_test.go
index 889a009..08de9fa 100644
--- a/soap/soap_test.go
+++ b/soap/soap_test.go
@@ -6,6 +6,7 @@ import (
"net/http"
"net/url"
"reflect"
+ "strings"
"testing"
)
@@ -87,6 +88,74 @@ func TestActionInputs(t *testing.T) {
}
}
+func TestUPnPError(t *testing.T) {
+ t.Parallel()
+ url, err := url.Parse("http://example.com/soap")
+ if err != nil {
+ t.Fatal(err)
+ }
+ body := `
+
+
+
+ s:Client
+ UPnPError
+
+
+ 725
+ OnlyPermanentLeasesSupported
+
+
+
+
+ `
+ rt := &capturingRoundTripper{
+ resp: &http.Response{
+ StatusCode: 500,
+ ContentLength: int64(len(body)),
+ Body: ioutil.NopCloser(bytes.NewBufferString(body)),
+ },
+ }
+ client := SOAPClient{
+ EndpointURL: *url,
+ HTTPClient: http.Client{
+ Transport: rt,
+ },
+ }
+
+ err = client.PerformAction("mynamespace", "myaction", nil, nil)
+ if err == nil {
+ t.Fatal("expected error, got nil")
+ }
+ if testing.Verbose() {
+ t.Logf("%+v\n", err)
+ }
+ soapErr, ok := err.(*SOAPFaultError)
+ if !ok {
+ t.Fatal("expected *SOAPFaultError")
+ }
+ if soapErr.FaultCode != "s:Client" {
+ t.Fatalf("unexpected FaultCode: %s", soapErr.FaultCode)
+ }
+ if soapErr.FaultString != "UPnPError" {
+ t.Fatalf("unexpected FaultString: %s", soapErr.FaultString)
+ }
+ if soapErr.Detail.UPnPError.Errorcode != 725 {
+ t.Fatalf("unexpected UPnPError Errorcode: %d", soapErr.Detail.UPnPError.Errorcode)
+ }
+ if soapErr.Detail.UPnPError.ErrorDescription != "OnlyPermanentLeasesSupported" {
+ t.Fatalf("unexpected UPnPError ErrorDescription: %s",
+ soapErr.Detail.UPnPError.ErrorDescription)
+ }
+ if !strings.EqualFold(string(soapErr.Detail.Raw), `
+
+ 725
+ OnlyPermanentLeasesSupported
+
+`) {
+ t.Fatalf("unexpected Detail.Raw, got:\n%s", string(soapErr.Detail.Raw))
+ }
+}
func TestEscapeXMLText(t *testing.T) {
t.Parallel()