Skip to content

Commit

Permalink
Refactored the connection to use the util helpers.
Browse files Browse the repository at this point in the history
  • Loading branch information
Dmitry Ratnikov committed Apr 12, 2011
1 parent b0cd8cd commit ac14cb7
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 88 deletions.
127 changes: 40 additions & 87 deletions connection.go
@@ -1,41 +1,43 @@
package xmpp;

import (
"bytes"
"crypto/tls"
"io"
"fmt"
"os"
"regexp"
"net"
"xml"
)

type Client struct {
tls *tls.Conn
tls_read io.ByteReader
parser *xml.Parser
err os.Error
hostname string
conn net.Conn
}

func startTls(host string) {
if conn, err := net.Dial("tcp", "", "talk.google.com:5222"); err != nil {
func (client *Client) startTls() {
var plain_conn net.Conn
var err os.Error

if plain_conn, err = net.Dial("tcp", "", client.hostname + ":5222"); err != nil {
die("Failed to establish plain connection: %s", err)
} else {
write(conn, "<?xml version='1.0'?>")
write(conn, "<stream:stream to='gmail.com' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>")
}

fmt.Printf("Read: %s\n", read(conn))
write(plain_conn, "<?xml version='1.0'?>")
write(plain_conn, "<stream:stream to='gmail.com' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>")

// assuming need to start tls
write(conn, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls' />")
log("Read: %s", read(plain_conn))

fmt.Printf("Read: %s\n", read(conn))
// assuming need to start tls
write(plain_conn, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls' />")
log("Read: %s", read(plain_conn))

// assuming the server asked to proceed
if client.conn, err = tls.Dial("tcp", "", client.hostname + ":https", nil); err != nil {
die("Failed to establish tls connection (%s)", err)
}
}


func NewClient(user, password string) (client *Client, failure os.Error) {
func NewClient(hostname, user, password string) (client *Client, failure os.Error) {
failure = nil
defer func() {
if err := recover(); err != nil {
Expand All @@ -48,63 +50,37 @@ func NewClient(user, password string) (client *Client, failure os.Error) {
}
}()

client = &Client{}



hostname := "talk.google.com"

if conn, err := net.Dial("tcp", "", "talk.google.com:5222"); err != nil {
die("Failed to establish plain connection: %s", err)
} else {
client.write(conn, "<?xml version='1.0'?>")
client.write(conn, "<stream:stream to='gmail.com' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>")

fmt.Printf("Read: %s\n", client.read(conn))

// assuming need to start tls
client.write(conn, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls' />")

fmt.Printf("Read: %s\n", client.read(conn))
}

tlsconn, err := tls.Dial("tcp", "", hostname + ":https", nil)

if err != nil {
panic(os.NewError(fmt.Sprintf("Failed to connect to %s (%s)", hostname, err)))
}
client = &Client{hostname: hostname}

client.tls = tlsconn
client.startTls()

tlsconn.Handshake()
client.write("<stream:stream to='gmail.com' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>")

client.write(tlsconn, "<stream:stream to='gmail.com' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>")

client.read(tlsconn)
client.read(tlsconn)
client.read()
client.read()

auth := NewAuth(user, password)

client.write(tlsconn, "<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN' xmlns:ga='http://www.google.com/talk/protocol/auth' ga:client-uses-full-bind-result='true'>%s</auth>", auth.Base64())
client.write("<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN' xmlns:ga='http://www.google.com/talk/protocol/auth' ga:client-uses-full-bind-result='true'>%s</auth>", auth.Base64())

client.read(tlsconn)
client.read()

client.write(tlsconn, "<stream:stream to='gmail.com' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>")
client.write("<stream:stream to='gmail.com' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>")

client.read(tlsconn)
client.read()

client.write(tlsconn, "<iq type='set' id='xmpp-bot1029'><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'><resource>Home</resource></bind></iq>")
client.write("<iq type='set' id='xmpp-bot1029'><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'><resource>Home</resource></bind></iq>")

client.read(tlsconn)
client.read(tlsconn)
client.read(tlsconn)
client.read()
client.read()
client.read()

client.Message("ratnikov@gmail.com", "Write me something and I will write back! (Please send 2 messages at first....)")

client.read(tlsconn)
client.read()

for {
raw := client.read(tlsconn)
raw := client.read()

var recipient, received string

Expand All @@ -126,37 +102,14 @@ func NewClient(user, password string) (client *Client, failure os.Error) {
return client, nil
}

func (client *Client) Message(recipient, msg string) {
client.write(client.tls, fmt.Sprintf("<message type='chat' id='xmpp-bot1029' to='%s'><body>%s</body></message>", recipient, msg))
func (client *Client) read() string {
return read(client.conn)
}

func (client *Client) read(conn io.Reader) (out string) {
buf := make([]byte, 2048)

num, err := conn.Read(buf)

if err != nil {
fmt.Printf("Error occured (%s). Read %d bytes anyway: %s\n", err, num, buf)
} else {
fmt.Printf("Read %d bytes: %s\n", num, buf)
}

return bytes.NewBuffer(buf).String()
func (client *Client) write(format string, args ...interface{}) int {
return write(client.conn, format, args...)
}


func (client *Client) write(conn io.Writer, format string, args ...interface{}) {
buf := bytes.NewBufferString(fmt.Sprintf(format + "\n", args...))

client.log("Sending %s\n", buf.String())

if num, err := conn.Write(buf.Bytes()); err != nil {
panic(os.NewError(fmt.Sprintf("Failed to write... (%s)", err)))
} else {
client.log("Wrote %d bytes to connection", num)
}
}

func (client *Client) log(format string, args ...interface{}) {
fmt.Printf("LOG: %s\n", fmt.Sprintf(format, args... ))
func (client *Client) Message(recipient, msg string) {
client.write("<message type='chat' id='xmpp-bot1029' to='%s'><body>%s</body></message>", recipient, msg)
}
2 changes: 1 addition & 1 deletion main.go
Expand Up @@ -6,7 +6,7 @@ import (
)

func main() {
client, err := xmpp.NewClient("ratnikov@gmail.com", "secret")
client, err := xmpp.NewClient("talk.google.com", "ratnikov@gmail.com", "secret")

if err != nil {
fmt.Printf("Failed due to: %s\n", err)
Expand Down

0 comments on commit ac14cb7

Please sign in to comment.