IQ error management
This commit is contained in:
parent
8470c01c09
commit
fb8d050a00
|
@ -1,7 +1,6 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/xml"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"fluux.io/xmpp"
|
"fluux.io/xmpp"
|
||||||
|
@ -22,28 +21,28 @@ func main() {
|
||||||
switch p := packet.(type) {
|
switch p := packet.(type) {
|
||||||
case xmpp.IQ:
|
case xmpp.IQ:
|
||||||
switch inner := p.Payload[0].(type) {
|
switch inner := p.Payload[0].(type) {
|
||||||
case *xmpp.Node:
|
case *xmpp.DiscoInfo:
|
||||||
fmt.Printf("%q\n", inner)
|
fmt.Println("Disco Info")
|
||||||
|
if p.Type == "get" {
|
||||||
data, err := xml.Marshal(inner)
|
DiscoResult(component, p.From, p.To, p.Id)
|
||||||
if err != nil {
|
|
||||||
fmt.Println("cannot marshall payload")
|
|
||||||
}
|
}
|
||||||
fmt.Println("data=", string(data))
|
|
||||||
component.processIQ(p.Type, p.Id, p.From, inner)
|
|
||||||
default:
|
default:
|
||||||
fmt.Println("default")
|
fmt.Println("ignoring iq packet", inner)
|
||||||
|
xerror := xmpp.Err{
|
||||||
|
Code: 501,
|
||||||
|
Reason: "feature-not-implemented",
|
||||||
|
Type: "cancel",
|
||||||
|
}
|
||||||
|
reply := p.MakeError(xerror)
|
||||||
|
component.xmpp.Send(&reply)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
fmt.Println("Packet unhandled packet:", packet)
|
fmt.Println("ignoring packet:", packet)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
|
||||||
NSDiscoInfo = "http://jabber.org/protocol/disco#info"
|
|
||||||
)
|
|
||||||
|
|
||||||
type MyComponent struct {
|
type MyComponent struct {
|
||||||
Name string
|
Name string
|
||||||
// Typical categories and types: https://xmpp.org/registrar/disco-categories.html
|
// Typical categories and types: https://xmpp.org/registrar/disco-categories.html
|
||||||
|
@ -53,35 +52,19 @@ type MyComponent struct {
|
||||||
xmpp *xmpp.Component
|
xmpp *xmpp.Component
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c MyComponent) processIQ(iqType, id, from string, inner *xmpp.Node) {
|
func DiscoResult(c MyComponent, from, to, id string) {
|
||||||
fmt.Println("Node:", inner.XMLName.Space, inner.XMLName.Local)
|
iq := xmpp.NewIQ("result", to, from, id, "en")
|
||||||
switch inner.XMLName.Space + " " + iqType {
|
payload := xmpp.DiscoInfo{
|
||||||
case NSDiscoInfo + " get":
|
Identity: xmpp.Identity{
|
||||||
fmt.Println("Send Disco Info")
|
Name: c.Name,
|
||||||
|
Category: c.Category,
|
||||||
iq := xmpp.NewIQ("result", "admin@localhost", "test@localhost", "1", "en")
|
Type: c.Type,
|
||||||
payload := xmpp.DiscoInfo{
|
},
|
||||||
Identity: xmpp.Identity{
|
Features: []xmpp.Feature{
|
||||||
Name: "Test Gateway",
|
{Var: "http://jabber.org/protocol/disco#info"},
|
||||||
Category: "gateway",
|
{Var: "http://jabber.org/protocol/disco#item"},
|
||||||
Type: "mqtt",
|
},
|
||||||
},
|
|
||||||
Features: []xmpp.Feature{
|
|
||||||
{Var: "http://jabber.org/protocol/disco#info"},
|
|
||||||
{Var: "http://jabber.org/protocol/disco#item"},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
iq.AddPayload(&payload)
|
|
||||||
c.xmpp.Send(iq)
|
|
||||||
default:
|
|
||||||
iqErr := fmt.Sprintf(`<iq type='error'
|
|
||||||
from='%s'
|
|
||||||
to='%s'
|
|
||||||
id='%s'>
|
|
||||||
<error type="cancel" code="501">
|
|
||||||
<feature-not-implemented xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
|
|
||||||
</error>
|
|
||||||
</iq>`, c.xmpp.Host, from, id)
|
|
||||||
c.xmpp.SendOld(iqErr) // FIXME Remove that method
|
|
||||||
}
|
}
|
||||||
|
iq.AddPayload(&payload)
|
||||||
|
c.xmpp.Send(iq)
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,13 +106,6 @@ func (c *Component) Send(packet Packet) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Component) SendOld(packet string) error {
|
|
||||||
if _, err := fmt.Fprintf(c.conn, packet); err != nil {
|
|
||||||
return errors.New("cannot send packet " + err.Error())
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// Handshake Packet
|
// Handshake Packet
|
||||||
|
|
||||||
|
|
38
iq.go
38
iq.go
|
@ -67,12 +67,14 @@ TODO support ability to put Raw payload
|
||||||
|
|
||||||
type Err struct {
|
type Err struct {
|
||||||
XMLName xml.Name `xml:"error"`
|
XMLName xml.Name `xml:"error"`
|
||||||
|
Code int `xml:"code,attr,omitempty"`
|
||||||
|
Type string `xml:"type,attr,omitempty"`
|
||||||
Reason string
|
Reason string
|
||||||
Code int `xml:"code,attr,omitempty"`
|
Text string `xml:"urn:ietf:params:xml:ns:xmpp-stanzas text,omitempty"`
|
||||||
Type string `xml:"type,attr,omitempty"`
|
|
||||||
Text string `xml:"urn:ietf:params:xml:ns:xmpp-stanzas text"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*Err) IsIQPayload() {}
|
||||||
|
|
||||||
// UnmarshalXML implements custom parsing for IQs
|
// UnmarshalXML implements custom parsing for IQs
|
||||||
func (x *Err) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
func (x *Err) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
||||||
x.XMLName = start.Name
|
x.XMLName = start.Name
|
||||||
|
@ -135,15 +137,19 @@ func (x Err) MarshalXML(e *xml.Encoder, start xml.StartElement) (err error) {
|
||||||
|
|
||||||
// Subtags
|
// Subtags
|
||||||
// Reason
|
// Reason
|
||||||
reason := xml.Name{Space: "urn:ietf:params:xml:ns:xmpp-stanzas", Local: x.Reason}
|
if x.Reason != "" {
|
||||||
e.EncodeToken(xml.StartElement{Name: reason})
|
reason := xml.Name{Space: "urn:ietf:params:xml:ns:xmpp-stanzas", Local: x.Reason}
|
||||||
e.EncodeToken(xml.EndElement{Name: reason})
|
e.EncodeToken(xml.StartElement{Name: reason})
|
||||||
|
e.EncodeToken(xml.EndElement{Name: reason})
|
||||||
|
}
|
||||||
|
|
||||||
// Text
|
// Text
|
||||||
text := xml.Name{Space: "urn:ietf:params:xml:ns:xmpp-stanzas", Local: "text"}
|
if x.Text != "" {
|
||||||
e.EncodeToken(xml.StartElement{Name: text})
|
text := xml.Name{Space: "urn:ietf:params:xml:ns:xmpp-stanzas", Local: "text"}
|
||||||
e.EncodeToken(xml.CharData(x.Text))
|
e.EncodeToken(xml.StartElement{Name: text})
|
||||||
e.EncodeToken(xml.EndElement{Name: text})
|
e.EncodeToken(xml.CharData(x.Text))
|
||||||
|
e.EncodeToken(xml.EndElement{Name: text})
|
||||||
|
}
|
||||||
|
|
||||||
return e.EncodeToken(xml.EndElement{Name: start.Name})
|
return e.EncodeToken(xml.EndElement{Name: start.Name})
|
||||||
}
|
}
|
||||||
|
@ -176,6 +182,18 @@ func (iq *IQ) AddPayload(payload IQPayload) {
|
||||||
iq.Payload = append(iq.Payload, payload)
|
iq.Payload = append(iq.Payload, payload)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (iq IQ) MakeError(xerror Err) IQ {
|
||||||
|
from := iq.From
|
||||||
|
to := iq.To
|
||||||
|
|
||||||
|
iq.Type = "error"
|
||||||
|
iq.From = to
|
||||||
|
iq.To = from
|
||||||
|
iq.Error = xerror
|
||||||
|
|
||||||
|
return iq
|
||||||
|
}
|
||||||
|
|
||||||
func (IQ) Name() string {
|
func (IQ) Name() string {
|
||||||
return "iq"
|
return "iq"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue