Add support for delegation namespace packet parsing

Refactor and clean up pubsub & pep files
disco_info_form
Mickael Remond 5 years ago committed by Mickaël Rémond
parent cc2fa7307f
commit c6f0d03f60

@ -216,6 +216,40 @@ func (handshakeDecoder) decode(p *xml.Decoder, se xml.StartElement) (Handshake,
return packet, err
}
// ============================================================================
// Component delegation
// XEP-0355
// Delegation can be used both on message (for delegated) and IQ (for Forwarded),
// depending on the context.
type Delegation struct {
MsgExtension
XMLName xml.Name `xml:"urn:xmpp:delegation:1 delegation"`
Forwarded Forwarded // This is used in iq to wrap delegated iqs
Delegated Delegated // This is used in a message to confirm delegated namespace
}
func (d *Delegation) Namespace() string {
return d.XMLName.Space
}
type Forwarded struct {
XMLName xml.Name `xml:"urn:xmpp:forward:0 forwarded"`
IQ IQ
Message Message
Presence Presence
}
type Delegated struct {
XMLName xml.Name `xml:"delegated"`
Namespace string `xml:"namespace,attr,omitempty"`
}
func init() {
TypeRegistry.MapExtension(PKTMessage, xml.Name{"urn:xmpp:delegation:1", "delegation"}, Delegation{})
TypeRegistry.MapExtension(PKTIQ, xml.Name{"urn:xmpp:delegation:1", "delegation"}, Delegation{})
}
/*
TODO: Add support for discovery management directly in component
TODO: Support multiple identities on disco info

@ -1,6 +1,9 @@
package xmpp // import "gosrc.io/xmpp"
import "testing"
import (
"encoding/xml"
"testing"
)
func TestHandshake(t *testing.T) {
opts := ComponentOptions{
@ -21,3 +24,72 @@ func TestHandshake(t *testing.T) {
func TestGenerateHandshake(t *testing.T) {
// TODO
}
// We should be able to properly parse delegation confirmation messages
func TestParsingDelegationMessage(t *testing.T) {
packetStr := `<message to='service.localhost' from='localhost'>
<delegation xmlns='urn:xmpp:delegation:1'>
<delegated namespace='http://jabber.org/protocol/pubsub'/>
</delegation>
</message>`
var msg Message
data := []byte(packetStr)
if err := xml.Unmarshal(data, &msg); err != nil {
t.Errorf("Unmarshal(%s) returned error", data)
}
// Check that we have extracted the delegation info as MsgExtension
var nsDelegated string
for _, ext := range msg.Extensions {
if delegation, ok := ext.(*Delegation); ok {
nsDelegated = delegation.Delegated.Namespace
}
}
if nsDelegated != "http://jabber.org/protocol/pubsub" {
t.Errorf("Could not find delegated namespace in delegation: %#v\n", msg)
}
}
// Check that we can parse a delegation IQ.
// The most important thing is to be able to
func TestParsingDelegationIQ(t *testing.T) {
packetStr := `<iq to='service.localhost' from='localhost' type='set' id='1'>
<delegation xmlns='urn:xmpp:delegation:1'>
<forwarded xmlns='urn:xmpp:forward:0'>
<iq xml:lang='en' to='test1@localhost' from='test1@localhost/mremond-mbp' type='set' id='aaf3a' xmlns='jabber:client'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<publish node='http://jabber.org/protocol/mood'>
<item id='current'>
<mood xmlns='http://jabber.org/protocol/mood'>
<excited/>
</mood>
</item>
</publish>
</pubsub>
</iq>
</forwarded>
</delegation>
</iq>`
var iq IQ
data := []byte(packetStr)
if err := xml.Unmarshal(data, &iq); err != nil {
t.Errorf("Unmarshal(%s) returned error", data)
}
// Check that we have extracted the delegation info as IQPayload
var node string
for _, ext := range iq.Payload {
if delegation, ok := ext.(*Delegation); ok {
payload := delegation.Forwarded.IQ.Payload
if len(payload) > 0 {
payload := delegation.Forwarded.IQ.Payload[0]
if pubsub, ok := payload.(*PubSub); ok {
node = pubsub.Publish.Node
}
}
}
}
if node != "http://jabber.org/protocol/mood" {
t.Errorf("Could not find mood node name on delegated publish: %#v\n", iq)
}
}

@ -1,25 +1,11 @@
package xmpp // import "gosrc.io/xmpp"
// TODO: Move to a pubsub file
import (
"encoding/xml"
)
type PubSub struct {
XMLName xml.Name `xml:"http://jabber.org/protocol/pubsub pubsub"`
Publish Publish
}
type Publish struct {
XMLName xml.Name `xml:"publish"`
Node string `xml:"node,attr"`
Item Item
}
type Item struct {
XMLName xml.Name `xml:"item"`
Tune Tune
}
type Tune struct {
XMLName xml.Name `xml:"http://jabber.org/protocol/tune tune"`
Artist string `xml:"artist,omitempty"`
@ -31,53 +17,9 @@ type Tune struct {
Uri string `xml:"uri,omitempty"`
}
/*
type PubsubPublish struct {
XMLName xml.Name `xml:"publish"`
node string `xml:"node,attr"`
item PubSubItem
}
type PubSubItem struct {
xmlName xml.Name `xml:"item"`
}
type Thing2 struct {
XMLName xml.Name `xml:"publish"`
node string `xml:"node,attr"`
tune string `xml:"http://jabber.org/protocol/tune item>tune"`
}
type Tune struct {
artist string
length int
rating int
source string
title string
track string
uri string
}
*/
/*
func (*Tune) XMPPFormat() string {
return fmt.Sprintf(
`<iq type='set' id='%s'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<publish node='http://jabber.org/protocol/tune'>
<item>
<tune xmlns='http://jabber.org/protocol/tune'>
<artist>%s</artist>
<length>%i</length>
<rating>%i</rating>
<source>%s</source>
<title>%s</title>
<track>%s</track>
<uri>%s</uri>
</tune>
</item>
</publish>
</pubsub>
</iq>`)
type Mood struct {
XMLName xml.Name `xml:"http://jabber.org/protocol/mood mood"`
// TODO: Custom parsing to extract mood type from tag name
// Mood type
Text string `xml:"text,omitempty"`
}
*/

