Properly decode an IQ with both a payload and an error
This commit is contained in:
parent
3f81465c6c
commit
a6cbc0c08f
23
iq.go
23
iq.go
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
21
iq_test.go
21
iq_test.go
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue