Fix XMPP logger consistency
- Rename socketProxy to StreamLogger - Ensure client send traffic through the logger
This commit is contained in:
parent
318e5e8a50
commit
5992cc2231
|
@ -18,7 +18,7 @@ func main() {
|
||||||
Address: "localhost:5222",
|
Address: "localhost:5222",
|
||||||
Jid: "test@localhost",
|
Jid: "test@localhost",
|
||||||
Password: "test",
|
Password: "test",
|
||||||
PacketLogger: os.Stdout,
|
StreamLogger: os.Stdout,
|
||||||
Insecure: true,
|
Insecure: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ func main() {
|
||||||
Address: *address,
|
Address: *address,
|
||||||
Jid: *jid,
|
Jid: *jid,
|
||||||
Password: *password,
|
Password: *password,
|
||||||
// PacketLogger: os.Stdout,
|
// StreamLogger: os.Stdout,
|
||||||
Insecure: true,
|
Insecure: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
13
client.go
13
client.go
|
@ -133,7 +133,7 @@ func (c *Client) Connect() error {
|
||||||
//fmt.Fprintf(client.conn, "<presence xml:lang='en'><show>%s</show><status>%s</status></presence>", "chat", "Online")
|
//fmt.Fprintf(client.conn, "<presence xml:lang='en'><show>%s</show><status>%s</status></presence>", "chat", "Online")
|
||||||
// TODO: Do we always want to send initial presence automatically ?
|
// TODO: Do we always want to send initial presence automatically ?
|
||||||
// Do we need an option to avoid that or do we rely on client to send the presence itself ?
|
// Do we need an option to avoid that or do we rely on client to send the presence itself ?
|
||||||
fmt.Fprintf(c.Session.socketProxy, "<presence/>")
|
fmt.Fprintf(c.Session.streamLogger, "<presence/>")
|
||||||
|
|
||||||
// Start the keepalive go routine
|
// Start the keepalive go routine
|
||||||
keepaliveQuit := make(chan struct{})
|
keepaliveQuit := make(chan struct{})
|
||||||
|
@ -166,10 +166,7 @@ func (c *Client) Send(packet stanza.Packet) error {
|
||||||
return errors.New("cannot marshal packet " + err.Error())
|
return errors.New("cannot marshal packet " + err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := fmt.Fprintf(conn, string(data)); err != nil {
|
return c.sendWithLogger(string(data))
|
||||||
return errors.New("cannot send packet " + err.Error())
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SendRaw sends an XMPP stanza as a string to the server.
|
// SendRaw sends an XMPP stanza as a string to the server.
|
||||||
|
@ -182,8 +179,12 @@ func (c *Client) SendRaw(packet string) error {
|
||||||
return errors.New("client is not connected")
|
return errors.New("client is not connected")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return c.sendWithLogger(packet)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) sendWithLogger(packet string) error {
|
||||||
var err error
|
var err error
|
||||||
_, err = fmt.Fprintf(conn, packet)
|
_, err = fmt.Fprintf(c.Session.streamLogger, packet)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ type Config struct {
|
||||||
Jid string
|
Jid string
|
||||||
parsedJid *Jid // For easier manipulation
|
parsedJid *Jid // For easier manipulation
|
||||||
Password string
|
Password string
|
||||||
PacketLogger *os.File // Used for debugging
|
StreamLogger *os.File // Used for debugging
|
||||||
Lang string // TODO: should default to 'en'
|
Lang string // TODO: should default to 'en'
|
||||||
ConnectTimeout int // Client timeout in seconds. Default to 15
|
ConnectTimeout int // Client timeout in seconds. Default to 15
|
||||||
// Insecure can be set to true to allow to open a session without TLS. If TLS
|
// Insecure can be set to true to allow to open a session without TLS. If TLS
|
||||||
|
|
25
session.go
25
session.go
|
@ -26,7 +26,7 @@ type Session struct {
|
||||||
Out chan interface{}
|
Out chan interface{}
|
||||||
|
|
||||||
// read / write
|
// read / write
|
||||||
socketProxy io.ReadWriter
|
streamLogger io.ReadWriter
|
||||||
decoder *xml.Decoder
|
decoder *xml.Decoder
|
||||||
|
|
||||||
// error management
|
// error management
|
||||||
|
@ -65,7 +65,7 @@ func (s *Session) PacketId() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Session) init(conn net.Conn, o Config) {
|
func (s *Session) init(conn net.Conn, o Config) {
|
||||||
s.setProxy(nil, conn, o)
|
s.setStreamLogger(nil, conn, o)
|
||||||
s.Features = s.open(o.parsedJid.Domain)
|
s.Features = s.open(o.parsedJid.Domain)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,22 +74,21 @@ func (s *Session) reset(conn net.Conn, newConn net.Conn, o Config) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
s.setProxy(conn, newConn, o)
|
s.setStreamLogger(conn, newConn, o)
|
||||||
s.Features = s.open(o.parsedJid.Domain)
|
s.Features = s.open(o.parsedJid.Domain)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: setProxyLogger ? better name ? This is not a TCP / HTTP proxy
|
func (s *Session) setStreamLogger(conn net.Conn, newConn net.Conn, o Config) {
|
||||||
func (s *Session) setProxy(conn net.Conn, newConn net.Conn, o Config) {
|
|
||||||
if newConn != conn {
|
if newConn != conn {
|
||||||
s.socketProxy = newSocketProxy(newConn, o.PacketLogger)
|
s.streamLogger = newStreamLogger(newConn, o.StreamLogger)
|
||||||
}
|
}
|
||||||
s.decoder = xml.NewDecoder(s.socketProxy)
|
s.decoder = xml.NewDecoder(s.streamLogger)
|
||||||
s.decoder.CharsetReader = o.CharsetReader
|
s.decoder.CharsetReader = o.CharsetReader
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Session) open(domain string) (f stanza.StreamFeatures) {
|
func (s *Session) open(domain string) (f stanza.StreamFeatures) {
|
||||||
// Send stream open tag
|
// Send stream open tag
|
||||||
if _, s.err = fmt.Fprintf(s.socketProxy, xmppStreamOpen, domain, stanza.NSClient, stanza.NSStream); s.err != nil {
|
if _, s.err = fmt.Fprintf(s.streamLogger, xmppStreamOpen, domain, stanza.NSClient, stanza.NSStream); s.err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +111,7 @@ func (s *Session) startTlsIfSupported(conn net.Conn, domain string) net.Conn {
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := s.Features.DoesStartTLS(); ok {
|
if _, ok := s.Features.DoesStartTLS(); ok {
|
||||||
fmt.Fprintf(s.socketProxy, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>")
|
fmt.Fprintf(s.streamLogger, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>")
|
||||||
|
|
||||||
var k stanza.TLSProceed
|
var k stanza.TLSProceed
|
||||||
if s.err = s.decoder.DecodeElement(&k, nil); s.err != nil {
|
if s.err = s.decoder.DecodeElement(&k, nil); s.err != nil {
|
||||||
|
@ -143,7 +142,7 @@ func (s *Session) auth(o Config) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
s.err = authSASL(s.socketProxy, s.decoder, s.Features, o.parsedJid.Node, o.Password)
|
s.err = authSASL(s.streamLogger, s.decoder, s.Features, o.parsedJid.Node, o.Password)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Session) bind(o Config) {
|
func (s *Session) bind(o Config) {
|
||||||
|
@ -154,10 +153,10 @@ func (s *Session) bind(o Config) {
|
||||||
// Send IQ message asking to bind to the local user name.
|
// Send IQ message asking to bind to the local user name.
|
||||||
var resource = o.parsedJid.Resource
|
var resource = o.parsedJid.Resource
|
||||||
if resource != "" {
|
if resource != "" {
|
||||||
fmt.Fprintf(s.socketProxy, "<iq type='set' id='%s'><bind xmlns='%s'><resource>%s</resource></bind></iq>",
|
fmt.Fprintf(s.streamLogger, "<iq type='set' id='%s'><bind xmlns='%s'><resource>%s</resource></bind></iq>",
|
||||||
s.PacketId(), stanza.NSBind, resource)
|
s.PacketId(), stanza.NSBind, resource)
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(s.socketProxy, "<iq type='set' id='%s'><bind xmlns='%s'/></iq>", s.PacketId(), stanza.NSBind)
|
fmt.Fprintf(s.streamLogger, "<iq type='set' id='%s'><bind xmlns='%s'/></iq>", s.PacketId(), stanza.NSBind)
|
||||||
}
|
}
|
||||||
|
|
||||||
var iq stanza.IQ
|
var iq stanza.IQ
|
||||||
|
@ -186,7 +185,7 @@ func (s *Session) rfc3921Session(o Config) {
|
||||||
|
|
||||||
var iq stanza.IQ
|
var iq stanza.IQ
|
||||||
if s.Features.Session.Optional.Local != "" {
|
if s.Features.Session.Optional.Local != "" {
|
||||||
fmt.Fprintf(s.socketProxy, "<iq type='set' id='%s'><session xmlns='%s'/></iq>", s.PacketId(), stanza.NSSession)
|
fmt.Fprintf(s.streamLogger, "<iq type='set' id='%s'><session xmlns='%s'/></iq>", s.PacketId(), stanza.NSSession)
|
||||||
if s.err = s.decoder.Decode(&iq); s.err != nil {
|
if s.err = s.decoder.Decode(&iq); s.err != nil {
|
||||||
s.err = errors.New("expecting iq result after session open: " + s.err.Error())
|
s.err = errors.New("expecting iq result after session open: " + s.err.Error())
|
||||||
return
|
return
|
||||||
|
|
|
@ -7,20 +7,20 @@ import (
|
||||||
|
|
||||||
// Mediated Read / Write on socket
|
// Mediated Read / Write on socket
|
||||||
// Used if logFile from Config is not nil
|
// Used if logFile from Config is not nil
|
||||||
type socketProxy struct {
|
type streamLogger struct {
|
||||||
socket io.ReadWriter // Actual connection
|
socket io.ReadWriter // Actual connection
|
||||||
logFile *os.File
|
logFile *os.File
|
||||||
}
|
}
|
||||||
|
|
||||||
func newSocketProxy(conn io.ReadWriter, logFile *os.File) io.ReadWriter {
|
func newStreamLogger(conn io.ReadWriter, logFile *os.File) io.ReadWriter {
|
||||||
if logFile == nil {
|
if logFile == nil {
|
||||||
return conn
|
return conn
|
||||||
} else {
|
} else {
|
||||||
return &socketProxy{conn, logFile}
|
return &streamLogger{conn, logFile}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sp *socketProxy) Read(p []byte) (n int, err error) {
|
func (sp *streamLogger) Read(p []byte) (n int, err error) {
|
||||||
n, err = sp.socket.Read(p)
|
n, err = sp.socket.Read(p)
|
||||||
if n > 0 {
|
if n > 0 {
|
||||||
sp.logFile.Write([]byte("RECV:\n")) // Prefix
|
sp.logFile.Write([]byte("RECV:\n")) // Prefix
|
||||||
|
@ -32,7 +32,7 @@ func (sp *socketProxy) Read(p []byte) (n int, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sp *socketProxy) Write(p []byte) (n int, err error) {
|
func (sp *streamLogger) Write(p []byte) (n int, err error) {
|
||||||
sp.logFile.Write([]byte("SEND:\n")) // Prefix
|
sp.logFile.Write([]byte("SEND:\n")) // Prefix
|
||||||
for _, w := range []io.Writer{sp.socket, sp.logFile} {
|
for _, w := range []io.Writer{sp.socket, sp.logFile} {
|
||||||
n, err = w.Write(p)
|
n, err = w.Write(p)
|
||||||
|
@ -47,3 +47,7 @@ func (sp *socketProxy) Write(p []byte) (n int, err error) {
|
||||||
sp.logFile.Write([]byte("\n\n")) // Separator
|
sp.logFile.Write([]byte("\n\n")) // Separator
|
||||||
return len(p), nil
|
return len(p), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
TODO: Make RECV, SEND prefixes +
|
||||||
|
*/
|
Loading…
Reference in a new issue