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