fixes after xmpp lib refactored

This commit is contained in:
Martin/Geno 2019-06-20 13:40:22 +02:00
parent c6f9405906
commit ea9b107109
No known key found for this signature in database
GPG Key ID: 9D7D3C6BFF600C6A
3 changed files with 187 additions and 136 deletions

View File

@ -21,6 +21,13 @@ func (c *Config) Start() (err error) {
if err != nil {
return
}
router := xmpp.NewRouter()
router.NewRoute().IQNamespaces(xmpp.NSDiscoInfo).HandlerFunc(c.handleDiscoInfo)
router.NewRoute().IQNamespaces(xmpp.NSDiscoItems).HandlerFunc(c.handleDiscoItems)
router.HandleFunc("iq", c.handleIQ)
router.HandleFunc("message", c.handleMessage)
c.xmpp, err = xmpp.NewComponent(xmpp.ComponentOptions{
Domain: c.Host,
Secret: c.Secret,
@ -28,18 +35,13 @@ func (c *Config) Start() (err error) {
Name: c.Type,
Category: "gateway",
Type: "service",
})
}, router)
if err != nil {
return
}
cm := xmpp.NewStreamManager(c.xmpp, nil)
err = cm.Start()
if err != nil {
return
}
go cm.Run()
go c.sender(out)
go c.receiver()
return nil
}

View File