@ -0,0 +1,39 @@
package xmpp // import "gosrc.io/xmpp"
import (
"encoding/xml"
)
type PubSub struct {
XMLName xml.Name `xml:"http://jabber.org/protocol/pubsub pubsub"`
Publish Publish
Retract Retract
// TODO <configure/>
}
func (p *PubSub) Namespace() string {
return p.XMLName.Space
}
type Publish struct {
XMLName xml.Name `xml:"publish"`
Node string `xml:"node,attr"`
Item Item
}
type Item struct {
XMLName xml.Name `xml:"item"`
Id string `xml:"id,attr,omitempty"`
Tune Tune
}
type Retract struct {
XMLName xml.Name `xml:"retract"`
Node string `xml:"node,attr"`
Notify string `xml:"notify,attr"`
Item Item
}
func init() {
TypeRegistry.MapExtension(PKTIQ, xml.Name{"http://jabber.org/protocol/pubsub", "pubsub"}, PubSub{})
}

@ -8,6 +8,11 @@ import (
The XMPP router helps client and component developers select which XMPP they would like to process,
and associate processing code depending on the router configuration.
Here are important rules to keep in mind while setting your routes and matchers:
- Routes are evaluated in the order they are set.
- When a route matches, it is executed and all others routes are ignored. For each packet, only a single
route is executed.
TODO: Automatically reply to IQ that do not match any route, to comply to XMPP standard.
*/

Loading…
Cancel
Save