Use our own version of go-xmpp with debug output to logrus

This commit is contained in:
Wim 2018-02-27 22:55:55 +01:00
parent 02a5bc096f
commit 6a727b9723
8 changed files with 60 additions and 28 deletions

View File

@ -6,7 +6,7 @@ import (
"github.com/42wim/matterbridge/bridge/config" "github.com/42wim/matterbridge/bridge/config"
"github.com/42wim/matterbridge/bridge/helper" "github.com/42wim/matterbridge/bridge/helper"
"github.com/jpillora/backoff" "github.com/jpillora/backoff"
"github.com/mattn/go-xmpp" "github.com/matterbridge/go-xmpp"
"strings" "strings"
"time" "time"
) )
@ -105,6 +105,7 @@ func (b *Bxmpp) createXMPP() (*xmpp.Client, error) {
TLSConfig: tc, TLSConfig: tc,
Debug: b.General.Debug, Debug: b.General.Debug,
Logger: b.Log.Writer(),
Session: true, Session: true,
Status: "", Status: "",
StatusMessage: "", StatusMessage: "",

View File

@ -68,6 +68,11 @@ func (c *Client) JID() string {
return c.jid return c.jid
} }
func containsIgnoreCase(s, substr string) bool {
s, substr = strings.ToUpper(s), strings.ToUpper(substr)
return strings.Contains(s, substr)
}
func connect(host, user, passwd string) (net.Conn, error) { func connect(host, user, passwd string) (net.Conn, error) {
addr := host addr := host
@ -81,16 +86,34 @@ func connect(host, user, passwd string) (net.Conn, error) {
if len(a) == 1 { if len(a) == 1 {
addr += ":5222" addr += ":5222"
} }
proxy := os.Getenv("HTTP_PROXY") proxy := os.Getenv("HTTP_PROXY")
if proxy == "" { if proxy == "" {
proxy = os.Getenv("http_proxy") proxy = os.Getenv("http_proxy")
} }
// test for no proxy, takes a comma separated list with substrings to match
if proxy != "" {
noproxy := os.Getenv("NO_PROXY")
if noproxy == "" {
noproxy = os.Getenv("no_proxy")
}
if noproxy != "" {
nplist := strings.Split(noproxy, ",")
for _, s := range nplist {
if containsIgnoreCase(addr, s) {
proxy = ""
break
}
}
}
}
if proxy != "" { if proxy != "" {
url, err := url.Parse(proxy) url, err := url.Parse(proxy)
if err == nil { if err == nil {
addr = url.Host addr = url.Host
} }
} }
c, err := net.Dial("tcp", addr) c, err := net.Dial("tcp", addr)
if err != nil { if err != nil {
return nil, err return nil, err
@ -168,6 +191,9 @@ type Options struct {
// Status message // Status message
StatusMessage string StatusMessage string
// Logger
Logger io.Writer
} }
// NewClient establishes a new Client connection based on a set of Options. // NewClient establishes a new Client connection based on a set of Options.
@ -501,7 +527,7 @@ func (c *Client) startTLSIfRequired(f *streamFeatures, o *Options, domain string
// will be returned. // will be returned.
func (c *Client) startStream(o *Options, domain string) (*streamFeatures, error) { func (c *Client) startStream(o *Options, domain string) (*streamFeatures, error) {
if o.Debug { if o.Debug {
c.p = xml.NewDecoder(tee{c.conn, os.Stderr}) c.p = xml.NewDecoder(tee{c.conn, o.Logger})
} else { } else {
c.p = xml.NewDecoder(c.conn) c.p = xml.NewDecoder(c.conn)
} }
@ -545,6 +571,8 @@ type Chat struct {
Remote string Remote string
Type string Type string
Text string Text string
Subject string
Thread string
Roster Roster Roster Roster
Other []string Other []string
OtherElem []XMLElement OtherElem []XMLElement
@ -594,6 +622,8 @@ func (c *Client) Recv() (stanza interface{}, err error) {
Remote: v.From, Remote: v.From,
Type: v.Type, Type: v.Type,
Text: v.Body, Text: v.Body,
Subject: v.Subject,
Thread: v.Thread,
Other: v.OtherStrings(), Other: v.OtherStrings(),
OtherElem: v.Other, OtherElem: v.Other,
Stamp: stamp, Stamp: stamp,
@ -609,7 +639,7 @@ func (c *Client) Recv() (stanza interface{}, err error) {
return Presence{v.From, v.To, v.Type, v.Show, v.Status}, nil return Presence{v.From, v.To, v.Type, v.Show, v.Status}, nil
case *clientIQ: case *clientIQ:
// TODO check more strictly // TODO check more strictly
if bytes.Equal(v.Query, []byte(`<ping xmlns='urn:xmpp:ping'/>`)) || bytes.Equal(v.Query, []byte(`<ping xmlns="urn:xmpp:ping"/>`)) { if bytes.Equal(bytes.TrimSpace(v.Query), []byte(`<ping xmlns='urn:xmpp:ping'/>`)) || bytes.Equal(bytes.TrimSpace(v.Query), []byte(`<ping xmlns="urn:xmpp:ping"/>`)) {
err := c.SendResultPing(v.ID, v.From) err := c.SendResultPing(v.ID, v.From)
if err != nil { if err != nil {
return Chat{}, err return Chat{}, err
@ -622,7 +652,15 @@ func (c *Client) Recv() (stanza interface{}, err error) {
// Send sends the message wrapped inside an XMPP message stanza body. // Send sends the message wrapped inside an XMPP message stanza body.
func (c *Client) Send(chat Chat) (n int, err error) { func (c *Client) Send(chat Chat) (n int, err error) {
return fmt.Fprintf(c.conn, "<message to='%s' type='%s' xml:lang='en'>"+"<body>%s</body></message>", var subtext = ``
var thdtext = ``
if chat.Subject != `` {
subtext = `<subject>` + xmlEscape(chat.Subject) + `</subject>`
}
if chat.Thread != `` {
thdtext = `<thread>` + xmlEscape(chat.Thread) + `</thread>`
}
return fmt.Fprintf(c.conn, "<message to='%s' type='%s' xml:lang='en'>"+subtext+"<body>%s</body>"+thdtext+"</message>",
xmlEscape(chat.Remote), xmlEscape(chat.Type), xmlEscape(chat.Text)) xmlEscape(chat.Remote), xmlEscape(chat.Type), xmlEscape(chat.Text))
} }
@ -901,24 +939,10 @@ func next(p *xml.Decoder) (xml.Name, interface{}, error) {
return se.Name, nv, err return se.Name, nv, err
} }
var xmlSpecial = map[byte]string{
'<': "&lt;",
'>': "&gt;",
'"': "&quot;",
'\'': "&apos;",
'&': "&amp;",
}
func xmlEscape(s string) string { func xmlEscape(s string) string {
var b bytes.Buffer var b bytes.Buffer
for i := 0; i < len(s); i++ { xml.Escape(&b, []byte(s))
c := s[i]
if s, ok := xmlSpecial[c]; ok {
b.WriteString(s)
} else {
b.WriteByte(c)
}
}
return b.String() return b.String()
} }

View File

@ -22,3 +22,10 @@ func (c *Client) RawInformationQuery(from, to, id, iqType, requestNamespace, bod
_, err := fmt.Fprintf(c.conn, xmlIQ, xmlEscape(from), xmlEscape(to), id, iqType, requestNamespace, body) _, err := fmt.Fprintf(c.conn, xmlIQ, xmlEscape(from), xmlEscape(to), id, iqType, requestNamespace, body)
return id, err return id, err
} }
// rawInformation send a IQ request with the the payload body to the server
func (c *Client) RawInformation(from, to, id, iqType, body string) (string, error) {
const xmlIQ = "<iq from='%s' to='%s' id='%s' type='%s'>%s</iq>"
_, err := fmt.Fprintf(c.conn, xmlIQ, xmlEscape(from), xmlEscape(to), id, iqType, body)
return id, err
}

16
vendor/manifest vendored
View File

@ -286,6 +286,14 @@
"branch": "master", "branch": "master",
"notests": true "notests": true
}, },
{
"importpath": "github.com/matterbridge/go-xmpp",
"repository": "https://github.com/matterbridge/go-xmpp",
"vcs": "git",
"revision": "0aa93db586ce719b8793aace600ddea0fdc7e828",
"branch": "work",
"notests": true
},
{ {
"importpath": "github.com/matterbridge/gomatrix", "importpath": "github.com/matterbridge/gomatrix",
"repository": "https://github.com/matterbridge/gomatrix", "repository": "https://github.com/matterbridge/gomatrix",
@ -427,14 +435,6 @@
"branch": "master", "branch": "master",
"notests": true "notests": true
}, },
{
"importpath": "github.com/mattn/go-xmpp",
"repository": "https://github.com/mattn/go-xmpp",
"vcs": "git",
"revision": "d0cdb99fae16437f69616ccc40662b6fe8ac6d47",
"branch": "master",
"notests": true
},
{ {
"importpath": "github.com/mgutz/ansi", "importpath": "github.com/mgutz/ansi",
"repository": "https://github.com/mgutz/ansi", "repository": "https://github.com/mgutz/ansi",