Reworked the logging again, and also added namespaces to a couple of fields on Features.
authorChris Jones <christian.jones@sri.com>
Sun, 16 Dec 2012 15:15:59 -0700
changeset 102 872e936f9f3f
parent 101 5d721a565503
child 103 f27f78706623
Reworked the logging again, and also added namespaces to a couple of fields on Features.
log.go
stream.go
structs.go
xmpp.go
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/log.go	Sun Dec 16 15:15:59 2012 -0700
@@ -0,0 +1,36 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Control over logging from the XMPP library.
+
+package xmpp
+
+var (
+	// If any of these are non-nil when NewClient() is called,
+	// they will be used to log messages of the indicated
+	// severity.
+	Warn Logger = &noLog{}
+	Info Logger = &noLog{}
+	Debug Logger = &noLog{}
+)
+
+// Anything implementing Logger can receive log messages from the XMPP
+// library. The default implementation doesn't log anything; it
+// efficiently discards all messages.
+type Logger interface {
+	Log(v ...interface{})
+	Logf(fmt string, v ...interface{})
+}
+
+type noLog struct {
+	flags  int
+	prefix string
+}
+var _ Logger = &noLog{}
+
+func (l *noLog) Log(v ...interface{}) {
+}
+
+func (l *noLog) Logf(fmt string, v ...interface{}) {
+}
--- a/stream.go	Sun Dec 16 14:37:43 2012 -0700
+++ b/stream.go	Sun Dec 16 15:15:59 2012 -0700
@@ -50,12 +50,12 @@
 					continue
 				}
 			}
-			Warnf("read: %s", err)
+			Warn.Logf("read: %s", err)
 			break
 		}
 		nw, err := w.Write(p[:nr])
 		if nw < nr {
-			Warnf("read: %s", err)
+			Warn.Logf("read: %s", err)
 			break
 		}
 	}
@@ -67,12 +67,12 @@
 	for {
 		nr, err := r.Read(p)
 		if nr == 0 {
-			Warnf("write: %s", err)
+			Warn.Logf("write: %s", err)
 			break
 		}
 		nw, err := cl.socket.Write(p[:nr])
 		if nw < nr {
-			Warnf("write: %s", err)
+			Warn.Logf("write: %s", err)
 			break
 		}
 	}
