forked from chteufleur/go-xmpp
Add component API and example.
This commit is contained in:
parent
9933414cc1
commit
7cf14c4f35
|
|
@ -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 {}
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue