Properly decode an IQ with both a payload and an error

This commit is contained in:
Mickael Remond 2019-06-19 13:46:02 +02:00 committed by Mickaël Rémond
parent 3f81465c6c
commit a6cbc0c08f
2 changed files with 40 additions and 16 deletions

23
iq.go
View File

@ -2,6 +2,7 @@ package xmpp
import ( import (
"encoding/xml" "encoding/xml"
"fmt"
"strconv" "strconv"
) )
@ -195,7 +196,6 @@ func (iq *IQ) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
} }
// decode inner elements // decode inner elements
level := 0
for { for {
t, err := d.Token() t, err := d.Token()
if err != nil { if err != nil {
@ -203,10 +203,17 @@ func (iq *IQ) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
} }
switch tt := t.(type) { switch tt := t.(type) {
case xml.StartElement: case xml.StartElement:
level++ if tt.Name.Local == "error" {
if level <= 1 { 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 { if iqExt := TypeRegistry.GetIQExtension(tt.Name); iqExt != nil {
// Decode payload extension // Decode payload extension
err = d.DecodeElement(iqExt, &tt) err = d.DecodeElement(iqExt, &tt)
@ -214,14 +221,10 @@ func (iq *IQ) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
return err return err
} }
iq.Payload = iqExt iq.Payload = iqExt
} else { continue
// TODO: Fix me. We do nothing of that element here.
// elt = new(Node)
} }
} return fmt.Errorf("unexpected element in iq: %s %s", tt.Name.Space, tt.Name.Local)
case xml.EndElement: case xml.EndElement:
level--
if tt == start.End() { if tt == start.End() {
return nil return nil
} }

View File

@ -132,3 +132,24 @@ func TestUnmarshalPayload(t *testing.T) {
t.Errorf("incorrect namespace: %s", namespace) t.Errorf("incorrect namespace: %s", namespace)
} }
} }
func TestPayloadWithError(t *testing.T) {
iq := `<iq xml:lang='en' to='test1@localhost/resource' from='test@localhost' type='error' id='aac1a'>
<query xmlns='jabber:iq:version'/>
<error code='407' type='auth'>
<subscription-required xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
<text xml:lang='en' xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'>Not subscribed</text>
</error>
</iq>`
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)
}
}