diff -r 626c390682fc -r b4bd77d58a3e xmpp/layer3.go --- a/xmpp/layer3.go Sun Feb 09 09:50:38 2014 -0700 +++ b/xmpp/layer3.go Sun Feb 09 09:52:28 2014 -0700 @@ -5,6 +5,8 @@ import ( "encoding/xml" + "fmt" + "log" ) // Callback to handle a stanza with a particular id. @@ -26,7 +28,10 @@ var input <-chan Stanza for { select { - case stat := <-status: + case stat, ok := <-status: + if !ok { + return + } switch stat { default: input = nil @@ -38,7 +43,9 @@ return } if x == nil { - Info.Log("Refusing to send nil stanza") + if Debug { + log.Println("Won't send nil stanza") + } continue } sendXml <- x @@ -74,7 +81,8 @@ case *stream: // Do nothing. case *streamError: - cl.handleStreamError(obj) + cl.setError(fmt.Errorf("%#v", obj)) + return case *Features: cl.handleFeatures(obj) case *starttls: @@ -92,23 +100,21 @@ sendXmpp <- obj } default: - Warn.Logf("Unhandled non-stanza: %T %#v", x, x) + if Debug { + log.Printf("Unrecognized input: %T %#v", + x, x) + } } } } } -func (cl *Client) handleStreamError(se *streamError) { - Info.Logf("Received stream error: %v", se) - cl.setStatus(StatusShutdown) -} - func (cl *Client) handleFeatures(fe *Features) { cl.Features = fe if fe.Starttls != nil { start := &starttls{XMLName: xml.Name{Space: NsTLS, Local: "starttls"}} - cl.sendXml <- start + cl.sendRaw <- start return } @@ -130,12 +136,12 @@ // Now re-send the initial handshake message to start the new // session. - cl.sendXml <- &stream{To: cl.Jid.Domain, Version: XMPPVersion} + cl.sendRaw <- &stream{To: cl.Jid.Domain(), Version: XMPPVersion} } // Send a request to bind a resource. RFC 3920, section 7. func (cl *Client) bind() { - res := cl.Jid.Resource + res := cl.Jid.Resource() bindReq := &bindIq{} if res != "" { bindReq.Resource = &res @@ -145,10 +151,13 @@ f := func(st Stanza) { iq, ok := st.(*Iq) if !ok { - Warn.Log("non-iq response") + cl.setError(fmt.Errorf("non-iq response to bind %#v", + st)) + return } if iq.Type == "error" { - Warn.Log("Resource binding failed") + cl.setError(fmt.Errorf("Resource binding failed")) + return } var bindRepl *bindIq for _, ele := range iq.Nested { @@ -158,22 +167,20 @@ } } if bindRepl == nil { - Warn.Logf("Bad bind reply: %#v", iq) - } - jidStr := bindRepl.Jid - if jidStr == nil || *jidStr == "" { - Warn.Log("Can't bind empty resource") + cl.setError(fmt.Errorf("Bad bind reply: %#v", iq)) + return } - jid := new(JID) - if err := jid.Set(*jidStr); err != nil { - Warn.Logf("Can't parse JID %s: %s", *jidStr, err) + jid := bindRepl.Jid + if jid == nil || *jid == "" { + cl.setError(fmt.Errorf("empty resource in bind %#v", + iq)) + return } - cl.Jid = *jid - Info.Logf("Bound resource: %s", cl.Jid.String()) + cl.Jid = JID(*jid) cl.setStatus(StatusBound) } cl.SetCallback(msg.Id, f) - cl.sendXml <- msg + cl.sendRaw <- msg } // Register a callback to handle the next XMPP stanza (iq, message, or