From a6cbc0c08f52bae296dafc2aea408b3a1000995e Mon Sep 17 00:00:00 2001 From: Mickael Remond Date: Wed, 19 Jun 2019 13:46:02 +0200 Subject: [PATCH] Properly decode an IQ with both a payload and an error --- iq.go | 35 +++++++++++++++++++---------------- iq_test.go | 21 +++++++++++++++++++++ 2 files changed, 40 insertions(+), 16 deletions(-) diff --git a/iq.go b/iq.go index 27077aa..ec165eb 100644 --- a/iq.go +++ b/iq.go @@ -2,6 +2,7 @@ package xmpp import ( "encoding/xml" + "fmt" "strconv" ) @@ -195,7 +196,6 @@ func (iq *IQ) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { } // decode inner elements - level := 0 for { t, err := d.Token() if err != nil { @@ -203,25 +203,28 @@ func (iq *IQ) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { } switch tt := t.(type) { - case xml.StartElement: - level++ - if level <= 1 { - if iqExt := TypeRegistry.GetIQExtension(tt.Name); iqExt != nil { - // Decode payload extension - err = d.DecodeElement(iqExt, &tt) - if err != nil { - return err - } - iq.Payload = iqExt - } else { - // TODO: Fix me. We do nothing of that element here. - // elt = new(Node) + if tt.Name.Local == "error" { + var xmppError Err + err = d.DecodeElement(&xmppError, &tt) + if err != nil { + fmt.Println(err) + return err } + iq.Error = xmppError + continue } - + if iqExt := TypeRegistry.GetIQExtension(tt.Name); iqExt != nil { + // Decode payload extension + err = d.DecodeElement(iqExt, &tt) + if err != nil { + return err + } + iq.Payload = iqExt + continue + } + return fmt.Errorf("unexpected element in iq: %s %s", tt.Name.Space, tt.Name.Local) case xml.EndElement: - level-- if tt == start.End() { return nil } diff --git a/iq_test.go b/iq_test.go index 2138372..790d173 100644 --- a/iq_test.go +++ b/iq_test.go @@ -132,3 +132,24 @@ func TestUnmarshalPayload(t *testing.T) { t.Errorf("incorrect namespace: %s", namespace) } } + +func TestPayloadWithError(t *testing.T) { + iq := ` + + + + Not subscribed + +` + + parsedIQ := xmpp.IQ{} + err := xml.Unmarshal([]byte(iq), &parsedIQ) + if err != nil { + t.Errorf("Unmarshal error: %s", iq) + return + } + + if parsedIQ.Error.Reason != "subscription-required" { + t.Errorf("incorrect error value: '%s'", parsedIQ.Error.Reason) + } +}