1
0
Fork 0

Add component API and example.

This commit is contained in:
Matt Goodall 2012-06-27 13:03:42 +01:00
parent 9933414cc1
commit 7cf14c4f35
2 changed files with 113 additions and 0 deletions

27
component.go Normal file
View File

@ -0,0 +1,27 @@
package main
import (
"flag"
"log"
"xmpp"
)
func main() {
jid := flag.String("jid", "", "JID")
secret := flag.String("secret", "", "Component secret")
flag.Parse()
jid2, err := xmpp.ParseJID(*jid)
if err != nil {
log.Fatal(err)
}
c, err := xmpp.NewComponent("localhost:5347", jid2, *secret)
if err != nil {
log.Fatal(err)
}
log.Println(c)
select {}
}

86
src/xmpp/component.go Normal file
View File

@ -0,0 +1,86 @@
package xmpp
import (
"crypto/sha1"
"encoding/xml"
"errors"
"fmt"
"log"
)
type component struct {
jid JID
stream *Stream
}
func NewComponent(addr string, jid JID, secret string) (*component, error) {
stream, err := NewStream(addr)
if err != nil {
return nil, err
}
if err := stream.Send("<?xml version='1.0'?>"); err != nil {
return nil, err
}
streamId, err := startComponent(stream, jid)
if err != nil {
return nil, err
}
if err := handshake(stream, streamId, secret); err != nil {
return nil, err
}
return &component{jid, stream}, nil
}
func startComponent(stream *Stream, jid JID) (string, error) {
s := fmt.Sprintf(
"<stream:stream xmlns='jabber:component:accept' xmlns:stream='http://etherx.jabber.org/streams' to='%s'>",
jid)
if err := stream.Send(s); err != nil {
return "", err
}
streamId := ""
if e, err := stream.Next(&xml.Name{nsStream, "stream"}); err != nil {
return "", err
} else {
// Find the stream id.
for _, attr := range e.Attr {
if attr.Name.Local == "id" {
streamId = attr.Value
break
}
}
if streamId == "" {
return "", errors.New("Missing stream id")
}
}
return streamId, nil
}
func handshake(stream *Stream, streamId, secret string) error {
hash := sha1.New()
hash.Write([]byte(streamId))
hash.Write([]byte(secret))
// Send handshake.
s := fmt.Sprintf("<handshake>%x</handshake>", hash.Sum(nil))
log.Println(s)
if err := stream.Send(s); err != nil {
return err
}
// Get handshake response.
if _, err := stream.Next(&xml.Name{"jabber:component:accept", "handshake"}); err != nil {
return err
}
return nil
}