@@ -55,7 +55,6 @@ var DefaultConfig = &tls.Config{}
55
55
56
56
// DebugWriter is the writer used to write debugging output to.
57
57
var DebugWriter io.Writer = os .Stderr
58
- var StanzaWriter io.Writer
59
58
60
59
// Cookie is a unique XMPP session identifier
61
60
type Cookie uint64
@@ -70,10 +69,11 @@ func getCookie() Cookie {
70
69
71
70
// Client holds XMPP connection options
72
71
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
77
77
}
78
78
79
79
func (c * Client ) JID () string {
@@ -378,7 +378,7 @@ func (c *Client) init(o *Options) error {
378
378
foundAnonymous := false
379
379
for _ , m := range f .Mechanisms .Mechanism {
380
380
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 )
382
382
foundAnonymous = true
383
383
break
384
384
}
@@ -436,7 +436,7 @@ func (c *Client) init(o *Options) error {
436
436
}
437
437
clientNonce := cnonce ()
438
438
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>" ,
440
440
nsSASL , mechanism , base64 .StdEncoding .EncodeToString ([]byte ("n,," +
441
441
clientFirstMessage )))
442
442
var sfm string
@@ -536,15 +536,15 @@ func (c *Client) init(o *Options) error {
536
536
}
537
537
clientFinalMessage := base64 .StdEncoding .EncodeToString ([]byte (clientFinalMessageBare +
538
538
",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 ,
540
540
clientFinalMessage )
541
541
}
542
542
if mechanism == "X-OAUTH2" && o .OAuthToken != "" && o .OAuthScope != "" {
543
543
// Oauth authentication: send base64-encoded \x00 user \x00 token.
544
544
raw := "\x00 " + user + "\x00 " + o .OAuthToken
545
545
enc := make ([]byte , base64 .StdEncoding .EncodedLen (len (raw )))
546
546
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' " +
548
548
"xmlns:auth='%s'>%s</auth>\n " , nsSASL , o .OAuthXmlNs , enc )
549
549
}
550
550
if mechanism == "PLAIN" {
@@ -556,7 +556,7 @@ func (c *Client) init(o *Options) error {
556
556
}
557
557
if mechanism == "DIGEST-MD5" {
558
558
// 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 )
560
560
var ch saslChallenge
561
561
if err = c .p .DecodeElement (& ch , nil ); err != nil {
562
562
return errors .New ("unmarshal <challenge>: " + err .Error ())
@@ -586,7 +586,7 @@ func (c *Client) init(o *Options) error {
586
586
message := "username=\" " + user + "\" , realm=\" " + realm + "\" , nonce=\" " + nonce + "\" , cnonce=\" " + cnonceStr +
587
587
"\" , nc=" + nonceCount + ", qop=" + qop + ", digest-uri=\" " + digestURI + "\" , response=" + digest + ", charset=" + charset
588
588
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 )))
590
590
591
591
var rspauth saslRspAuth
592
592
if err = c .p .DecodeElement (& rspauth , nil ); err != nil {
@@ -596,7 +596,7 @@ func (c *Client) init(o *Options) error {
596
596
if err != nil {
597
597
return err
598
598
}
599
- fmt .Fprintf (StanzaWriter , "<response xmlns='%s'/>\n " , nsSASL )
599
+ fmt .Fprintf (c . stanzaWriter , "<response xmlns='%s'/>\n " , nsSASL )
600
600
}
601
601
}
602
602
if mechanism == "" {
@@ -649,9 +649,9 @@ func (c *Client) init(o *Options) error {
649
649
650
650
// Send IQ message asking to bind to the local user name.
651
651
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 )
653
653
} 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 )
655
655
}
656
656
var iq clientIQ
657
657
if err = c .p .DecodeElement (& iq , nil ); err != nil {
@@ -665,11 +665,11 @@ func (c *Client) init(o *Options) error {
665
665
666
666
if o .Session {
667
667
//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 )
669
669
}
670
670
671
671
// 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 )
673
673
674
674
return nil
675
675
}
@@ -691,7 +691,7 @@ func (c *Client) startTLSIfRequired(f *streamFeatures, o *Options, domain string
691
691
}
692
692
var err error
693
693
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 " )
695
695
var k tlsProceed
696
696
if err = c .p .DecodeElement (& k , nil ); err != nil {
697
697
return f , errors .New ("unmarshal <proceed>: " + err .Error ())
@@ -724,13 +724,13 @@ func (c *Client) startTLSIfRequired(f *streamFeatures, o *Options, domain string
724
724
func (c * Client ) startStream (o * Options , domain string ) (* streamFeatures , error ) {
725
725
if o .Debug {
726
726
c .p = xml .NewDecoder (tee {c .conn , DebugWriter })
727
- StanzaWriter = io .MultiWriter (c .conn , DebugWriter )
727
+ c . stanzaWriter = io .MultiWriter (c .conn , DebugWriter )
728
728
} else {
729
729
c .p = xml .NewDecoder (c .conn )
730
- StanzaWriter = c .conn
730
+ c . stanzaWriter = c .conn
731
731
}
732
732
733
- _ , err := fmt .Fprintf (StanzaWriter , "<?xml version='1.0'?>" +
733
+ _ , err := fmt .Fprintf (c . stanzaWriter , "<?xml version='1.0'?>" +
734
734
"<stream:stream to='%s' xmlns='%s'" +
735
735
" xmlns:stream='%s' version='1.0'>" ,
736
736
xmlEscape (domain ), nsClient , nsStream )
@@ -1058,7 +1058,7 @@ func (c *Client) Send(chat Chat) (n int, err error) {
1058
1058
1059
1059
stanza := "<message to='%s' type='%s' id='%s' xml:lang='en'>" + subtext + "<body>%s</body>" + oobtext + thdtext + "</message>"
1060
1060
1061
- return fmt .Fprintf (StanzaWriter , stanza ,
1061
+ return fmt .Fprintf (c . stanzaWriter , stanza ,
1062
1062
xmlEscape (chat .Remote ), xmlEscape (chat .Type ), cnonce (), xmlEscape (chat .Text ))
1063
1063
}
1064
1064
@@ -1075,17 +1075,17 @@ func (c *Client) SendOOB(chat Chat) (n int, err error) {
1075
1075
}
1076
1076
oobtext += `</x>`
1077
1077
}
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>" ,
1079
1079
xmlEscape (chat .Remote ), xmlEscape (chat .Type ), cnonce ())
1080
1080
}
1081
1081
1082
1082
// SendOrg sends the original text without being wrapped in an XMPP message stanza.
1083
1083
func (c * Client ) SendOrg (org string ) (n int , err error ) {
1084
- return fmt .Fprint (StanzaWriter , org )
1084
+ return fmt .Fprint (c . stanzaWriter , org )
1085
1085
}
1086
1086
1087
1087
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 ))
1089
1089
}
1090
1090
1091
1091
// 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) {
1095
1095
1096
1096
// SendHtml sends the message as HTML as defined by XEP-0071
1097
1097
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'>" +
1099
1099
"<body>%s</body>" +
1100
1100
"<html xmlns='http://jabber.org/protocol/xhtml-im'><body xmlns='http://www.w3.org/1999/xhtml'>%s</body></html></message>" ,
1101
1101
xmlEscape (chat .Remote ), xmlEscape (chat .Type ), xmlEscape (chat .Text ), chat .Text )
1102
1102
}
1103
1103
1104
1104
// Roster asks for the chat roster.
1105
1105
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 ))
1107
1107
return nil
1108
1108
}
1109
1109
0 commit comments