diff --git a/xmpp.go b/xmpp.go index 9af89a2..b8b60c7 100644 --- a/xmpp.go +++ b/xmpp.go @@ -55,7 +55,6 @@ var DefaultConfig = &tls.Config{} // DebugWriter is the writer used to write debugging output to. var DebugWriter io.Writer = os.Stderr -var StanzaWriter io.Writer // Cookie is a unique XMPP session identifier type Cookie uint64 @@ -70,10 +69,11 @@ func getCookie() Cookie { // Client holds XMPP connection options type Client struct { - conn net.Conn // connection to server - jid string // Jabber ID for our connection - domain string - p *xml.Decoder + conn net.Conn // connection to server + jid string // Jabber ID for our connection + domain string + p *xml.Decoder + stanzaWriter io.Writer } func (c *Client) JID() string { @@ -378,7 +378,7 @@ func (c *Client) init(o *Options) error { foundAnonymous := false for _, m := range f.Mechanisms.Mechanism { if m == "ANONYMOUS" { - fmt.Fprintf(StanzaWriter, "\n", nsSASL) + fmt.Fprintf(c.stanzaWriter, "\n", nsSASL) foundAnonymous = true break } @@ -436,7 +436,7 @@ func (c *Client) init(o *Options) error { } clientNonce := cnonce() clientFirstMessage := "n=" + user + ",r=" + clientNonce - fmt.Fprintf(StanzaWriter, "%s", + fmt.Fprintf(c.stanzaWriter, "%s", nsSASL, mechanism, base64.StdEncoding.EncodeToString([]byte("n,,"+ clientFirstMessage))) var sfm string @@ -536,7 +536,7 @@ func (c *Client) init(o *Options) error { } clientFinalMessage := base64.StdEncoding.EncodeToString([]byte(clientFinalMessageBare + ",p=" + base64.StdEncoding.EncodeToString(clientProof))) - fmt.Fprintf(StanzaWriter, "%s", nsSASL, + fmt.Fprintf(c.stanzaWriter, "%s", nsSASL, clientFinalMessage) } if mechanism == "X-OAUTH2" && o.OAuthToken != "" && o.OAuthScope != "" { @@ -544,7 +544,7 @@ func (c *Client) init(o *Options) error { raw := "\x00" + user + "\x00" + o.OAuthToken enc := make([]byte, base64.StdEncoding.EncodedLen(len(raw))) base64.StdEncoding.Encode(enc, []byte(raw)) - fmt.Fprintf(StanzaWriter, "%s\n", nsSASL, o.OAuthXmlNs, enc) } if mechanism == "PLAIN" { @@ -556,7 +556,7 @@ func (c *Client) init(o *Options) error { } if mechanism == "DIGEST-MD5" { // Digest-MD5 authentication - fmt.Fprintf(StanzaWriter, "\n", nsSASL) + fmt.Fprintf(c.stanzaWriter, "\n", nsSASL) var ch saslChallenge if err = c.p.DecodeElement(&ch, nil); err != nil { return errors.New("unmarshal : " + err.Error()) @@ -586,7 +586,7 @@ func (c *Client) init(o *Options) error { message := "username=\"" + user + "\", realm=\"" + realm + "\", nonce=\"" + nonce + "\", cnonce=\"" + cnonceStr + "\", nc=" + nonceCount + ", qop=" + qop + ", digest-uri=\"" + digestURI + "\", response=" + digest + ", charset=" + charset - fmt.Fprintf(StanzaWriter, "%s\n", nsSASL, base64.StdEncoding.EncodeToString([]byte(message))) + fmt.Fprintf(c.stanzaWriter, "%s\n", nsSASL, base64.StdEncoding.EncodeToString([]byte(message))) var rspauth saslRspAuth if err = c.p.DecodeElement(&rspauth, nil); err != nil { @@ -596,7 +596,7 @@ func (c *Client) init(o *Options) error { if err != nil { return err } - fmt.Fprintf(StanzaWriter, "\n", nsSASL) + fmt.Fprintf(c.stanzaWriter, "\n", nsSASL) } } if mechanism == "" { @@ -649,9 +649,9 @@ func (c *Client) init(o *Options) error { // Send IQ message asking to bind to the local user name. if o.Resource == "" { - fmt.Fprintf(StanzaWriter, "\n", cookie, nsBind) + fmt.Fprintf(c.stanzaWriter, "\n", cookie, nsBind) } else { - fmt.Fprintf(StanzaWriter, "%s\n", cookie, nsBind, o.Resource) + fmt.Fprintf(c.stanzaWriter, "%s\n", cookie, nsBind, o.Resource) } var iq clientIQ if err = c.p.DecodeElement(&iq, nil); err != nil { @@ -665,11 +665,11 @@ func (c *Client) init(o *Options) error { if o.Session { //if server support session, open it - fmt.Fprintf(StanzaWriter, "", xmlEscape(domain), cookie, nsSession) + fmt.Fprintf(c.stanzaWriter, "", xmlEscape(domain), cookie, nsSession) } // We're connected and can now receive and send messages. - fmt.Fprintf(StanzaWriter, "%s%s", o.Status, o.StatusMessage) + fmt.Fprintf(c.stanzaWriter, "%s%s", o.Status, o.StatusMessage) return nil } @@ -691,7 +691,7 @@ func (c *Client) startTLSIfRequired(f *streamFeatures, o *Options, domain string } var err error - fmt.Fprintf(StanzaWriter, "\n") + fmt.Fprintf(c.stanzaWriter, "\n") var k tlsProceed if err = c.p.DecodeElement(&k, nil); err != nil { return f, errors.New("unmarshal : " + err.Error()) @@ -724,13 +724,13 @@ func (c *Client) startTLSIfRequired(f *streamFeatures, o *Options, domain string func (c *Client) startStream(o *Options, domain string) (*streamFeatures, error) { if o.Debug { c.p = xml.NewDecoder(tee{c.conn, DebugWriter}) - StanzaWriter = io.MultiWriter(c.conn, DebugWriter) + c.stanzaWriter = io.MultiWriter(c.conn, DebugWriter) } else { c.p = xml.NewDecoder(c.conn) - StanzaWriter = c.conn + c.stanzaWriter = c.conn } - _, err := fmt.Fprintf(StanzaWriter, ""+ + _, err := fmt.Fprintf(c.stanzaWriter, ""+ "", xmlEscape(domain), nsClient, nsStream) @@ -1058,7 +1058,7 @@ func (c *Client) Send(chat Chat) (n int, err error) { stanza := "" + subtext + "%s" + oobtext + thdtext + "" - return fmt.Fprintf(StanzaWriter, stanza, + return fmt.Fprintf(c.stanzaWriter, stanza, xmlEscape(chat.Remote), xmlEscape(chat.Type), cnonce(), xmlEscape(chat.Text)) } @@ -1075,17 +1075,17 @@ func (c *Client) SendOOB(chat Chat) (n int, err error) { } oobtext += `` } - return fmt.Fprintf(StanzaWriter, ""+oobtext+thdtext+"", + return fmt.Fprintf(c.stanzaWriter, ""+oobtext+thdtext+"", xmlEscape(chat.Remote), xmlEscape(chat.Type), cnonce()) } // SendOrg sends the original text without being wrapped in an XMPP message stanza. func (c *Client) SendOrg(org string) (n int, err error) { - return fmt.Fprint(StanzaWriter, org) + return fmt.Fprint(c.stanzaWriter, org) } func (c *Client) SendPresence(presence Presence) (n int, err error) { - return fmt.Fprintf(StanzaWriter, "", xmlEscape(presence.From), xmlEscape(presence.To)) + return fmt.Fprintf(c.stanzaWriter, "", xmlEscape(presence.From), xmlEscape(presence.To)) } // SendKeepAlive sends a "whitespace keepalive" as described in chapter 4.6.1 of RFC6120. @@ -1095,7 +1095,7 @@ func (c *Client) SendKeepAlive() (n int, err error) { // SendHtml sends the message as HTML as defined by XEP-0071 func (c *Client) SendHtml(chat Chat) (n int, err error) { - return fmt.Fprintf(StanzaWriter, ""+ + return fmt.Fprintf(c.stanzaWriter, ""+ "%s"+ "%s", xmlEscape(chat.Remote), xmlEscape(chat.Type), xmlEscape(chat.Text), chat.Text) @@ -1103,7 +1103,7 @@ func (c *Client) SendHtml(chat Chat) (n int, err error) { // Roster asks for the chat roster. func (c *Client) Roster() error { - fmt.Fprintf(StanzaWriter, "\n", xmlEscape(c.jid)) + fmt.Fprintf(c.stanzaWriter, "\n", xmlEscape(c.jid)) return nil } diff --git a/xmpp_information_query.go b/xmpp_information_query.go index 01ff089..bda5d86 100644 --- a/xmpp_information_query.go +++ b/xmpp_information_query.go @@ -35,13 +35,13 @@ func (c *Client) DiscoverEntityItems(jid string) (string, error) { // RawInformationQuery sends an information query request to the server. func (c *Client) RawInformationQuery(from, to, id, iqType, requestNamespace, body string) (string, error) { const xmlIQ = "%s" - _, err := fmt.Fprintf(StanzaWriter, xmlIQ, xmlEscape(from), xmlEscape(to), id, iqType, requestNamespace, body) + _, err := fmt.Fprintf(c.stanzaWriter, xmlIQ, xmlEscape(from), xmlEscape(to), id, iqType, requestNamespace, body) return id, err } // rawInformation send a IQ request with the payload body to the server func (c *Client) RawInformation(from, to, id, iqType, body string) (string, error) { const xmlIQ = "%s" - _, err := fmt.Fprintf(StanzaWriter, xmlIQ, xmlEscape(from), xmlEscape(to), id, iqType, body) + _, err := fmt.Fprintf(c.stanzaWriter, xmlIQ, xmlEscape(from), xmlEscape(to), id, iqType, body) return id, err } diff --git a/xmpp_muc.go b/xmpp_muc.go index 64798c2..aec89bc 100644 --- a/xmpp_muc.go +++ b/xmpp_muc.go @@ -25,7 +25,7 @@ const ( // Send sends room topic wrapped inside an XMPP message stanza body. func (c *Client) SendTopic(chat Chat) (n int, err error) { - return fmt.Fprintf(StanzaWriter, ""+"%s", + return fmt.Fprintf(c.stanzaWriter, ""+"%s", xmlEscape(chat.Remote), xmlEscape(chat.Type), xmlEscape(chat.Text)) } @@ -33,7 +33,7 @@ func (c *Client) JoinMUCNoHistory(jid, nick string) (n int, err error) { if nick == "" { nick = c.jid } - return fmt.Fprintf(StanzaWriter, "\n"+ + return fmt.Fprintf(c.stanzaWriter, "\n"+ ""+ "\n"+ "", @@ -47,31 +47,31 @@ func (c *Client) JoinMUC(jid, nick string, history_type, history int, history_da } switch history_type { case NoHistory: - return fmt.Fprintf(StanzaWriter, "\n"+ + return fmt.Fprintf(c.stanzaWriter, "\n"+ "\n"+ "", xmlEscape(jid), xmlEscape(nick), nsMUC) case CharHistory: - return fmt.Fprintf(StanzaWriter, "\n"+ + return fmt.Fprintf(c.stanzaWriter, "\n"+ "\n"+ "\n"+ "", xmlEscape(jid), xmlEscape(nick), nsMUC, history) case StanzaHistory: - return fmt.Fprintf(StanzaWriter, "\n"+ + return fmt.Fprintf(c.stanzaWriter, "\n"+ "\n"+ "\n"+ "", xmlEscape(jid), xmlEscape(nick), nsMUC, history) case SecondsHistory: - return fmt.Fprintf(StanzaWriter, "\n"+ + return fmt.Fprintf(c.stanzaWriter, "\n"+ "\n"+ "\n"+ "", xmlEscape(jid), xmlEscape(nick), nsMUC, history) case SinceHistory: if history_date != nil { - return fmt.Fprintf(StanzaWriter, "\n"+ + return fmt.Fprintf(c.stanzaWriter, "\n"+ "\n"+ "\n"+ "", @@ -88,28 +88,28 @@ func (c *Client) JoinProtectedMUC(jid, nick string, password string, history_typ } switch history_type { case NoHistory: - return fmt.Fprintf(StanzaWriter, "\n"+ + return fmt.Fprintf(c.stanzaWriter, "\n"+ "\n"+ "%s"+ "\n"+ "", xmlEscape(jid), xmlEscape(nick), nsMUC, xmlEscape(password)) case CharHistory: - return fmt.Fprintf(StanzaWriter, "\n"+ + return fmt.Fprintf(c.stanzaWriter, "\n"+ "\n"+ "%s\n"+ "\n"+ "", xmlEscape(jid), xmlEscape(nick), nsMUC, xmlEscape(password), history) case StanzaHistory: - return fmt.Fprintf(StanzaWriter, "\n"+ + return fmt.Fprintf(c.stanzaWriter, "\n"+ "\n"+ "%s\n"+ "\n"+ "", xmlEscape(jid), xmlEscape(nick), nsMUC, xmlEscape(password), history) case SecondsHistory: - return fmt.Fprintf(StanzaWriter, "\n"+ + return fmt.Fprintf(c.stanzaWriter, "\n"+ "\n"+ "%s\n"+ "\n"+ @@ -117,7 +117,7 @@ func (c *Client) JoinProtectedMUC(jid, nick string, password string, history_typ xmlEscape(jid), xmlEscape(nick), nsMUC, xmlEscape(password), history) case SinceHistory: if history_date != nil { - return fmt.Fprintf(StanzaWriter, "\n"+ + return fmt.Fprintf(c.stanzaWriter, "\n"+ "\n"+ "%s\n"+ "\n"+ @@ -130,6 +130,6 @@ func (c *Client) JoinProtectedMUC(jid, nick string, password string, history_typ // xep-0045 7.14 func (c *Client) LeaveMUC(jid string) (n int, err error) { - return fmt.Fprintf(StanzaWriter, "", + return fmt.Fprintf(c.stanzaWriter, "", c.jid, xmlEscape(jid)) } diff --git a/xmpp_ping.go b/xmpp_ping.go index eb20704..b22e52d 100644 --- a/xmpp_ping.go +++ b/xmpp_ping.go @@ -11,7 +11,7 @@ func (c *Client) PingC2S(jid, server string) error { if server == "" { server = c.domain } - _, err := fmt.Fprintf(StanzaWriter, "\n"+ + _, err := fmt.Fprintf(c.stanzaWriter, "\n"+ "\n"+ "", xmlEscape(jid), xmlEscape(server)) @@ -19,7 +19,7 @@ func (c *Client) PingC2S(jid, server string) error { } func (c *Client) PingS2S(fromServer, toServer string) error { - _, err := fmt.Fprintf(StanzaWriter, "\n"+ + _, err := fmt.Fprintf(c.stanzaWriter, "\n"+ "\n"+ "", xmlEscape(fromServer), xmlEscape(toServer)) @@ -27,7 +27,7 @@ func (c *Client) PingS2S(fromServer, toServer string) error { } func (c *Client) SendResultPing(id, toServer string) error { - _, err := fmt.Fprintf(StanzaWriter, "", + _, err := fmt.Fprintf(c.stanzaWriter, "", xmlEscape(toServer), xmlEscape(id)) return err } diff --git a/xmpp_subscription.go b/xmpp_subscription.go index ed8289f..2f90339 100644 --- a/xmpp_subscription.go +++ b/xmpp_subscription.go @@ -5,12 +5,12 @@ import ( ) func (c *Client) ApproveSubscription(jid string) { - fmt.Fprintf(StanzaWriter, "", + fmt.Fprintf(c.stanzaWriter, "", xmlEscape(jid)) } func (c *Client) RevokeSubscription(jid string) { - fmt.Fprintf(StanzaWriter, "", + fmt.Fprintf(c.stanzaWriter, "", xmlEscape(jid)) } @@ -20,6 +20,6 @@ func (c *Client) RetrieveSubscription(jid string) { } func (c *Client) RequestSubscription(jid string) { - fmt.Fprintf(StanzaWriter, "", + fmt.Fprintf(c.stanzaWriter, "", xmlEscape(jid)) }