quick fix for component see #47

This commit is contained in:
Martin/Geno 2019-09-05 22:01:40 +02:00 committed by Mickaël Rémond
parent 6f9808fe16
commit 7e596fc33c

View File

@ -66,52 +66,60 @@ func NewComponent(opts ComponentOptions, r *Router) (*Component, error) {
// Connect triggers component connection to XMPP server component port. // Connect triggers component connection to XMPP server component port.
// TODO: Failed handshake should be a permanent error // TODO: Failed handshake should be a permanent error
func (c *Component) Connect() error { func (c *Component) Connect() error {
var state SMState
return c.Resume(state)
}
func (c *Component) Resume(sm SMState) error {
var conn net.Conn var conn net.Conn
var err error var err error
if conn, err = net.DialTimeout("tcp", c.Address, time.Duration(5)*time.Second); err != nil { if conn, err = net.DialTimeout("tcp", c.Address, time.Duration(5)*time.Second); err != nil {
return err return err
} }
c.conn = conn c.conn = conn
c.updateState(StateConnected)
// 1. Send stream open tag // 1. Send stream open tag
if _, err := fmt.Fprintf(conn, componentStreamOpen, c.Domain, stanza.NSComponent, stanza.NSStream); err != nil { if _, err := fmt.Fprintf(conn, componentStreamOpen, c.Domain, stanza.NSComponent, stanza.NSStream); err != nil {
return errors.New("cannot send stream open " + err.Error()) c.updateState(StateStreamError)
return NewConnError(errors.New("cannot send stream open "+err.Error()), false)
} }
c.decoder = xml.NewDecoder(conn) c.decoder = xml.NewDecoder(conn)
// 2. Initialize xml decoder and extract streamID from reply // 2. Initialize xml decoder and extract streamID from reply
streamId, err := stanza.InitStream(c.decoder) streamId, err := stanza.InitStream(c.decoder)
if err != nil { if err != nil {
return errors.New("cannot init decoder " + err.Error()) c.updateState(StateStreamError)
return NewConnError(errors.New("cannot init decoder "+err.Error()), false)
} }
// 3. Authentication // 3. Authentication
if _, err := fmt.Fprintf(conn, "<handshake>%s</handshake>", c.handshake(streamId)); err != nil { if _, err := fmt.Fprintf(conn, "<handshake>%s</handshake>", c.handshake(streamId)); err != nil {
return errors.New("cannot send handshake " + err.Error()) c.updateState(StateStreamError)
return NewConnError(errors.New("cannot send handshake "+err.Error()), false)
} }
// 4. Check server response for authentication // 4. Check server response for authentication
val, err := stanza.NextPacket(c.decoder) val, err := stanza.NextPacket(c.decoder)
if err != nil { if err != nil {
return err c.updateState(StateDisconnected)
return NewConnError(err, true)
} }
switch v := val.(type) { switch v := val.(type) {
case stanza.StreamError: case stanza.StreamError:
return errors.New("handshake failed " + v.Error.Local) c.streamError("conflict", "no auth loop")
return NewConnError(errors.New("handshake failed "+v.Error.Local), true)
case stanza.Handshake: case stanza.Handshake:
// Start the receiver go routine // Start the receiver go routine
c.updateState(StateSessionEstablished)
go c.recv() go c.recv()
return nil return nil
default: default:
return errors.New("expecting handshake result, got " + v.Name()) c.updateState(StateStreamError)
return NewConnError(errors.New("expecting handshake result, got "+v.Name()), true)
} }
} }
func (c *Component) Resume(SMState) error {
return errors.New("components do not support stream management")
}
func (c *Component) Disconnect() { func (c *Component) Disconnect() {
_ = c.SendRaw("</stream:stream>") _ = c.SendRaw("</stream:stream>")
// TODO: Add a way to wait for stream close acknowledgement from the server for clean disconnect // TODO: Add a way to wait for stream close acknowledgement from the server for clean disconnect