@@ -80,7 +80,7 @@
 
 func readXml(r io.Reader, ch chan<- interface{},
 extStanza map[string]func(*xml.Name) interface{}) {
-	if Debug != nil {
+	if _, ok := Debug.(*noLog) ; ok {
 		pr, pw := io.Pipe()
 		go tee(r, pw, "S: ")
 		r = pr
@@ -96,7 +96,7 @@
 		t, err := p.Token()
 		if t == nil {
 			if err != io.EOF {
-				Warnf("read: %s", err)
+				Warn.Logf("read: %s", err)
 			}
 			break
 		}
@@ -112,7 +112,7 @@
 		case NsStream + " stream":
 			st, err := parseStream(se)
 			if err != nil {
-				Warnf("unmarshal stream: %s", err)
+				Warn.Logf("unmarshal stream: %s", err)
 				break Loop
 			}
 			ch <- st
@@ -134,14 +134,14 @@
 			obj = &Presence{}
 		default:
 			obj = &Generic{}
-			Infof("Ignoring unrecognized: %s %s", se.Name.Space,
+			Info.Logf("Ignoring unrecognized: %s %s", se.Name.Space,
 				se.Name.Local)
 		}
 
 		// Read the complete XML stanza.
 		err = p.DecodeElement(obj, &se)
 		if err != nil {
-			Warnf("unmarshal: %s", err)
+			Warn.Logf("unmarshal: %s", err)
 			break Loop
 		}
 
@@ -151,7 +151,7 @@
 		if st, ok := obj.(Stanza); ok {
 			err = parseExtended(st, extStanza)
 			if err != nil {
-				Warnf("ext unmarshal: %s", err)
+				Warn.Logf("ext unmarshal: %s", err)
 				break Loop
 			}
 		}
@@ -194,7 +194,7 @@
 }
 
 func writeXml(w io.Writer, ch <-chan interface{}) {
-	if Debug != nil {
+	if _, ok := Debug.(*noLog) ; ok {
 		pr, pw := io.Pipe()
 		go tee(pr, w, "C: ")
 		w = pw
@@ -213,12 +213,12 @@
 		if st, ok := obj.(*stream); ok {
 			_, err := w.Write([]byte(st.String()))
 			if err != nil {
-				Warnf("write: %s", err)
+				Warn.Logf("write: %s", err)
 			}
 		} else {
 			err := enc.Encode(obj)
 			if err != nil {
-				Warnf("marshal: %s", err)
+				Warn.Logf("marshal: %s", err)
 				break
 			}
 		}
@@ -258,7 +258,7 @@
 			}
 			st, ok := x.(Stanza)
 			if !ok {
-				Warnf("Unhandled non-stanza: %v", x)
+				Warn.Logf("Unhandled non-stanza: %v", x)
 				continue
 			}
 			if handlers[st.GetId()] != nil {
@@ -299,7 +299,7 @@
 				break Loop
 			}
 			if x == nil {
-				Infof("Refusing to send nil stanza")
+				Info.Logf("Refusing to send nil stanza")
 				continue
 			}
 			srvOut <- x
@@ -317,7 +317,7 @@
 		select {
 		case newFilterOut := <-filterOut:
 			if newFilterOut == nil {
-				Warnf("Received nil filter")
+				Warn.Logf("Received nil filter")
 				filterIn <- nil
 				continue
 			}
@@ -344,7 +344,7 @@
 }
 
 func (cl *Client) handleStreamError(se *streamError) {
-	Infof("Received stream error: %v", se)
+	Info.Logf("Received stream error: %v", se)
 	close(cl.Out)
 }
 
@@ -389,7 +389,7 @@
 	cl.socket = tls
 	cl.socketSync.Wait()
 
-	Infof("TLS negotiation succeeded.")
+	Info.Logf("TLS negotiation succeeded.")
 	cl.Features = nil
 
 	// Now re-send the initial handshake message to start the new
@@ -435,7 +435,7 @@
 		b64 := base64.StdEncoding
 		str, err := b64.DecodeString(srv.Chardata)
 		if err != nil {
-			Warnf("SASL challenge decode: %s", err)
+			Warn.Logf("SASL challenge decode: %s", err)
 			return
 		}
 		srvMap := parseSasl(string(str))
@@ -446,9 +446,9 @@
 			cl.saslDigest2(srvMap)
 		}
 	case "failure":
-		Infof("SASL authentication failed")
+		Info.Logf("SASL authentication failed")
 	case "success":
-		Infof("Sasl authentication succeeded")
+		Info.Logf("Sasl authentication succeeded")
 		cl.Features = nil
 		ss := &stream{To: cl.Jid.Domain, Version: Version}
 		cl.xmlOut <- ss
@@ -464,7 +464,7 @@
 		}
 	}
 	if !hasAuth {
-		Warnf("Server doesn't support SASL auth")
+		Warn.Logf("Server doesn't support SASL auth")
 		return
 	}
 
@@ -494,7 +494,7 @@
 	randSize.Lsh(big.NewInt(1), 64)
 	cnonce, err := rand.Int(rand.Reader, randSize)
 	if err != nil {
-		Warnf("SASL rand: %s", err)
+		Warn.Logf("SASL rand: %s", err)
 		return
 	}
 	cnonceStr := fmt.Sprintf("%016x", cnonce)
@@ -600,10 +600,10 @@
 	f := func(st Stanza) bool {
 		iq, ok := st.(*Iq)
 		if !ok {
-			Warnf("non-iq response")
+			Warn.Logf("non-iq response")
 		}
 		if iq.Type == "error" {
-			Warnf("Resource binding failed")
+			Warn.Logf("Resource binding failed")
 			return false
 		}
 		var bindRepl *bindIq
@@ -614,21 +614,21 @@
 			}
 		}
 		if bindRepl == nil {
-			Warnf("Bad bind reply: %v", iq)
+			Warn.Logf("Bad bind reply: %v", iq)
 			return false
 		}
 		jidStr := bindRepl.Jid
 		if jidStr == nil || *jidStr == "" {
-			Warnf("Can't bind empty resource")
+			Warn.Logf("Can't bind empty resource")
 			return false
 		}
 		jid := new(JID)
 		if err := jid.Set(*jidStr); err != nil {
-			Warnf("Can't parse JID %s: %s", *jidStr, err)
+			Warn.Logf("Can't parse JID %s: %s", *jidStr, err)
 			return false
 		}
 		cl.Jid = *jid