@ -1,50 +1,29 @@
package component
import (
"encoding/xml"
"github.com/bdlm/log"
"gosrc.io/xmpp"
)
func (c *Config) receiver() {
for packet := range c.xmpp.Recv() {
p, back := c.receiving(packet)
if p == nil {
continue
}
if back {
c.xmpp.Send(p)
} else {
c.comp.Send(p)
}
}
}
func (c *Config) receiving(packet interface{}) (xmpp.Packet, bool) {
logger := log.WithField("type", c.Type)
switch p := packet.(type) {
case xmpp.IQ:
attrs := p.PacketAttrs
loggerIQ := logger.WithFields(map[string]interface{}{
"from": attrs.From,
"to": attrs.To,
})
switch inner := p.Payload[0].(type) {
case *xmpp.DiscoInfo:
if p.Type == "get" {
iq := xmpp.NewIQ("result", attrs.To, attrs.From, attrs.Id, "en")
var identity xmpp.Identity
if inner.Node == "" {
identity = xmpp.Identity{
Name: c.Type,
Category: "gateway",
Type: "service",
func (c *Config) handleDiscoInfo(s xmpp.Sender, p xmpp.Packet) {
iq, ok := p.(xmpp.IQ)
if !ok || iq.Type != "get" {
return
}
discoInfo, ok := iq.Payload.(*xmpp.DiscoInfo)
if !ok {
return
}
attrs := iq.PacketAttrs
iq = xmpp.NewIQ("result", attrs.To, attrs.From, attrs.Id, "en")
payload := xmpp.DiscoInfo{
Identity: identity,
XMLName: xml.Name{
Space: xmpp.NSDiscoInfo,
Local: "query",
},
Features: []xmpp.Feature{
{Var: xmpp.NSDiscoInfo},
{Var: xmpp.NSDiscoItems},
@ -53,54 +32,81 @@ func (c *Config) receiving(packet interface{}) (xmpp.Packet, bool) {
{Var: xmpp.NSMsgChatStateNotifications},
},
}
iq.AddPayload(&payload)
loggerIQ.Debug("disco info")
return iq, true
if discoInfo.Node == "" {
payload.Identity = xmpp.Identity{
Name: c.Type,
Category: "gateway",
Type: "service",
}
}
iq.Payload = &payload
log.WithFields(map[string]interface{}{
"type": c.Type,
"from": s,
"to": attrs.To,
}).Debug("disco info")
s.Send(iq)
}
case *xmpp.DiscoItems:
if p.Type == "get" {
iq := xmpp.NewIQ("result", attrs.To, attrs.From, attrs.Id, "en")
func (c *Config) handleDiscoItems(s xmpp.Sender, p xmpp.Packet) {
iq, ok := p.(xmpp.IQ)
if !ok || iq.Type != "get" {
return
}
discoItems, ok := iq.Payload.(*xmpp.DiscoItems)
if !ok {
return
}
attrs := iq.PacketAttrs
iq = xmpp.NewIQ("result", attrs.To, attrs.From, attrs.Id, "en")
var payload xmpp.DiscoItems
if inner.Node == "" {
payload = xmpp.DiscoItems{
Items: []xmpp.DiscoItem{
payload := xmpp.DiscoItems{}
if discoItems.Node == "" {
payload.Items = []xmpp.DiscoItem{
{Name: c.Type, JID: c.Host, Node: "node1"},
},
}
}
iq.AddPayload(&payload)
loggerIQ.Debug("disco items")
return iq, true
iq.Payload = &payload
log.WithFields(map[string]interface{}{
"type": c.Type,
"from": s,
"to": attrs.To,
}).Debug("disco items")
s.Send(iq)
}
func (c *Config) handleIQ(s xmpp.Sender, p xmpp.Packet) {
iq, ok := p.(xmpp.IQ)
if !ok || iq.Type != "get" {
return
}
default:
logger.Debug("ignoring iq packet", inner)
xError := xmpp.Err{
Code: 501,
Reason: "feature-not-implemented",
Type: "cancel",
}
reply := p.MakeError(xError)
resp := iq.MakeError(xError)
attrs := iq.PacketAttrs
return reply, true
}
case xmpp.Message:
if c.XMPPDebug {
logger.WithFields(map[string]interface{}{
"from": p.PacketAttrs.From,
"to": p.PacketAttrs.To,
"id": p.PacketAttrs.Id,
}).Debug(p.XMPPFormat())
}
return p, false
case xmpp.Presence:
logger.Debug("received presence:", p.Type)
default:
logger.Debug("ignoring packet:", packet)
}
return nil, false
log.WithFields(map[string]interface{}{
"type": c.Type,
"from": s,
"to": attrs.To,
}).Debugf("ignore: %s", iq.Payload)
s.Send(resp)
}
func (c *Config) handleMessage(s xmpp.Sender, p xmpp.Packet) {
msg, ok := p.(xmpp.Message)
if !ok {
return
}
if c.XMPPDebug {
log.WithFields(map[string]interface{}{
"type": c.Type,
"from": s,
"to": msg.PacketAttrs.To,
"id": msg.PacketAttrs.Id,
}).Debug(msg.XMPPFormat())
}
c.comp.Send(p)
}

View File

@ -7,59 +7,102 @@ import (
"gosrc.io/xmpp"
)
type dummyComp struct {
Component
LastPacket xmpp.Packet
}
func (d *dummyComp) Connect() (chan xmpp.Packet, error) {
return nil, nil
}
func (d *dummyComp) Send(a xmpp.Packet) {
d.LastPacket = a
}
type dummyXMPP struct {
xmpp.Sender
LastPacket xmpp.Packet
}
func (d *dummyXMPP) Send(a xmpp.Packet) error {
d.LastPacket = a
return nil
}
func TestReceive(t *testing.T) {
assert := assert.New(t)
s := &dummyXMPP{}
c := Config{Host: "example.org", Type: "monkeyservice", XMPPDebug: true}
// ignoring packet
p, _ := c.receiving(xmpp.Handshake{})
assert.Nil(p)
// receive presence
p, _ = c.receiving(xmpp.Presence{})
assert.Nil(p)
comp := &dummyComp{}
c := Config{
Host: "example.org",
Type: "monkeyservice",
XMPPDebug: true,
comp: comp,
}
// message
p, back := c.receiving(xmpp.Message{})
assert.False(back)
assert.NotNil(p)
c.handleMessage(s, xmpp.IQ{})
assert.Nil(comp.LastPacket)
c.handleMessage(s, xmpp.Message{})
_, ok := comp.LastPacket.(xmpp.Message)
assert.True(ok)
// unsupported iq
p, back = c.receiving(xmpp.IQ{Payload: []xmpp.IQPayload{
&xmpp.Err{},
}})
assert.True(back)
assert.NotNil(p)
iq := p.(xmpp.IQ)
c.handleIQ(s, xmpp.IQ{})
assert.Nil(s.LastPacket)
c.handleIQ(s, xmpp.IQ{
PacketAttrs: xmpp.PacketAttrs{Type: "get"},
})
assert.NotNil(s.LastPacket)
iq := s.LastPacket.(xmpp.IQ)
assert.Equal("error", iq.Type)
assert.Equal("feature-not-implemented", iq.Error.Reason)
s.LastPacket = nil
// iq disco info
p, back = c.receiving(xmpp.IQ{
PacketAttrs: xmpp.PacketAttrs{Type: "get"},
Payload: []xmpp.IQPayload{
&xmpp.DiscoInfo{},
},
c.handleDiscoInfo(s, xmpp.IQ{
Payload: &xmpp.DiscoInfo{},
})
assert.True(back)
assert.NotNil(p)
iq = p.(xmpp.IQ)
assert.Nil(s.LastPacket)
c.handleDiscoInfo(s, xmpp.IQ{
PacketAttrs: xmpp.PacketAttrs{Type: "get"},
})
assert.Nil(s.LastPacket)
c.handleDiscoInfo(s, xmpp.IQ{
PacketAttrs: xmpp.PacketAttrs{Type: "get"},
Payload: &xmpp.DiscoInfo{},
})
assert.NotNil(s.LastPacket)
iq = s.LastPacket.(xmpp.IQ)
assert.Equal("result", iq.Type)
dinfo := iq.Payload[0].(*xmpp.DiscoInfo)
dinfo := iq.Payload.(*xmpp.DiscoInfo)
assert.Equal("monkeyservice", dinfo.Identity.Name)
s.LastPacket = nil
// iq disco items
p, back = c.receiving(xmpp.IQ{
PacketAttrs: xmpp.PacketAttrs{Type: "get"},
Payload: []xmpp.IQPayload{
&xmpp.DiscoItems{},
},
c.handleDiscoItems(s, xmpp.IQ{
Payload: &xmpp.DiscoItems{},
})
assert.True(back)
assert.NotNil(p)
iq = p.(xmpp.IQ)
assert.Nil(s.LastPacket)
c.handleDiscoItems(s, xmpp.IQ{
PacketAttrs: xmpp.PacketAttrs{Type: "get"},
})
assert.Nil(s.LastPacket)
c.handleDiscoItems(s, xmpp.IQ{
PacketAttrs: xmpp.PacketAttrs{Type: "get"},
Payload: &xmpp.DiscoItems{},
})
assert.NotNil(s.LastPacket)
iq = s.LastPacket.(xmpp.IQ)
assert.Equal("result", iq.Type)
ditems := iq.Payload[0].(*xmpp.DiscoItems)
ditems := iq.Payload.(*xmpp.DiscoItems)
assert.Equal("monkeyservice", ditems.Items[0].Name)
s.LastPacket = nil
}