Changed "Disconnect" to wait for the closing stream tag. (#141)

Updated example with a README.md and fixed some logs.
This commit is contained in:
remicorniere
2019-12-26 13:47:02 +00:00
committed by Jérôme Sautret
parent e62b7fa0c7
commit 94aceac802
13 changed files with 252 additions and 52 deletions

View File

@@ -24,6 +24,7 @@ type XMPPTransport struct {
readWriter io.ReadWriter
logFile io.Writer
isSecure bool
closeChan chan stanza.StreamClosePacket
}
var componentStreamOpen = fmt.Sprintf("<?xml version='1.0'?><stream:stream to='%%s' xmlns='%s' xmlns:stream='%s'>", stanza.NSComponent, stanza.NSStream)
@@ -38,13 +39,14 @@ func (t *XMPPTransport) Connect() (string, error) {
return "", NewConnError(err, true)
}
t.closeChan = make(chan stanza.StreamClosePacket)
t.readWriter = newStreamLogger(t.conn, t.logFile)
t.decoder = xml.NewDecoder(bufio.NewReaderSize(t.readWriter, maxPacketSize))
t.decoder.CharsetReader = t.Config.CharsetReader
return t.StartStream()
}
func (t XMPPTransport) StartStream() (string, error) {
func (t *XMPPTransport) StartStream() (string, error) {
if _, err := fmt.Fprintf(t, t.openStatement, t.Config.Domain); err != nil {
t.Close()
return "", NewConnError(err, true)
@@ -58,19 +60,19 @@ func (t XMPPTransport) StartStream() (string, error) {
return sessionID, nil
}
func (t XMPPTransport) DoesStartTLS() bool {
func (t *XMPPTransport) DoesStartTLS() bool {
return true
}
func (t XMPPTransport) GetDomain() string {
func (t *XMPPTransport) GetDomain() string {
return t.Config.Domain
}
func (t XMPPTransport) GetDecoder() *xml.Decoder {
func (t *XMPPTransport) GetDecoder() *xml.Decoder {
return t.decoder
}
func (t XMPPTransport) IsSecure() bool {
func (t *XMPPTransport) IsSecure() bool {
return t.isSecure
}
@@ -105,7 +107,7 @@ func (t *XMPPTransport) StartTLS() error {
return nil
}
func (t XMPPTransport) Ping() error {
func (t *XMPPTransport) Ping() error {
n, err := t.conn.Write([]byte("\n"))
if err != nil {
return err
@@ -116,24 +118,31 @@ func (t XMPPTransport) Ping() error {
return nil
}
func (t XMPPTransport) Read(p []byte) (n int, err error) {
func (t *XMPPTransport) Read(p []byte) (n int, err error) {
if t.readWriter == nil {
return 0, errors.New("cannot read: not connected, no readwriter")
}
return t.readWriter.Read(p)
}
func (t XMPPTransport) Write(p []byte) (n int, err error) {
func (t *XMPPTransport) Write(p []byte) (n int, err error) {
if t.readWriter == nil {
return 0, errors.New("cannot write: not connected, no readwriter")
}
return t.readWriter.Write(p)
}
func (t XMPPTransport) Close() error {
func (t *XMPPTransport) Close() error {
if t.readWriter != nil {
_, _ = t.readWriter.Write([]byte("</stream:stream>"))
_, _ = t.readWriter.Write([]byte(stanza.StreamClose))
}
// Try to wait for the stream close tag from the server. After a timeout, disconnect anyway.
select {
case <-t.closeChan:
case <-time.After(time.Duration(t.Config.ConnectTimeout) * time.Second):
}
if t.conn != nil {
return t.conn.Close()
}
@@ -143,3 +152,7 @@ func (t XMPPTransport) Close() error {
func (t *XMPPTransport) LogTraffic(logFile io.Writer) {
t.logFile = logFile
}
func (t *XMPPTransport) ReceivedStreamClose() {
t.closeChan <- stanza.StreamClosePacket{}
}