Skip to content

Commit 98ff0d4

Browse files
authored
Rework printing of sent stanzas when debug is enabled (#148)
* Rework printing of sent stanzas when debug is enabled This got reworked to also work with multiple connections as pointed out by @vcabbage in #141 (comment) * Remove StanzaWriter.
1 parent bef3e54 commit 98ff0d4

File tree

5 files changed

+47
-47
lines changed

5 files changed

+47
-47
lines changed

xmpp.go

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ var DefaultConfig = &tls.Config{}
5555

5656
// DebugWriter is the writer used to write debugging output to.
5757
var DebugWriter io.Writer = os.Stderr
58-
var StanzaWriter io.Writer
5958

6059
// Cookie is a unique XMPP session identifier
6160
type Cookie uint64
@@ -70,10 +69,11 @@ func getCookie() Cookie {
7069

7170
// Client holds XMPP connection options
7271
type Client struct {
73-
conn net.Conn // connection to server
74-
jid string // Jabber ID for our connection
75-
domain string
76-
p *xml.Decoder
72+
conn net.Conn // connection to server
73+
jid string // Jabber ID for our connection
74+
domain string
75+
p *xml.Decoder
76+
stanzaWriter io.Writer
7777
}
7878

7979
func (c *Client) JID() string {
@@ -378,7 +378,7 @@ func (c *Client) init(o *Options) error {
378378
foundAnonymous := false
379379
for _, m := range f.Mechanisms.Mechanism {
380380
if m == "ANONYMOUS" {
381-
fmt.Fprintf(StanzaWriter, "<auth xmlns='%s' mechanism='ANONYMOUS' />\n", nsSASL)
381+
fmt.Fprintf(c.stanzaWriter, "<auth xmlns='%s' mechanism='ANONYMOUS' />\n", nsSASL)
382382
foundAnonymous = true
383383
break
384384
}
@@ -436,7 +436,7 @@ func (c *Client) init(o *Options) error {
436436
}
437437
clientNonce := cnonce()
438438
clientFirstMessage := "n=" + user + ",r=" + clientNonce
439-
fmt.Fprintf(StanzaWriter, "<auth xmlns='%s' mechanism='%s'>%s</auth>",
439+
fmt.Fprintf(c.stanzaWriter, "<auth xmlns='%s' mechanism='%s'>%s</auth>",
440440
nsSASL, mechanism, base64.StdEncoding.EncodeToString([]byte("n,,"+
441441
clientFirstMessage)))
442442
var sfm string
@@ -536,15 +536,15 @@ func (c *Client) init(o *Options) error {
536536
}
537537
clientFinalMessage := base64.StdEncoding.EncodeToString([]byte(clientFinalMessageBare +
538538
",p=" + base64.StdEncoding.EncodeToString(clientProof)))
539-
fmt.Fprintf(StanzaWriter, "<response xmlns='%s'>%s</response>", nsSASL,
539+
fmt.Fprintf(c.stanzaWriter, "<response xmlns='%s'>%s</response>", nsSASL,
540540
clientFinalMessage)
541541
}
542542
if mechanism == "X-OAUTH2" && o.OAuthToken != "" && o.OAuthScope != "" {
543543
// Oauth authentication: send base64-encoded \x00 user \x00 token.
544544
raw := "\x00" + user + "\x00" + o.OAuthToken
545545
enc := make([]byte, base64.StdEncoding.EncodedLen(len(raw)))
546546
base64.StdEncoding.Encode(enc, []byte(raw))
547-
fmt.Fprintf(StanzaWriter, "<auth xmlns='%s' mechanism='X-OAUTH2' auth:service='oauth2' "+
547+
fmt.Fprintf(c.stanzaWriter, "<auth xmlns='%s' mechanism='X-OAUTH2' auth:service='oauth2' "+
548548
"xmlns:auth='%s'>%s</auth>\n", nsSASL, o.OAuthXmlNs, enc)
549549
}
550550
if mechanism == "PLAIN" {
@@ -556,7 +556,7 @@ func (c *Client) init(o *Options) error {
556556
}
557557
if mechanism == "DIGEST-MD5" {
558558
// Digest-MD5 authentication
559-
fmt.Fprintf(StanzaWriter, "<auth xmlns='%s' mechanism='DIGEST-MD5'/>\n", nsSASL)
559+
fmt.Fprintf(c.stanzaWriter, "<auth xmlns='%s' mechanism='DIGEST-MD5'/>\n", nsSASL)
560560
var ch saslChallenge
561561
if err = c.p.DecodeElement(&ch, nil); err != nil {
562562
return errors.New("unmarshal <challenge>: " + err.Error())
@@ -586,7 +586,7 @@ func (c *Client) init(o *Options) error {
586586
message := "username=\"" + user + "\", realm=\"" + realm + "\", nonce=\"" + nonce + "\", cnonce=\"" + cnonceStr +
587587
"\", nc=" + nonceCount + ", qop=" + qop + ", digest-uri=\"" + digestURI + "\", response=" + digest + ", charset=" + charset
588588

589-
fmt.Fprintf(StanzaWriter, "<response xmlns='%s'>%s</response>\n", nsSASL, base64.StdEncoding.EncodeToString([]byte(message)))
589+
fmt.Fprintf(c.stanzaWriter, "<response xmlns='%s'>%s</response>\n", nsSASL, base64.StdEncoding.EncodeToString([]byte(message)))
590590

591591
var rspauth saslRspAuth
592592
if err = c.p.DecodeElement(&rspauth, nil); err != nil {
@@ -596,7 +596,7 @@ func (c *Client) init(o *Options) error {
596596
if err != nil {
597597
return err
598598
}
599-
fmt.Fprintf(StanzaWriter, "<response xmlns='%s'/>\n", nsSASL)
599+
fmt.Fprintf(c.stanzaWriter, "<response xmlns='%s'/>\n", nsSASL)
600600
}
601601
}
602602
if mechanism == "" {
@@ -649,9 +649,9 @@ func (c *Client) init(o *Options) error {
649649

650650
// Send IQ message asking to bind to the local user name.
651651
if o.Resource == "" {
652-
fmt.Fprintf(StanzaWriter, "<iq type='set' id='%x'><bind xmlns='%s'></bind></iq>\n", cookie, nsBind)
652+
fmt.Fprintf(c.stanzaWriter, "<iq type='set' id='%x'><bind xmlns='%s'></bind></iq>\n", cookie, nsBind)
653653
} else {
654-
fmt.Fprintf(StanzaWriter, "<iq type='set' id='%x'><bind xmlns='%s'><resource>%s</resource></bind></iq>\n", cookie, nsBind, o.Resource)
654+
fmt.Fprintf(c.stanzaWriter, "<iq type='set' id='%x'><bind xmlns='%s'><resource>%s</resource></bind></iq>\n", cookie, nsBind, o.Resource)
655655
}
656656
var iq clientIQ
657657
if err = c.p.DecodeElement(&iq, nil); err != nil {
@@ -665,11 +665,11 @@ func (c *Client) init(o *Options) error {
665665

666666
if o.Session {
667667
//if server support session, open it
668-
fmt.Fprintf(StanzaWriter, "<iq to='%s' type='set' id='%x'><session xmlns='%s'/></iq>", xmlEscape(domain), cookie, nsSession)
668+
fmt.Fprintf(c.stanzaWriter, "<iq to='%s' type='set' id='%x'><session xmlns='%s'/></iq>", xmlEscape(domain), cookie, nsSession)
669669
}
670670

671671
// We're connected and can now receive and send messages.
672-
fmt.Fprintf(StanzaWriter, "<presence xml:lang='en'><show>%s</show><status>%s</status></presence>", o.Status, o.StatusMessage)
672+
fmt.Fprintf(c.stanzaWriter, "<presence xml:lang='en'><show>%s</show><status>%s</status></presence>", o.Status, o.StatusMessage)
673673

674674
return nil
675675
}
@@ -691,7 +691,7 @@ func (c *Client) startTLSIfRequired(f *streamFeatures, o *Options, domain string
691691
}
692692
var err error
693693

694-
fmt.Fprintf(StanzaWriter, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>\n")
694+
fmt.Fprintf(c.stanzaWriter, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>\n")
695695
var k tlsProceed
696696
if err = c.p.DecodeElement(&k, nil); err != nil {
697697
return f, errors.New("unmarshal <proceed>: " + err.Error())
@@ -724,13 +724,13 @@ func (c *Client) startTLSIfRequired(f *streamFeatures, o *Options, domain string
724724
func (c *Client) startStream(o *Options, domain string) (*streamFeatures, error) {
725725
if o.Debug {
726726
c.p = xml.NewDecoder(tee{c.conn, DebugWriter})
727-
StanzaWriter = io.MultiWriter(c.conn, DebugWriter)
727+
c.stanzaWriter = io.MultiWriter(c.conn, DebugWriter)
728728
} else {
729729
c.p = xml.NewDecoder(c.conn)
730-
StanzaWriter = c.conn
730+
c.stanzaWriter = c.conn
731731
}
732732

733-
_, err := fmt.Fprintf(StanzaWriter, "<?xml version='1.0'?>"+
733+
_, err := fmt.Fprintf(c.stanzaWriter, "<?xml version='1.0'?>"+
734734
"<stream:stream to='%s' xmlns='%s'"+
735735
" xmlns:stream='%s' version='1.0'>",
736736
xmlEscape(domain), nsClient, nsStream)
@@ -1058,7 +1058,7 @@ func (c *Client) Send(chat Chat) (n int, err error) {
10581058

10591059
stanza := "<message to='%s' type='%s' id='%s' xml:lang='en'>" + subtext + "<body>%s</body>" + oobtext + thdtext + "</message>"
10601060

1061-
return fmt.Fprintf(StanzaWriter, stanza,
1061+
return fmt.Fprintf(c.stanzaWriter, stanza,
10621062
xmlEscape(chat.Remote), xmlEscape(chat.Type), cnonce(), xmlEscape(chat.Text))
10631063
}
10641064

@@ -1075,17 +1075,17 @@ func (c *Client) SendOOB(chat Chat) (n int, err error) {
10751075
}
10761076
oobtext += `</x>`
10771077
}
1078-
return fmt.Fprintf(StanzaWriter, "<message to='%s' type='%s' id='%s' xml:lang='en'>"+oobtext+thdtext+"</message>",
1078+
return fmt.Fprintf(c.stanzaWriter, "<message to='%s' type='%s' id='%s' xml:lang='en'>"+oobtext+thdtext+"</message>",
10791079
xmlEscape(chat.Remote), xmlEscape(chat.Type), cnonce())
10801080
}
10811081

10821082
// SendOrg sends the original text without being wrapped in an XMPP message stanza.
10831083
func (c *Client) SendOrg(org string) (n int, err error) {
1084-
return fmt.Fprint(StanzaWriter, org)
1084+
return fmt.Fprint(c.stanzaWriter, org)
10851085
}
10861086

10871087
func (c *Client) SendPresence(presence Presence) (n int, err error) {
1088-
return fmt.Fprintf(StanzaWriter, "<presence from='%s' to='%s'/>", xmlEscape(presence.From), xmlEscape(presence.To))
1088+
return fmt.Fprintf(c.stanzaWriter, "<presence from='%s' to='%s'/>", xmlEscape(presence.From), xmlEscape(presence.To))
10891089
}
10901090

10911091
// SendKeepAlive sends a "whitespace keepalive" as described in chapter 4.6.1 of RFC6120.
@@ -1095,15 +1095,15 @@ func (c *Client) SendKeepAlive() (n int, err error) {
10951095

10961096
// SendHtml sends the message as HTML as defined by XEP-0071
10971097
func (c *Client) SendHtml(chat Chat) (n int, err error) {
1098-
return fmt.Fprintf(StanzaWriter, "<message to='%s' type='%s' xml:lang='en'>"+
1098+
return fmt.Fprintf(c.stanzaWriter, "<message to='%s' type='%s' xml:lang='en'>"+
10991099
"<body>%s</body>"+
11001100
"<html xmlns='http://jabber.org/protocol/xhtml-im'><body xmlns='http://www.w3.org/1999/xhtml'>%s</body></html></message>",
11011101
xmlEscape(chat.Remote), xmlEscape(chat.Type), xmlEscape(chat.Text), chat.Text)
11021102
}
11031103

11041104
// Roster asks for the chat roster.
11051105
func (c *Client) Roster() error {
1106-
fmt.Fprintf(StanzaWriter, "<iq from='%s' type='get' id='roster1'><query xmlns='jabber:iq:roster'/></iq>\n", xmlEscape(c.jid))
1106+
fmt.Fprintf(c.stanzaWriter, "<iq from='%s' type='get' id='roster1'><query xmlns='jabber:iq:roster'/></iq>\n", xmlEscape(c.jid))
11071107
return nil
11081108
}
11091109

xmpp_information_query.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,13 @@ func (c *Client) DiscoverEntityItems(jid string) (string, error) {
3535
// RawInformationQuery sends an information query request to the server.
3636
func (c *Client) RawInformationQuery(from, to, id, iqType, requestNamespace, body string) (string, error) {
3737
const xmlIQ = "<iq from='%s' to='%s' id='%s' type='%s'><query xmlns='%s'>%s</query></iq>"
38-
_, err := fmt.Fprintf(StanzaWriter, xmlIQ, xmlEscape(from), xmlEscape(to), id, iqType, requestNamespace, body)
38+
_, err := fmt.Fprintf(c.stanzaWriter, xmlIQ, xmlEscape(from), xmlEscape(to), id, iqType, requestNamespace, body)
3939
return id, err
4040
}
4141

4242
// rawInformation send a IQ request with the payload body to the server
4343
func (c *Client) RawInformation(from, to, id, iqType, body string) (string, error) {
4444
const xmlIQ = "<iq from='%s' to='%s' id='%s' type='%s'>%s</iq>"
45-
_, err := fmt.Fprintf(StanzaWriter, xmlIQ, xmlEscape(from), xmlEscape(to), id, iqType, body)
45+
_, err := fmt.Fprintf(c.stanzaWriter, xmlIQ, xmlEscape(from), xmlEscape(to), id, iqType, body)
4646
return id, err
4747
}

xmpp_muc.go

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,15 @@ const (
2525

2626
// Send sends room topic wrapped inside an XMPP message stanza body.
2727
func (c *Client) SendTopic(chat Chat) (n int, err error) {
28-
return fmt.Fprintf(StanzaWriter, "<message to='%s' type='%s' xml:lang='en'>"+"<subject>%s</subject></message>",
28+
return fmt.Fprintf(c.stanzaWriter, "<message to='%s' type='%s' xml:lang='en'>"+"<subject>%s</subject></message>",
2929
xmlEscape(chat.Remote), xmlEscape(chat.Type), xmlEscape(chat.Text))
3030
}
3131

3232
func (c *Client) JoinMUCNoHistory(jid, nick string) (n int, err error) {
3333
if nick == "" {
3434
nick = c.jid
3535
}
36-
return fmt.Fprintf(StanzaWriter, "<presence to='%s/%s'>\n"+
36+
return fmt.Fprintf(c.stanzaWriter, "<presence to='%s/%s'>\n"+
3737
"<x xmlns='%s'>"+
3838
"<history maxchars='0'/></x>\n"+
3939
"</presence>",
@@ -47,31 +47,31 @@ func (c *Client) JoinMUC(jid, nick string, history_type, history int, history_da
4747
}
4848
switch history_type {
4949
case NoHistory:
50-
return fmt.Fprintf(StanzaWriter, "<presence to='%s/%s'>\n"+
50+
return fmt.Fprintf(c.stanzaWriter, "<presence to='%s/%s'>\n"+
5151
"<x xmlns='%s' />\n"+
5252
"</presence>",
5353
xmlEscape(jid), xmlEscape(nick), nsMUC)
5454
case CharHistory:
55-
return fmt.Fprintf(StanzaWriter, "<presence to='%s/%s'>\n"+
55+
return fmt.Fprintf(c.stanzaWriter, "<presence to='%s/%s'>\n"+
5656
"<x xmlns='%s'>\n"+
5757
"<history maxchars='%d'/></x>\n"+
5858
"</presence>",
5959
xmlEscape(jid), xmlEscape(nick), nsMUC, history)
6060
case StanzaHistory:
61-
return fmt.Fprintf(StanzaWriter, "<presence to='%s/%s'>\n"+
61+
return fmt.Fprintf(c.stanzaWriter, "<presence to='%s/%s'>\n"+
6262
"<x xmlns='%s'>\n"+
6363
"<history maxstanzas='%d'/></x>\n"+
6464
"</presence>",
6565
xmlEscape(jid), xmlEscape(nick), nsMUC, history)
6666
case SecondsHistory:
67-
return fmt.Fprintf(StanzaWriter, "<presence to='%s/%s'>\n"+
67+
return fmt.Fprintf(c.stanzaWriter, "<presence to='%s/%s'>\n"+
6868
"<x xmlns='%s'>\n"+
6969
"<history seconds='%d'/></x>\n"+
7070
"</presence>",
7171
xmlEscape(jid), xmlEscape(nick), nsMUC, history)
7272
case SinceHistory:
7373
if history_date != nil {
74-
return fmt.Fprintf(StanzaWriter, "<presence to='%s/%s'>\n"+
74+
return fmt.Fprintf(c.stanzaWriter, "<presence to='%s/%s'>\n"+
7575
"<x xmlns='%s'>\n"+
7676
"<history since='%s'/></x>\n"+
7777
"</presence>",
@@ -88,36 +88,36 @@ func (c *Client) JoinProtectedMUC(jid, nick string, password string, history_typ
8888
}
8989
switch history_type {
9090
case NoHistory:
91-
return fmt.Fprintf(StanzaWriter, "<presence to='%s/%s'>\n"+
91+
return fmt.Fprintf(c.stanzaWriter, "<presence to='%s/%s'>\n"+
9292
"<x xmlns='%s'>\n"+
9393
"<password>%s</password>"+
9494
"</x>\n"+
9595
"</presence>",
9696
xmlEscape(jid), xmlEscape(nick), nsMUC, xmlEscape(password))
9797
case CharHistory:
98-
return fmt.Fprintf(StanzaWriter, "<presence to='%s/%s'>\n"+
98+
return fmt.Fprintf(c.stanzaWriter, "<presence to='%s/%s'>\n"+
9999
"<x xmlns='%s'>\n"+
100100
"<password>%s</password>\n"+
101101
"<history maxchars='%d'/></x>\n"+
102102
"</presence>",
103103
xmlEscape(jid), xmlEscape(nick), nsMUC, xmlEscape(password), history)
104104
case StanzaHistory:
105-
return fmt.Fprintf(StanzaWriter, "<presence to='%s/%s'>\n"+
105+
return fmt.Fprintf(c.stanzaWriter, "<presence to='%s/%s'>\n"+
106106
"<x xmlns='%s'>\n"+
107107
"<password>%s</password>\n"+
108108
"<history maxstanzas='%d'/></x>\n"+
109109
"</presence>",
110110
xmlEscape(jid), xmlEscape(nick), nsMUC, xmlEscape(password), history)
111111
case SecondsHistory:
112-
return fmt.Fprintf(StanzaWriter, "<presence to='%s/%s'>\n"+
112+
return fmt.Fprintf(c.stanzaWriter, "<presence to='%s/%s'>\n"+
113113
"<x xmlns='%s'>\n"+
114114
"<password>%s</password>\n"+
115115
"<history seconds='%d'/></x>\n"+
116116
"</presence>",
117117
xmlEscape(jid), xmlEscape(nick), nsMUC, xmlEscape(password), history)
118118
case SinceHistory:
119119
if history_date != nil {
120-
return fmt.Fprintf(StanzaWriter, "<presence to='%s/%s'>\n"+
120+
return fmt.Fprintf(c.stanzaWriter, "<presence to='%s/%s'>\n"+
121121
"<x xmlns='%s'>\n"+
122122
"<password>%s</password>\n"+
123123
"<history since='%s'/></x>\n"+
@@ -130,6 +130,6 @@ func (c *Client) JoinProtectedMUC(jid, nick string, password string, history_typ
130130

131131
// xep-0045 7.14
132132
func (c *Client) LeaveMUC(jid string) (n int, err error) {
133-
return fmt.Fprintf(StanzaWriter, "<presence from='%s' to='%s' type='unavailable' />",
133+
return fmt.Fprintf(c.stanzaWriter, "<presence from='%s' to='%s' type='unavailable' />",
134134
c.jid, xmlEscape(jid))
135135
}

xmpp_ping.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,23 @@ func (c *Client) PingC2S(jid, server string) error {
1111
if server == "" {
1212
server = c.domain
1313
}
14-
_, err := fmt.Fprintf(StanzaWriter, "<iq from='%s' to='%s' id='c2s1' type='get'>\n"+
14+
_, err := fmt.Fprintf(c.stanzaWriter, "<iq from='%s' to='%s' id='c2s1' type='get'>\n"+
1515
"<ping xmlns='urn:xmpp:ping'/>\n"+
1616
"</iq>",
1717
xmlEscape(jid), xmlEscape(server))
1818
return err
1919
}
2020

2121
func (c *Client) PingS2S(fromServer, toServer string) error {
22-
_, err := fmt.Fprintf(StanzaWriter, "<iq from='%s' to='%s' id='s2s1' type='get'>\n"+
22+
_, err := fmt.Fprintf(c.stanzaWriter, "<iq from='%s' to='%s' id='s2s1' type='get'>\n"+
2323
"<ping xmlns='urn:xmpp:ping'/>\n"+
2424
"</iq>",
2525
xmlEscape(fromServer), xmlEscape(toServer))
2626
return err
2727
}
2828

2929
func (c *Client) SendResultPing(id, toServer string) error {
30-
_, err := fmt.Fprintf(StanzaWriter, "<iq type='result' to='%s' id='%s'/>",
30+
_, err := fmt.Fprintf(c.stanzaWriter, "<iq type='result' to='%s' id='%s'/>",
3131
xmlEscape(toServer), xmlEscape(id))
3232
return err
3333
}

xmpp_subscription.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ import (
55
)
66

77
func (c *Client) ApproveSubscription(jid string) {
8-
fmt.Fprintf(StanzaWriter, "<presence to='%s' type='subscribed'/>",
8+
fmt.Fprintf(c.stanzaWriter, "<presence to='%s' type='subscribed'/>",
99
xmlEscape(jid))
1010
}
1111

1212
func (c *Client) RevokeSubscription(jid string) {
13-
fmt.Fprintf(StanzaWriter, "<presence to='%s' type='unsubscribed'/>",
13+
fmt.Fprintf(c.stanzaWriter, "<presence to='%s' type='unsubscribed'/>",
1414
xmlEscape(jid))
1515
}
1616

@@ -20,6 +20,6 @@ func (c *Client) RetrieveSubscription(jid string) {
2020
}
2121

2222
func (c *Client) RequestSubscription(jid string) {
23-
fmt.Fprintf(StanzaWriter, "<presence to='%s' type='subscribe'/>",
23+
fmt.Fprintf(c.stanzaWriter, "<presence to='%s' type='subscribe'/>",
2424
xmlEscape(jid))
2525
}

0 commit comments

Comments
 (0)