-		Infof("Bound resource: %s", cl.Jid.String())
+		Info.Logf("Bound resource: %s", cl.Jid.String())
 		cl.bindDone()
 		return false
 	}
--- a/structs.go	Sun Dec 16 14:37:43 2012 -0700
+++ b/structs.go	Sun Dec 16 15:15:59 2012 -0700
@@ -55,8 +55,8 @@
 }
 
 type Features struct {
-	Starttls   *starttls
-	Mechanisms mechs
+	Starttls   *starttls `xml:"urn:ietf:params:xml:ns:xmpp-tls starttls"`
+	Mechanisms mechs     `xml:"urn:ietf:params:xml:ns:xmpp-sasl mechanisms"`
 	Bind       *bindIq
 	Session    *Generic
 	Any        *Generic
@@ -274,7 +274,7 @@
 func (er *Error) Error() string {
 	buf, err := xml.Marshal(er)
 	if err != nil {
-		Warnf("double bad error: couldn't marshal error")
+		Warn.Logf("double bad error: couldn't marshal error")
 		return "unreadable error"
 	}
 	return string(buf)
--- a/xmpp.go	Sun Dec 16 14:37:43 2012 -0700
+++ b/xmpp.go	Sun Dec 16 15:15:59 2012 -0700
@@ -12,7 +12,6 @@
 	"errors"
 	"fmt"
 	"io"
-	"log"
 	"net"
 	"sync"
 )
@@ -36,15 +35,6 @@
 	clientSrv = "xmpp-client"
 )
 
-var (
-	// If any of these are non-nil when NewClient() is called,
-	// they will be used to log messages of the indicated
-	// severity.
-	Warn *log.Logger
-	Info *log.Logger
-	Debug *log.Logger
-)
-
 // This channel may be used as a convenient way to generate a unique
 // id for an iq, message, or presence stanza.
 var Id <-chan string
@@ -250,13 +240,13 @@
 		}
 		buf.Write(c[:n])
 		if c[0] == '\n' || c[0] == '>' {
-			Debug.Print(buf)
+			Debug.Log(buf)
 			buf.Reset()
 		}
 	}
 	leftover := buf.String()
 	if leftover != "" {
-		Debug.Print(buf)
+		Debug.Log(buf)
 	}
 }
 
@@ -279,12 +269,12 @@
 	f := func(st Stanza) bool {
 		iq, ok := st.(*Iq)
 		if !ok {
-			Warnf("iq reply not iq; can't start session")
+			Warn.Logf("iq reply not iq; can't start session")
 			ch <- errors.New("bad session start reply")
 			return false
 		}
 		if iq.Type == "error" {
-			Warnf("Can't start session: %v", iq)
+			Warn.Logf("Can't start session: %v", iq)
 			ch <- iq.Error
 			return false
 		}
@@ -319,21 +309,3 @@
 	cl.filterOut <- out
 	return <-cl.filterIn
 }
-
-func Warnf(msg string, args ...interface{}) {
-	if Warn != nil {
-		Warn.Printf(msg, args)
-	}
-}
-
-func Infof(msg string, args ...interface{}) {
-	if Info != nil {
-		Info.Printf(msg, args)
-	}
-}
-
-func Debugf(msg string, args ...interface{}) {
-	if Debug != nil {
-		Debug.Printf(msg, args)
-	}
-}