go-xmpp/transport.go

79 lines
2.5 KiB
Go
Raw Normal View History

2019-10-06 10:37:56 -07:00
package xmpp
import (
"crypto/tls"
"encoding/xml"
2019-10-10 22:15:47 -07:00
"errors"
2019-10-25 06:22:01 -07:00
"fmt"
"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-11-04 03:58:10 -08:00
// TODO: rename to transport config?
type TransportConfiguration struct {
// Address is the XMPP Host and port to connect to. Host is of
// the form 'serverhost:port' i.e "localhost:8888"
Address string
Domain string
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.
TLSConfig *tls.Config
CharsetReader func(charset string, input io.Reader) (io.Reader, error) // passed to xml decoder
}
2019-10-06 10:37:56 -07:00
type Transport interface {
Connect() (string, error)
2019-10-06 10:37:56 -07:00
DoesStartTLS() bool
StartTLS() error
2019-10-06 10:37:56 -07:00
LogTraffic(logFile io.Writer)
StartStream() (string, error)
GetDecoder() *xml.Decoder
2019-10-10 22:15:47 -07:00
IsSecure() bool
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
// ReceivedStreamClose signals to the transport that a </stream:stream> has been received and that the tcp connection
// should be closed.
ReceivedStreamClose()
2019-10-06 10:37:56 -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}
}
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
}