From af0ae525b88dee24de18e51a71cedd80850261d2 Mon Sep 17 00:00:00 2001 From: Mickael Remond Date: Wed, 19 Jun 2019 10:21:57 +0200 Subject: [PATCH] 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." --- client_test.go | 2 +- component_test.go | 10 ++++------ iot_control_test.go | 2 +- iq.go | 14 +++++--------- iq_test.go | 8 ++++---- router.go | 4 ++-- router_test.go | 10 +++++----- session.go | 2 +- 8 files changed, 23 insertions(+), 29 deletions(-) diff --git a/client_test.go b/client_test.go index 966e6b8..813f2be 100644 --- a/client_test.go +++ b/client_test.go @@ -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 := ` diff --git a/component_test.go b/component_test.go index b007c85..fd7ae3c 100644 --- a/component_test.go +++ b/component_test.go @@ -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 } } diff --git a/iot_control_test.go b/iot_control_test.go index 878b251..aaf26c9 100644 --- a/iot_control_test.go +++ b/iot_control_test.go @@ -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) } } diff --git a/iq.go b/iq.go index 1b9f127..27077aa 100644 --- a/iq.go +++ b/iq.go @@ -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"` - Error Err `xml:"error,omitempty"` + 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) diff --git a/iq_test.go b/iq_test.go index 956a00a..bfa1c98 100644 --- a/iq_test.go +++ b/iq_test.go @@ -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") } } diff --git a/router.go b/router.go index 92b1594..5b4515b 100644 --- a/router.go +++ b/router.go @@ -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 diff --git a/router_test.go b/router_test.go index 8afbc9c..4e44f41 100644 --- a/router_test.go +++ b/router_test.go @@ -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) diff --git a/session.go b/session.go index 04af21f..48dc02f 100644 --- a/session.go +++ b/session.go @@ -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: