2019-10-06 10:37:56 -07:00
|
|
|
package xmpp
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/tls"
|
2019-10-18 11:29:54 -07:00
|
|
|
"encoding/xml"
|
2019-10-10 22:15:47 -07:00
|
|
|
"errors"
|
2019-10-25 06:22:01 -07:00
|
|
|
"fmt"
|
2019-10-18 11:29:54 -07:00
|
|
|
"io"
|
2019-10-10 22:19:55 -07:00
|
|
|
"strings"
|
2019-10-06 10:37:56 -07:00
|
|
|
)
|
|
|
|
|
2019-10-25 06:22:01 -07:00
|
|
|
var ErrTransportProtocolNotSupported = errors.New("Transport protocol not supported")
|
|
|
|
var ErrTLSNotSupported = errors.New("Transport does not support StartTLS")
|
2019-10-10 22:15:47 -07:00
|
|
|
|
2019-10-10 21:24:27 -07:00
|
|
|
type TransportConfiguration struct {
|
2019-10-10 21:41:15 -07:00
|
|
|
// Address is the XMPP Host and port to connect to. Host is of
|
|
|
|
// the form 'serverhost:port' i.e "localhost:8888"
|
|
|
|
Address string
|
2019-10-18 11:29:54 -07:00
|
|
|
Domain string
|
2019-10-10 21:24:27 -07:00
|
|
|
ConnectTimeout int // Client timeout in seconds. Default to 15
|
|
|
|
// tls.Config must not be modified after having been passed to NewClient. Any
|
|
|
|
// changes made after connecting are ignored.
|
2019-10-18 11:29:54 -07:00
|
|
|
TLSConfig *tls.Config
|
|
|
|
CharsetReader func(charset string, input io.Reader) (io.Reader, error) // passed to xml decoder
|
2019-10-10 21:24:27 -07:00
|
|
|
}
|
|
|
|
|
2019-10-06 10:37:56 -07:00
|
|
|
type Transport interface {
|
2019-10-18 11:29:54 -07:00
|
|
|
Connect() (string, error)
|
2019-10-06 10:37:56 -07:00
|
|
|
DoesStartTLS() bool
|
2019-10-25 06:22:01 -07:00
|
|
|
StartTLS() (string, error)
|
2019-10-06 10:37:56 -07:00
|
|
|
|
2019-10-18 11:29:54 -07:00
|
|
|
LogTraffic(logFile io.Writer)
|
|
|
|
|
|
|
|
GetDecoder() *xml.Decoder
|
2019-10-10 22:15:47 -07:00
|
|
|
IsSecure() bool
|
|
|
|
|
2019-10-15 11:56:11 -07:00
|
|
|
Ping() error
|
2019-10-06 10:37:56 -07:00
|
|
|
Read(p []byte) (n int, err error)
|
|
|
|
Write(p []byte) (n int, err error)
|
|
|
|
Close() error
|
|
|
|
}
|
2019-10-10 21:41:15 -07:00
|
|
|
|
2019-10-25 06:22:01 -07:00
|
|
|
// NewClientTransport creates a new Transport instance for clients.
|
2019-10-10 22:19:55 -07:00
|
|
|
// The type of transport is determined by the address in the configuration:
|
|
|
|
// - if the address is a URL with the `ws` or `wss` scheme WebsocketTransport is used
|
|
|
|
// - in all other cases a XMPPTransport is used
|
|
|
|
// For XMPPTransport it is mandatory for the address to have a port specified.
|
2019-10-25 06:22:01 -07:00
|
|
|
func NewClientTransport(config TransportConfiguration) Transport {
|
2019-10-10 22:19:55 -07:00
|
|
|
if strings.HasPrefix(config.Address, "ws:") || strings.HasPrefix(config.Address, "wss:") {
|
|
|
|
return &WebsocketTransport{Config: config}
|
|
|
|
}
|
2019-10-12 06:49:22 -07:00
|
|
|
|
|
|
|
config.Address = ensurePort(config.Address, 5222)
|
2019-10-25 06:22:01 -07:00
|
|
|
return &XMPPTransport{
|
|
|
|
Config: config,
|
|
|
|
openStatement: clientStreamOpen,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewComponentTransport creates a new Transport instance for components.
|
|
|
|
// Only XMPP transports are allowed. If you try to use any other protocol an error
|
|
|
|
// will be returned.
|
|
|
|
func NewComponentTransport(config TransportConfiguration) (Transport, error) {
|
|
|
|
if strings.HasPrefix(config.Address, "ws:") || strings.HasPrefix(config.Address, "wss:") {
|
|
|
|
return nil, fmt.Errorf("Components only support XMPP transport: %w", ErrTransportProtocolNotSupported)
|
|
|
|
}
|
|
|
|
|
|
|
|
config.Address = ensurePort(config.Address, 5222)
|
|
|
|
return &XMPPTransport{
|
|
|
|
Config: config,
|
|
|
|
openStatement: componentStreamOpen,
|
|
|
|
}, nil
|
2019-10-10 21:41:15 -07:00
|
|
|
}
|