From fb8d050a001f75288cfe6b91e54e0ef186639240 Mon Sep 17 00:00:00 2001 From: Mickael Remond Date: Sat, 20 Jan 2018 18:56:07 +0100 Subject: [PATCH] IQ error management --- cmd/xmpp_component/xmpp_component.go | 73 +++++++++++----------------- component.go | 7 --- iq.go | 38 +++++++++++---- 3 files changed, 56 insertions(+), 62 deletions(-) diff --git a/cmd/xmpp_component/xmpp_component.go b/cmd/xmpp_component/xmpp_component.go index 01a222a..ec400e8 100644 --- a/cmd/xmpp_component/xmpp_component.go +++ b/cmd/xmpp_component/xmpp_component.go @@ -1,7 +1,6 @@ package main import ( - "encoding/xml" "fmt" "fluux.io/xmpp" @@ -22,28 +21,28 @@ func main() { switch p := packet.(type) { case xmpp.IQ: switch inner := p.Payload[0].(type) { - case *xmpp.Node: - fmt.Printf("%q\n", inner) - - data, err := xml.Marshal(inner) - if err != nil { - fmt.Println("cannot marshall payload") + case *xmpp.DiscoInfo: + fmt.Println("Disco Info") + if p.Type == "get" { + DiscoResult(component, p.From, p.To, p.Id) } - fmt.Println("data=", string(data)) - component.processIQ(p.Type, p.Id, p.From, inner) + 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: - fmt.Println("Packet unhandled packet:", packet) + fmt.Println("ignoring packet:", packet) } } } -const ( - NSDiscoInfo = "http://jabber.org/protocol/disco#info" -) - type MyComponent struct { Name string // Typical categories and types: https://xmpp.org/registrar/disco-categories.html @@ -53,35 +52,19 @@ type MyComponent struct { xmpp *xmpp.Component } -func (c MyComponent) processIQ(iqType, id, from string, inner *xmpp.Node) { - fmt.Println("Node:", inner.XMLName.Space, inner.XMLName.Local) - switch inner.XMLName.Space + " " + iqType { - case NSDiscoInfo + " get": - fmt.Println("Send Disco Info") - - iq := xmpp.NewIQ("result", "admin@localhost", "test@localhost", "1", "en") - payload := xmpp.DiscoInfo{ - Identity: xmpp.Identity{ - Name: "Test Gateway", - Category: "gateway", - 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(` - - - -`, c.xmpp.Host, from, id) - c.xmpp.SendOld(iqErr) // FIXME Remove that method +func DiscoResult(c MyComponent, from, to, id string) { + iq := xmpp.NewIQ("result", to, from, id, "en") + payload := xmpp.DiscoInfo{ + Identity: xmpp.Identity{ + Name: c.Name, + Category: c.Category, + Type: c.Type, + }, + Features: []xmpp.Feature{ + {Var: "http://jabber.org/protocol/disco#info"}, + {Var: "http://jabber.org/protocol/disco#item"}, + }, } + iq.AddPayload(&payload) + c.xmpp.Send(iq) } diff --git a/component.go b/component.go index 750bfc9..702c7d7 100644 --- a/component.go +++ b/component.go @@ -106,13 +106,6 @@ func (c *Component) Send(packet Packet) error { 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 diff --git a/iq.go b/iq.go index 68dd2b0..2ac7d0b 100644 --- a/iq.go +++ b/iq.go @@ -67,12 +67,14 @@ TODO support ability to put Raw payload type Err struct { XMLName xml.Name `xml:"error"` + Code int `xml:"code,attr,omitempty"` + Type string `xml:"type,attr,omitempty"` Reason string - Code int `xml:"code,attr,omitempty"` - Type string `xml:"type,attr,omitempty"` - Text string `xml:"urn:ietf:params:xml:ns:xmpp-stanzas text"` + Text string `xml:"urn:ietf:params:xml:ns:xmpp-stanzas text,omitempty"` } +func (*Err) IsIQPayload() {} + // UnmarshalXML implements custom parsing for IQs func (x *Err) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { x.XMLName = start.Name @@ -135,15 +137,19 @@ func (x Err) MarshalXML(e *xml.Encoder, start xml.StartElement) (err error) { // Subtags // Reason - reason := xml.Name{Space: "urn:ietf:params:xml:ns:xmpp-stanzas", Local: x.Reason} - e.EncodeToken(xml.StartElement{Name: reason}) - e.EncodeToken(xml.EndElement{Name: reason}) + if x.Reason != "" { + reason := xml.Name{Space: "urn:ietf:params:xml:ns:xmpp-stanzas", Local: x.Reason} + e.EncodeToken(xml.StartElement{Name: reason}) + e.EncodeToken(xml.EndElement{Name: reason}) + } // Text - text := xml.Name{Space: "urn:ietf:params:xml:ns:xmpp-stanzas", Local: "text"} - e.EncodeToken(xml.StartElement{Name: text}) - e.EncodeToken(xml.CharData(x.Text)) - e.EncodeToken(xml.EndElement{Name: text}) + if x.Text != "" { + text := xml.Name{Space: "urn:ietf:params:xml:ns:xmpp-stanzas", Local: "text"} + e.EncodeToken(xml.StartElement{Name: text}) + e.EncodeToken(xml.CharData(x.Text)) + e.EncodeToken(xml.EndElement{Name: text}) + } return e.EncodeToken(xml.EndElement{Name: start.Name}) } @@ -176,6 +182,18 @@ func (iq *IQ) AddPayload(payload IQPayload) { 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 { return "iq" }