An IQ can only have a single payload

"An IQ stanza of type "get" or "set" MUST contain exactly one
 child element, which specifies the semantics of the particular
 request."
This commit is contained in:
Mickael Remond 2019-06-19 10:21:57 +02:00 committed by Mickaël Rémond
parent d455f29258
commit af0ae525b8
8 changed files with 23 additions and 29 deletions

View file

@ -198,7 +198,7 @@ func bind(t *testing.T, c net.Conn, decoder *xml.Decoder) {
}
// TODO Check all elements
switch iq.Payload[0].(type) {
switch iq.Payload.(type) {
case *BindBind:
result := `<iq id='%s' type='result'>
<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>

View file

@ -78,18 +78,16 @@ func TestParsingDelegationIQ(t *testing.T) {
// Check that we have extracted the delegation info as IQPayload
var node string
for _, ext := range iq.Payload {
if delegation, ok := ext.(*Delegation); ok {
if iq.Payload != nil {
if delegation, ok := iq.Payload.(*Delegation); ok {
packet := delegation.Forwarded.Stanza
forwardedIQ, ok := packet.(IQ)
if !ok {
t.Errorf("Could not extract packet IQ")
return
}
payload := forwardedIQ.Payload
if len(payload) > 0 {
pl := payload[0]
if pubsub, ok := pl.(*PubSub); ok {
if forwardedIQ.Payload != nil {
if pubsub, ok := forwardedIQ.Payload.(*PubSub); ok {
node = pubsub.Publish.Node
}
}

View file

@ -20,7 +20,7 @@ func TestControlSet(t *testing.T) {
t.Errorf("Unmarshal(%s) returned error", data)
}
if cs, ok := parsedIQ.Payload[0].(*ControlSet); !ok {
if cs, ok := parsedIQ.Payload.(*ControlSet); !ok {
t.Errorf("Paylod is not an iot control set: %v", cs)
}
}

12
iq.go
View file

@ -123,13 +123,13 @@ func (x Err) MarshalXML(e *xml.Encoder, start xml.StartElement) (err error) {
type IQ struct { // Info/Query
XMLName xml.Name `xml:"iq"`
PacketAttrs
// FIXME: We can only have one payload:
// We can only have one payload on IQ:
// "An IQ stanza of type "get" or "set" MUST contain exactly one
// child element, which specifies the semantics of the particular
// request."
Payload []IQPayload `xml:",omitempty"`
RawXML string `xml:",innerxml"`
Payload IQPayload `xml:",omitempty"`
Error Err `xml:"error,omitempty"`
RawXML string `xml:",innerxml"`
}
func NewIQ(iqtype, from, to, id, lang string) IQ {
@ -145,10 +145,6 @@ func NewIQ(iqtype, from, to, id, lang string) IQ {
}
}
func (iq *IQ) AddPayload(payload IQPayload) {
iq.Payload = append(iq.Payload, payload)
}
func (iq IQ) MakeError(xerror Err) IQ {
from := iq.From
to := iq.To
@ -217,7 +213,7 @@ func (iq *IQ) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
if err != nil {
return err
}
iq.Payload = append(iq.Payload, iqExt)
iq.Payload = iqExt
} else {
// TODO: Fix me. We do nothing of that element here.
// elt = new(Node)

View file

@ -47,7 +47,7 @@ func TestGenerateIq(t *testing.T) {
{Var: xmpp.NSDiscoItems},
},
}
iq.AddPayload(&payload)
iq.Payload = &payload
data, err := xml.Marshal(iq)
if err != nil {
@ -97,7 +97,7 @@ func TestDiscoItems(t *testing.T) {
payload := xmpp.DiscoItems{
Node: "music",
}
iq.AddPayload(&payload)
iq.Payload = &payload
data, err := xml.Marshal(iq)
if err != nil {
@ -123,7 +123,7 @@ func TestUnmarshalPayload(t *testing.T) {
t.Errorf("Unmarshal(%s) returned error", query)
}
if len(parsedIQ.Payload) != 1 {
t.Errorf("Incorrect payload size: %d", len(parsedIQ.Payload))
if parsedIQ.Payload == nil {
t.Error("Missing payload")
}
}

View file

@ -157,10 +157,10 @@ func (m nsIQMatcher) Match(p Packet, match *RouteMatch) bool {
if !ok {
return false
}
if len(iq.Payload) < 1 {
if iq.Payload == nil {
return false
}
return matchInArray(m, iq.Payload[0].Namespace())
return matchInArray(m, iq.Payload.Namespace())
}
// IQNamespaces adds an IQ matcher, expecting both an IQ and a

View file

@ -33,7 +33,7 @@ func TestNameMatcher(t *testing.T) {
// Check that an IQ packet is not matched
conn = NewSenderMock()
iq := xmpp.NewIQ("get", "", "localhost", "1", "")
iq.Payload = append(iq.Payload, &xmpp.DiscoInfo{})
iq.Payload = &xmpp.DiscoInfo{}
router.Route(conn, iq)
if conn.String() == successFlag {
t.Error("IQ should not have been matched and routed")
@ -52,11 +52,11 @@ func TestIQNSMatcher(t *testing.T) {
conn := NewSenderMock()
iqDisco := xmpp.NewIQ("get", "", "localhost", "1", "")
// TODO: Add a function to generate payload with proper namespace initialisation
iqDisco.Payload = append(iqDisco.Payload, &xmpp.DiscoInfo{
iqDisco.Payload = &xmpp.DiscoInfo{
XMLName: xml.Name{
Space: xmpp.NSDiscoInfo,
Local: "query",
}})
}}
router.Route(conn, iqDisco)
if conn.String() != successFlag {
t.Errorf("IQ should have been matched and routed: %v", iqDisco)
@ -66,11 +66,11 @@ func TestIQNSMatcher(t *testing.T) {
conn = NewSenderMock()
iqVersion := xmpp.NewIQ("get", "", "localhost", "1", "")
// TODO: Add a function to generate payload with proper namespace initialisation
iqVersion.Payload = append(iqVersion.Payload, &xmpp.DiscoInfo{
iqVersion.Payload = &xmpp.DiscoInfo{
XMLName: xml.Name{
Space: "jabber:iq:version",
Local: "query",
}})
}}
router.Route(conn, iqVersion)
if conn.String() == successFlag {
t.Errorf("IQ should not have been matched and routed: %v", iqVersion)

View file

@ -165,7 +165,7 @@ func (s *Session) bind(o Config) {
}
// TODO Check all elements
switch payload := iq.Payload[0].(type) {
switch payload := iq.Payload.(type) {
case *BindBind:
s.BindJid = payload.Jid // our local id (with possibly randomly generated resource
default: