2018-01-11 21:15:54 +00:00
|
|
|
package xmpp
|
|
|
|
|
|
|
|
import (
|
2018-01-11 22:00:59 +00:00
|
|
|
"encoding/xml"
|
|
|
|
"errors"
|
2018-01-11 21:15:54 +00:00
|
|
|
"fmt"
|
2018-01-11 22:00:59 +00:00
|
|
|
"io"
|
2018-01-11 21:15:54 +00:00
|
|
|
"net"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
const componentStreamOpen = "<?xml version='1.0'?><stream:stream to='%s' xmlns='%s' xmlns:stream='%s'>"
|
|
|
|
|
|
|
|
// Component implements an XMPP extension allowing to extend XMPP server
|
|
|
|
// using external components. Component specifications are defined
|
|
|
|
// in XEP-0114, XEP-0355 and XEP-0356.
|
|
|
|
type Component struct {
|
|
|
|
// TCP level connection
|
|
|
|
conn net.Conn
|
2018-01-11 22:00:59 +00:00
|
|
|
|
|
|
|
// read / write
|
|
|
|
socketProxy io.ReadWriter
|
|
|
|
decoder *xml.Decoder
|
2018-01-11 21:15:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// TODO Helper to prepare connection string
|
|
|
|
func Open(connStr string) error {
|
2018-01-11 22:00:59 +00:00
|
|
|
c := Component{}
|
|
|
|
|
2018-01-11 21:15:54 +00:00
|
|
|
var conn net.Conn
|
|
|
|
var err error
|
|
|
|
if conn, err = net.DialTimeout("tcp", "localhost:8888", time.Duration(5)*time.Second); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2018-01-11 22:00:59 +00:00
|
|
|
c.conn = conn
|
2018-01-11 21:15:54 +00:00
|
|
|
|
|
|
|
// TODO send stream open and check for reply
|
|
|
|
// Send stream open tag
|
2018-01-11 22:00:59 +00:00
|
|
|
componentHost := connStr // TODO Fix me
|
2018-01-11 21:15:54 +00:00
|
|
|
if _, err := fmt.Fprintf(conn, componentStreamOpen, componentHost, NSComponent, NSStream); err != nil {
|
2018-01-11 22:00:59 +00:00
|
|
|
fmt.Println("cannot send stream open.")
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
c.decoder = xml.NewDecoder(conn)
|
|
|
|
|
|
|
|
// Initialize xml decoder and extract streamID from reply
|
|
|
|
streamId, err := initDecoder(c.decoder)
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println("cannot init decoder")
|
2018-01-11 21:15:54 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2018-01-11 22:00:59 +00:00
|
|
|
fmt.Println("StreamID = ", streamId)
|
|
|
|
|
|
|
|
// Authentication
|
|
|
|
if _, err := fmt.Fprint(conn, "<handshake>aaee83c26aeeafcbabeabfcbcd50df997e0a2a1e</handshake>"); err != nil {
|
|
|
|
fmt.Println("cannot send stream open.")
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Next message should be either success or failure.
|
|
|
|
name, val, err := next(c.decoder)
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println(err)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
switch v := val.(type) {
|
|
|
|
case *StreamError:
|
|
|
|
fmt.Printf("error: %s", v.Error.Local)
|
|
|
|
default:
|
|
|
|
return errors.New("unexpected packet, got " + name.Local + " in " + name.Space)
|
|
|
|
}
|
|
|
|
|
2018-01-11 21:15:54 +00:00
|
|
|
return nil
|
|
|
|
}
|