diff -r d19b556d4ea6 -r fbd51fa6b7ea stream.go --- a/stream.go Mon Jan 23 21:58:53 2012 -0700 +++ b/stream.go Sun Apr 15 11:20:55 2012 -0600 @@ -19,7 +19,6 @@ "encoding/xml" "fmt" "io" - "log/syslog" "math/big" "net" "regexp" @@ -52,11 +51,17 @@ func (cl *Client) readTransport(w io.WriteCloser) { defer w.Close() - cl.socket.SetReadTimeout(1e8) + readDelay, _ := time.ParseDuration("1s") p := make([]byte, 1024) for { if cl.socket == nil { cl.waitForSocket() + readDelay = 0 + } + if readDelay != 0 { + readTimeout := time.Now() + readTimeout.Add(readDelay) + cl.socket.SetReadDeadline(readTimeout) } nr, err := cl.socket.Read(p) if nr == 0 { @@ -103,14 +108,14 @@ func readXml(r io.Reader, ch chan<- interface{}, extStanza map[string]func(*xml.Name) interface{}) { - if Loglevel >= syslog.LOG_DEBUG { + if Loglevel >= LOG_DEBUG { pr, pw := io.Pipe() go tee(r, pw, "S: ") r = pr } defer close(ch) - p := xml.NewParser(r) + p := xml.NewDecoder(r) Loop: for { // Sniff the next token on the stream. @@ -162,14 +167,14 @@ obj = &Presence{} default: obj = &Generic{} - if Log != nil && Loglevel >= syslog.LOG_NOTICE { + if Log != nil && Loglevel >= LOG_NOTICE { Log.Printf("Ignoring unrecognized: %s %s", se.Name.Space, se.Name.Local) } } // Read the complete XML stanza. - err = p.Unmarshal(obj, &se) + err = p.DecodeElement(obj, &se) if err != nil { if Log != nil { Log.Println("unmarshal: " + err.Error()) @@ -200,7 +205,7 @@ // Now parse the stanza's innerxml to find the string that we // can unmarshal this nested element from. reader := strings.NewReader(st.innerxml()) - p := xml.NewParser(reader) + p := xml.NewDecoder(reader) for { t, err := p.Token() if err == io.EOF { @@ -216,7 +221,7 @@ // Unmarshal the nested element and // stuff it back into the stanza. - err := p.Unmarshal(nested, &se) + err := p.DecodeElement(nested, &se) if err != nil { return err } @@ -229,7 +234,7 @@ } func writeXml(w io.Writer, ch <-chan interface{}) { - if Loglevel >= syslog.LOG_DEBUG { + if Loglevel >= LOG_DEBUG { pr, pw := io.Pipe() go tee(pr, w, "C: ") w = pw @@ -241,7 +246,7 @@ }(w) for obj := range ch { - err := xml.Marshal(w, obj) + err := xml.NewEncoder(w).Encode(obj) if err != nil { if Log != nil { Log.Println("write: " + err.Error()) @@ -284,7 +289,7 @@ } st, ok := x.(Stanza) if !ok { - if Log != nil && Loglevel >= syslog.LOG_WARNING { + if Log != nil && Loglevel >= LOG_WARNING { Log.Printf( "Unhandled non-stanza: %v", x) } @@ -328,7 +333,7 @@ break Loop } if x == nil { - if Log != nil && Loglevel >= syslog.LOG_NOTICE { + if Log != nil && Loglevel >= LOG_NOTICE { Log.Println("Refusing to send" + " nil stanza") } @@ -349,7 +354,7 @@ select { case newFilterOut := <-filterOut: if newFilterOut == nil { - if Log != nil && Loglevel >= syslog.LOG_WARNING { + if Log != nil && Loglevel >= LOG_WARNING { Log.Println("Received nil filter") } filterIn <- nil @@ -378,7 +383,7 @@ } func (cl *Client) handleStreamError(se *streamError) { - if Log != nil && Loglevel >= syslog.LOG_NOTICE { + if Log != nil && Loglevel >= LOG_NOTICE { Log.Printf("Received stream error: %v", se) } close(cl.Out) @@ -428,11 +433,7 @@ cl.socket = tls cl.socketSync.Wait() - // Reset the read timeout on the (underlying) socket so the - // reader doesn't get woken up unnecessarily. - tcp.SetReadTimeout(0) - - if Log != nil && Loglevel >= syslog.LOG_INFO { + if Log != nil && Loglevel >= LOG_INFO { Log.Println("TLS negotiation succeeded.") } cl.Features = nil @@ -470,8 +471,7 @@ } if external { - auth := &auth{XMLName: xml.Name{Space: NsSASL, Local: - "auth"}, Mechanism: "EXTERNAL"} + auth := &auth{XMLName: xml.Name{Space: NsSASL, Local: "auth"}, Mechanism: "EXTERNAL"} cl.xmlOut <- auth } else if digestMd5 { auth := &auth{XMLName: xml.Name{Space: NsSASL, Local: "auth"}, Mechanism: "DIGEST-MD5"} @@ -479,17 +479,15 @@ } else { if Log != nil { buf := bytes.NewBuffer(nil) - xml.Marshal(buf, fe) + xml.NewEncoder(buf).Encode(fe) Log.Printf("No supported mechanisms: %s", buf.String()) } abort := Generic{XMLName: xml.Name{Local: "abort", Space: NsSASL}} cl.xmlOut <- abort - se := streamError{Any: Generic{XMLName: - xml.Name{Local: "undefined-condition", - Space: NsStreams}}, Text: - &errText{Lang: "en", Text: "No supported mechs"}} + se := streamError{Any: Generic{XMLName: xml.Name{Local: "undefined-condition", + Space: NsStreams}}, Text: &errText{Lang: "en", Text: "No supported mechs"}} cl.xmlOut <- se close(cl.xmlOut) } @@ -515,11 +513,11 @@ cl.saslDigest2(srvMap) } case "failure": - if Log != nil && Loglevel >= syslog.LOG_NOTICE { + if Log != nil && Loglevel >= LOG_NOTICE { Log.Println("SASL authentication failed") } case "success": - if Log != nil && Loglevel >= syslog.LOG_INFO { + if Log != nil && Loglevel >= LOG_INFO { Log.Println("Sasl authentication succeeded") } cl.Features = nil @@ -708,7 +706,7 @@ return false } cl.Jid = *jid - if Log != nil && Loglevel >= syslog.LOG_INFO { + if Log != nil && Loglevel >= LOG_INFO { Log.Println("Bound resource: " + cl.Jid.String()) } cl.bindDone()