mirror of
https://github.com/FluuxIO/go-xmpp.git
synced 2024-11-24 11:32:00 -08:00
Add support for delegation namespace packet parsing
Refactor and clean up pubsub & pep files
This commit is contained in:
parent
cc2fa7307f
commit
c6f0d03f60
34
component.go
34
component.go
@ -216,6 +216,40 @@ func (handshakeDecoder) decode(p *xml.Decoder, se xml.StartElement) (Handshake,
|
|||||||
return packet, err
|
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: Add support for discovery management directly in component
|
||||||
TODO: Support multiple identities on disco info
|
TODO: Support multiple identities on disco info
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
package xmpp // import "gosrc.io/xmpp"
|
package xmpp // import "gosrc.io/xmpp"
|
||||||
|
|
||||||
import "testing"
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
func TestHandshake(t *testing.T) {
|
func TestHandshake(t *testing.T) {
|
||||||
opts := ComponentOptions{
|
opts := ComponentOptions{
|
||||||
@ -21,3 +24,72 @@ func TestHandshake(t *testing.T) {
|
|||||||
func TestGenerateHandshake(t *testing.T) {
|
func TestGenerateHandshake(t *testing.T) {
|
||||||
// TODO
|
// 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
72
pep.go
72
pep.go
@ -1,25 +1,11 @@
|
|||||||
package xmpp // import "gosrc.io/xmpp"
|
package xmpp // import "gosrc.io/xmpp"
|
||||||
|
|
||||||
|
// TODO: Move to a pubsub file
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/xml"
|
"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 {
|
type Tune struct {
|
||||||
XMLName xml.Name `xml:"http://jabber.org/protocol/tune tune"`
|
XMLName xml.Name `xml:"http://jabber.org/protocol/tune tune"`
|
||||||
Artist string `xml:"artist,omitempty"`
|
Artist string `xml:"artist,omitempty"`
|
||||||
@ -31,53 +17,9 @@ type Tune struct {
|
|||||||
Uri string `xml:"uri,omitempty"`
|
Uri string `xml:"uri,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
type Mood struct {
|
||||||
type PubsubPublish struct {
|
XMLName xml.Name `xml:"http://jabber.org/protocol/mood mood"`
|
||||||
XMLName xml.Name `xml:"publish"`
|
// TODO: Custom parsing to extract mood type from tag name
|
||||||
node string `xml:"node,attr"`
|
// Mood type
|
||||||
item PubSubItem
|
Text string `xml:"text,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
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>`)
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
39
pubsub.go
Normal file
39
pubsub.go
Normal file
@ -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,
|
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.
|
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.
|
TODO: Automatically reply to IQ that do not match any route, to comply to XMPP standard.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user