forked from jshiffer/go-xmpp
Add initial support for stream management
For now it support enabling SM, replying to ack requests from server, and trying resuming the session with existing Stream Management state.
This commit is contained in:

committed by
Mickaël Rémond

parent
e531370dc9
commit
3de99e0e0e
@@ -63,6 +63,8 @@ func NextPacket(p *xml.Decoder) (Packet, error) {
|
||||
return decodeClient(p, se)
|
||||
case NSComponent:
|
||||
return decodeComponent(p, se)
|
||||
case NSStreamManagement:
|
||||
return sm.decode(p, se)
|
||||
default:
|
||||
return nil, errors.New("unknown namespace " +
|
||||
se.Name.Space + " <" + se.Name.Local + "/>")
|
||||
@@ -133,7 +135,7 @@ func decodeClient(p *xml.Decoder, se xml.StartElement) (Packet, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// decodeClient decodes all known packets in the component namespace.
|
||||
// decodeComponent decodes all known packets in the component namespace.
|
||||
func decodeComponent(p *xml.Decoder, se xml.StartElement) (Packet, error) {
|
||||
switch se.Name.Local {
|
||||
case "handshake": // handshake is used to authenticate components
|
||||
|
121
stanza/stream_management.go
Normal file
121
stanza/stream_management.go
Normal file
@@ -0,0 +1,121 @@
|
||||
package stanza
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
)
|
||||
|
||||
const (
|
||||
NSStreamManagement = "urn:xmpp:sm:3"
|
||||
)
|
||||
|
||||
// Enabled as defined in Stream Management spec
|
||||
// Reference: https://xmpp.org/extensions/xep-0198.html#enable
|
||||
type SMEnabled struct {
|
||||
XMLName xml.Name `xml:"urn:xmpp:sm:3 enabled"`
|
||||
Id string `xml:"id,attr,omitempty"`
|
||||
Location string `xml:"location,attr,omitempty"`
|
||||
Resume string `xml:"resume,attr,omitempty"`
|
||||
Max uint `xml:"max,attr,omitempty"`
|
||||
}
|
||||
|
||||
func (SMEnabled) Name() string {
|
||||
return "Stream Management: enabled"
|
||||
}
|
||||
|
||||
// Request as defined in Stream Management spec
|
||||
// Reference: https://xmpp.org/extensions/xep-0198.html#acking
|
||||
type SMRequest struct {
|
||||
XMLName xml.Name `xml:"urn:xmpp:sm:3 r"`
|
||||
}
|
||||
|
||||
func (SMRequest) Name() string {
|
||||
return "Stream Management: request"
|
||||
}
|
||||
|
||||
// Answer as defined in Stream Management spec
|
||||
// Reference: https://xmpp.org/extensions/xep-0198.html#acking
|
||||
type SMAnswer struct {
|
||||
XMLName xml.Name `xml:"urn:xmpp:sm:3 a"`
|
||||
H uint `xml:"h,attr,omitempty"`
|
||||
}
|
||||
|
||||
func (SMAnswer) Name() string {
|
||||
return "Stream Management: answer"
|
||||
}
|
||||
|
||||
// Resumed as defined in Stream Management spec
|
||||
// Reference: https://xmpp.org/extensions/xep-0198.html#acking
|
||||
type SMResumed struct {
|
||||
XMLName xml.Name `xml:"urn:xmpp:sm:3 resumed"`
|
||||
PrevId string `xml:"previd,attr,omitempty"`
|
||||
H uint `xml:"h,attr,omitempty"`
|
||||
}
|
||||
|
||||
func (SMResumed) Name() string {
|
||||
return "Stream Management: resumed"
|
||||
}
|
||||
|
||||
// Failed as defined in Stream Management spec
|
||||
// Reference: https://xmpp.org/extensions/xep-0198.html#acking
|
||||
type SMFailed struct {
|
||||
XMLName xml.Name `xml:"urn:xmpp:sm:3 failed"`
|
||||
// TODO: Handle decoding error cause (need custom parsing).
|
||||
}
|
||||
|
||||
func (SMFailed) Name() string {
|
||||
return "Stream Management: failed"
|
||||
}
|
||||
|
||||
type smDecoder struct{}
|
||||
|
||||
var sm smDecoder
|
||||
|
||||
// decode decodes all known nonza in the stream management namespace.
|
||||
func (s smDecoder) decode(p *xml.Decoder, se xml.StartElement) (Packet, error) {
|
||||
switch se.Name.Local {
|
||||
case "enabled":
|
||||
return s.decodeEnabled(p, se)
|
||||
case "resumed":
|
||||
return s.decodeResumed(p, se)
|
||||
case "r":
|
||||
return s.decodeRequest(p, se)
|
||||
case "h":
|
||||
return s.decodeAnswer(p, se)
|
||||
case "failed":
|
||||
return s.decodeFailed(p, se)
|
||||
default:
|
||||
return nil, errors.New("unexpected XMPP packet " +
|
||||
se.Name.Space + " <" + se.Name.Local + "/>")
|
||||
}
|
||||
}
|
||||
|
||||
func (smDecoder) decodeEnabled(p *xml.Decoder, se xml.StartElement) (SMEnabled, error) {
|
||||
var packet SMEnabled
|
||||
err := p.DecodeElement(&packet, &se)
|
||||
return packet, err
|
||||
}
|
||||
|
||||
func (smDecoder) decodeResumed(p *xml.Decoder, se xml.StartElement) (SMResumed, error) {
|
||||
var packet SMResumed
|
||||
err := p.DecodeElement(&packet, &se)
|
||||
return packet, err
|
||||
}
|
||||
|
||||
func (smDecoder) decodeRequest(p *xml.Decoder, se xml.StartElement) (SMRequest, error) {
|
||||
var packet SMRequest
|
||||
err := p.DecodeElement(&packet, &se)
|
||||
return packet, err
|
||||
}
|
||||
|
||||
func (smDecoder) decodeAnswer(p *xml.Decoder, se xml.StartElement) (SMAnswer, error) {
|
||||
var packet SMAnswer
|
||||
err := p.DecodeElement(&packet, &se)
|
||||
return packet, err
|
||||
}
|
||||
|
||||
func (smDecoder) decodeFailed(p *xml.Decoder, se xml.StartElement) (SMFailed, error) {
|
||||
var packet SMFailed
|
||||
err := p.DecodeElement(&packet, &se)
|
||||
return packet, err
|
||||
}
|
Reference in New Issue
Block a user