author | Chris Jones <chris@cjones.org> |
Fri, 30 Dec 2011 17:16:37 -0700 | |
changeset 33 | 571713f49494 |
parent 32 | 4e68d8f89dc3 |
child 34 | 7b1f924c75e2 |
permissions | -rw-r--r-- |
2
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
1 |
// Copyright 2011 The Go Authors. All rights reserved. |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
2 |
// Use of this source code is governed by a BSD-style |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
3 |
// license that can be found in the LICENSE file. |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
4 |
|
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
5 |
// This package implements a simple XMPP client according to RFCs 3920 |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
6 |
// and 3921, plus the various XEPs at http://xmpp.org/protocols/. |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
7 |
package xmpp |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
8 |
|
20
e119444a1119
Replaced TODO comments with Go-style BUG(me) comments.
Chris Jones <chris@cjones.org>
parents:
17
diff
changeset
|
9 |
// BUG(cjyar) Figure out why the library doesn't exit when the server |
e119444a1119
Replaced TODO comments with Go-style BUG(me) comments.
Chris Jones <chris@cjones.org>
parents:
17
diff
changeset
|
10 |
// closes its stream to us. |
17 | 11 |
|
2
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
12 |
import ( |
6
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
13 |
"bytes" |
2
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
14 |
"fmt" |
4
a8fbec71a194
Added an interactive test and made Client implement io.Closer.
Chris Jones <chris@cjones.org>
parents:
2
diff
changeset
|
15 |
"io" |
28 | 16 |
"log" |
2
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
17 |
"net" |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
18 |
"os" |
10 | 19 |
"sync" |
28 | 20 |
"xml" |
2
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
21 |
) |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
22 |
|
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
23 |
const ( |
10 | 24 |
// Version of RFC 3920 that we implement. |
25 |
Version = "1.0" |
|
26 |
||
33
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
27 |
// BUG(cjyar) These should be public. |
10 | 28 |
// Various XML namespaces. |
29 |
nsStreams = "urn:ietf:params:xml:ns:xmpp-streams" |
|
30 |
nsStream = "http://etherx.jabber.org/streams" |
|
31 |
nsTLS = "urn:ietf:params:xml:ns:xmpp-tls" |
|
11
48be1ae93fd4
Added SASL digest authentication.
Chris Jones <chris@cjones.org>
parents:
10
diff
changeset
|
32 |
nsSASL = "urn:ietf:params:xml:ns:xmpp-sasl" |
12
122ab6208c3c
Added resource binding and structures for <iq>, <message>, and <presence>.
Chris Jones <chris@cjones.org>
parents:
11
diff
changeset
|
33 |
nsBind = "urn:ietf:params:xml:ns:xmpp-bind" |
28 | 34 |
nsSession = "urn:ietf:params:xml:ns:xmpp-session" |
33
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
35 |
NsRoster = "jabber:iq:roster" |
10 | 36 |
|
37 |
// DNS SRV names |
|
2
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
38 |
serverSrv = "xmpp-server" |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
39 |
clientSrv = "xmpp-client" |
10 | 40 |
|
20
e119444a1119
Replaced TODO comments with Go-style BUG(me) comments.
Chris Jones <chris@cjones.org>
parents:
17
diff
changeset
|
41 |
// BUG(cjyar) Make this a parameter to NewClient, not a |
17 | 42 |
// constant. We should have both a log level and a |
43 |
// syslog.Writer, so the app can control how much time we |
|
44 |
// spend generating log messages, as well as where they go. |
|
10 | 45 |
debug = true |
2
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
46 |
) |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
47 |
|
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
48 |
// The client in a client-server XMPP connection. |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
49 |
type Client struct { |
29
a456133ed0ac
Don't accept data on Client.Out until resource binding is
Chris Jones <chris@cjones.org>
parents:
28
diff
changeset
|
50 |
// This client's JID. This will be updated asynchronously by |
a456133ed0ac
Don't accept data on Client.Out until resource binding is
Chris Jones <chris@cjones.org>
parents:
28
diff
changeset
|
51 |
// the time StartSession() returns. |
10 | 52 |
Jid JID |
11
48be1ae93fd4
Added SASL digest authentication.
Chris Jones <chris@cjones.org>
parents:
10
diff
changeset
|
53 |
password string |
10 | 54 |
socket net.Conn |
55 |
socketSync sync.WaitGroup |
|
11
48be1ae93fd4
Added SASL digest authentication.
Chris Jones <chris@cjones.org>
parents:
10
diff
changeset
|
56 |
saslExpected string |
12
122ab6208c3c
Added resource binding and structures for <iq>, <message>, and <presence>.
Chris Jones <chris@cjones.org>
parents:
11
diff
changeset
|
57 |
authDone bool |
13
c9527bbe99a6
Added a callback handler which will handle a stanza with a particular id.
Chris Jones <chris@cjones.org>
parents:
12
diff
changeset
|
58 |
handlers chan *stanzaHandler |
29
a456133ed0ac
Don't accept data on Client.Out until resource binding is
Chris Jones <chris@cjones.org>
parents:
28
diff
changeset
|
59 |
inputControl chan int |
30
a77fc342e013
Replaced Client.NextId() with a channel named Id.
Chris Jones <chris@cjones.org>
parents:
29
diff
changeset
|
60 |
// This channel may be used as a convenient way to generate a |
a77fc342e013
Replaced Client.NextId() with a channel named Id.
Chris Jones <chris@cjones.org>
parents:
29
diff
changeset
|
61 |
// unique id for an iq, message, or presence stanza. |
a77fc342e013
Replaced Client.NextId() with a channel named Id.
Chris Jones <chris@cjones.org>
parents:
29
diff
changeset
|
62 |
Id <-chan string |
17 | 63 |
// Incoming XMPP stanzas from the server will be published on |
64 |
// this channel. Information which is only used by this |
|
65 |
// library to set up the XMPP stream will not appear here. |
|
23
b5de44679389
Made the input and output channels of type Stanza rather than
Chris Jones <chris@cjones.org>
parents:
22
diff
changeset
|
66 |
In <-chan Stanza |
17 | 67 |
// Outgoing XMPP stanzas to the server should be sent to this |
68 |
// channel. |
|
23
b5de44679389
Made the input and output channels of type Stanza rather than
Chris Jones <chris@cjones.org>
parents:
22
diff
changeset
|
69 |
Out chan<- Stanza |
10 | 70 |
xmlOut chan<- interface{} |
32
4e68d8f89dc3
Make the server's advertised features available to the app.
Chris Jones <chris@cjones.org>
parents:
30
diff
changeset
|
71 |
// Features advertised by the remote. This will be updated |
4e68d8f89dc3
Make the server's advertised features available to the app.
Chris Jones <chris@cjones.org>
parents:
30
diff
changeset
|
72 |
// asynchronously as new features are received throughout the |
4e68d8f89dc3
Make the server's advertised features available to the app.
Chris Jones <chris@cjones.org>
parents:
30
diff
changeset
|
73 |
// connection process. It should not be updated once |
4e68d8f89dc3
Make the server's advertised features available to the app.
Chris Jones <chris@cjones.org>
parents:
30
diff
changeset
|
74 |
// StartSession() returns. |
4e68d8f89dc3
Make the server's advertised features available to the app.
Chris Jones <chris@cjones.org>
parents:
30
diff
changeset
|
75 |
Features *Features |
33
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
76 |
roster map[string] *RosterItem |
2
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
77 |
} |
4
a8fbec71a194
Added an interactive test and made Client implement io.Closer.
Chris Jones <chris@cjones.org>
parents:
2
diff
changeset
|
78 |
var _ io.Closer = &Client{} |
2
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
79 |
|
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
80 |
// Connect to the appropriate server and authenticate as the given JID |
17 | 81 |
// with the given password. This function will return as soon as a TCP |
82 |
// connection has been established, but before XMPP stream negotiation |
|
27 | 83 |
// has completed. The negotiation will occur asynchronously, and any |
84 |
// send operation to Client.Out will block until negotiation (resource |
|
85 |
// binding) is complete. |
|
2
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
86 |
func NewClient(jid *JID, password string) (*Client, os.Error) { |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
87 |
// Resolve the domain in the JID. |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
88 |
_, srvs, err := net.LookupSRV(clientSrv, "tcp", jid.Domain) |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
89 |
if err != nil { |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
90 |
return nil, os.NewError("LookupSrv " + jid.Domain + |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
91 |
": " + err.String()) |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
92 |
} |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
93 |
|
9
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
94 |
var tcp *net.TCPConn |
2
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
95 |
for _, srv := range srvs { |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
96 |
addrStr := fmt.Sprintf("%s:%d", srv.Target, srv.Port) |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
97 |
addr, err := net.ResolveTCPAddr("tcp", addrStr) |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
98 |
if err != nil { |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
99 |
err = os.NewError(fmt.Sprintf("ResolveTCPAddr(%s): %s", |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
100 |
addrStr, err.String())) |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
101 |
continue |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
102 |
} |
9
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
103 |
tcp, err = net.DialTCP("tcp", nil, addr) |
2
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
104 |
if err != nil { |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
105 |
err = os.NewError(fmt.Sprintf("DialTCP(%s): %s", |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
106 |
addr, err.String())) |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
107 |
continue |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
108 |
} |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
109 |
} |
9
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
110 |
if tcp == nil { |
2
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
111 |
return nil, err |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
112 |
} |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
113 |
|
10 | 114 |
cl := new(Client) |
11
48be1ae93fd4
Added SASL digest authentication.
Chris Jones <chris@cjones.org>
parents:
10
diff
changeset
|
115 |
cl.password = password |
10 | 116 |
cl.Jid = *jid |
117 |
cl.socket = tcp |
|
33
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
118 |
cl.handlers = make(chan *stanzaHandler, 100) |
29
a456133ed0ac
Don't accept data on Client.Out until resource binding is
Chris Jones <chris@cjones.org>
parents:
28
diff
changeset
|
119 |
cl.inputControl = make(chan int) |
30
a77fc342e013
Replaced Client.NextId() with a channel named Id.
Chris Jones <chris@cjones.org>
parents:
29
diff
changeset
|
120 |
idCh := make(chan string) |
a77fc342e013
Replaced Client.NextId() with a channel named Id.
Chris Jones <chris@cjones.org>
parents:
29
diff
changeset
|
121 |
cl.Id = idCh |
a77fc342e013
Replaced Client.NextId() with a channel named Id.
Chris Jones <chris@cjones.org>
parents:
29
diff
changeset
|
122 |
|
a77fc342e013
Replaced Client.NextId() with a channel named Id.
Chris Jones <chris@cjones.org>
parents:
29
diff
changeset
|
123 |
// Start the unique id generator. |
a77fc342e013
Replaced Client.NextId() with a channel named Id.
Chris Jones <chris@cjones.org>
parents:
29
diff
changeset
|
124 |
go makeIds(idCh) |
10 | 125 |
|
9
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
126 |
// Start the transport handler, initially unencrypted. |
10 | 127 |
tlsr, tlsw := cl.startTransport() |
9
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
128 |
|
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
129 |
// Start the reader and writers that convert to and from XML. |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
130 |
xmlIn := startXmlReader(tlsr) |
10 | 131 |
cl.xmlOut = startXmlWriter(tlsw) |
9
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
132 |
|
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
133 |
// Start the XMPP stream handler which filters stream-level |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
134 |
// events and responds to them. |
10 | 135 |
clIn := cl.startStreamReader(xmlIn, cl.xmlOut) |
29
a456133ed0ac
Don't accept data on Client.Out until resource binding is
Chris Jones <chris@cjones.org>
parents:
28
diff
changeset
|
136 |
clOut := cl.startStreamWriter(cl.xmlOut) |
5
faef59c8db05
Added a goroutine to read data from the remote and parse it into
Chris Jones <chris@cjones.org>
parents:
4
diff
changeset
|
137 |
|
8
30a7752cf8f7
Added the ability to parse <stream:features>.
Chris Jones <chris@cjones.org>
parents:
6
diff
changeset
|
138 |
// Initial handshake. |
22
d6b7b4cbf50d
Made the stream type non-public.
Chris Jones <chris@cjones.org>
parents:
20
diff
changeset
|
139 |
hsOut := &stream{To: jid.Domain, Version: Version} |
10 | 140 |
cl.xmlOut <- hsOut |
9
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
141 |
|
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
142 |
cl.In = clIn |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
143 |
cl.Out = clOut |
8
30a7752cf8f7
Added the ability to parse <stream:features>.
Chris Jones <chris@cjones.org>
parents:
6
diff
changeset
|
144 |
|
6
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
145 |
return cl, nil |
2
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
146 |
} |
4
a8fbec71a194
Added an interactive test and made Client implement io.Closer.
Chris Jones <chris@cjones.org>
parents:
2
diff
changeset
|
147 |
|
a8fbec71a194
Added an interactive test and made Client implement io.Closer.
Chris Jones <chris@cjones.org>
parents:
2
diff
changeset
|
148 |
func (c *Client) Close() os.Error { |
26 | 149 |
tryClose(c.In, c.Out) |
9
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
150 |
return nil |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
151 |
} |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
152 |
|
10 | 153 |
func (cl *Client) startTransport() (io.Reader, io.Writer) { |
9
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
154 |
inr, inw := io.Pipe() |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
155 |
outr, outw := io.Pipe() |
10 | 156 |
go cl.readTransport(inw) |
157 |
go cl.writeTransport(outr) |
|
9
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
158 |
return inr, outw |
4
a8fbec71a194
Added an interactive test and made Client implement io.Closer.
Chris Jones <chris@cjones.org>
parents:
2
diff
changeset
|
159 |
} |
5
faef59c8db05
Added a goroutine to read data from the remote and parse it into
Chris Jones <chris@cjones.org>
parents:
4
diff
changeset
|
160 |
|
9
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
161 |
func startXmlReader(r io.Reader) <-chan interface{} { |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
162 |
ch := make(chan interface{}) |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
163 |
go readXml(r, ch) |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
164 |
return ch |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
165 |
} |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
166 |
|
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
167 |
func startXmlWriter(w io.Writer) chan<- interface{} { |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
168 |
ch := make(chan interface{}) |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
169 |
go writeXml(w, ch) |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
170 |
return ch |
6
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
171 |
} |
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
172 |
|
23
b5de44679389
Made the input and output channels of type Stanza rather than
Chris Jones <chris@cjones.org>
parents:
22
diff
changeset
|
173 |
func (cl *Client) startStreamReader(xmlIn <-chan interface{}, srvOut chan<- interface{}) <-chan Stanza { |
b5de44679389
Made the input and output channels of type Stanza rather than
Chris Jones <chris@cjones.org>
parents:
22
diff
changeset
|
174 |
ch := make(chan Stanza) |
11
48be1ae93fd4
Added SASL digest authentication.
Chris Jones <chris@cjones.org>
parents:
10
diff
changeset
|
175 |
go cl.readStream(xmlIn, ch) |
9
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
176 |
return ch |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
177 |
} |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
178 |
|
29
a456133ed0ac
Don't accept data on Client.Out until resource binding is
Chris Jones <chris@cjones.org>
parents:
28
diff
changeset
|
179 |
func (cl *Client) startStreamWriter(xmlOut chan<- interface{}) chan<- Stanza { |
23
b5de44679389
Made the input and output channels of type Stanza rather than
Chris Jones <chris@cjones.org>
parents:
22
diff
changeset
|
180 |
ch := make(chan Stanza) |
29
a456133ed0ac
Don't accept data on Client.Out until resource binding is
Chris Jones <chris@cjones.org>
parents:
28
diff
changeset
|
181 |
go writeStream(xmlOut, ch, cl.inputControl) |
9
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
182 |
return ch |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
183 |
} |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
184 |
|
6
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
185 |
func tee(r io.Reader, w io.Writer, prefix string) { |
9
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
186 |
defer tryClose(r, w) |
6
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
187 |
|
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
188 |
buf := bytes.NewBuffer(nil) |
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
189 |
for { |
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
190 |
var c [1]byte |
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
191 |
n, _ := r.Read(c[:]) |
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
192 |
if n == 0 { |
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
193 |
break |
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
194 |
} |
9
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
195 |
n, _ = w.Write(c[:n]) |
6
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
196 |
if n == 0 { |
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
197 |
break |
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
198 |
} |
9
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
199 |
buf.Write(c[:n]) |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
200 |
if c[0] == '\n' || c[0] == '>' { |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
201 |
fmt.Printf("%s%s\n", prefix, buf.String()) |
6
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
202 |
buf.Reset() |
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
203 |
} |
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
204 |
} |
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
205 |
leftover := buf.String() |
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
206 |
if leftover != "" { |
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
207 |
fmt.Printf("%s%s\n", prefix, leftover) |
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
208 |
} |
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
209 |
} |
9
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
210 |
|
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
211 |
func tryClose(xs ...interface{}) { |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
212 |
f1 := func(ch chan<- interface{}) { |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
213 |
defer func() { |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
214 |
recover() |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
215 |
}() |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
216 |
close(ch) |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
217 |
} |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
218 |
f2 := func(ch <-chan interface{}) { |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
219 |
defer func() { |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
220 |
recover() |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
221 |
}() |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
222 |
close(ch) |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
223 |
} |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
224 |
|
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
225 |
for _, x := range xs { |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
226 |
if c, ok := x.(io.Closer) ; ok { |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
227 |
c.Close() |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
228 |
} else if ch, ok := x.(chan<- interface{}) ; ok { |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
229 |
f1(ch) |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
230 |
} else if ch, ok := x.(<-chan interface{}) ; ok { |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
231 |
f2(ch) |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
232 |
} |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
233 |
} |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
234 |
} |
12
122ab6208c3c
Added resource binding and structures for <iq>, <message>, and <presence>.
Chris Jones <chris@cjones.org>
parents:
11
diff
changeset
|
235 |
|
30
a77fc342e013
Replaced Client.NextId() with a channel named Id.
Chris Jones <chris@cjones.org>
parents:
29
diff
changeset
|
236 |
func makeIds(ch chan<- string) { |
a77fc342e013
Replaced Client.NextId() with a channel named Id.
Chris Jones <chris@cjones.org>
parents:
29
diff
changeset
|
237 |
id := int64(1) |
a77fc342e013
Replaced Client.NextId() with a channel named Id.
Chris Jones <chris@cjones.org>
parents:
29
diff
changeset
|
238 |
for { |
a77fc342e013
Replaced Client.NextId() with a channel named Id.
Chris Jones <chris@cjones.org>
parents:
29
diff
changeset
|
239 |
str := fmt.Sprintf("id_%d", id) |
a77fc342e013
Replaced Client.NextId() with a channel named Id.
Chris Jones <chris@cjones.org>
parents:
29
diff
changeset
|
240 |
ch <- str |
a77fc342e013
Replaced Client.NextId() with a channel named Id.
Chris Jones <chris@cjones.org>
parents:
29
diff
changeset
|
241 |
id++ |
a77fc342e013
Replaced Client.NextId() with a channel named Id.
Chris Jones <chris@cjones.org>
parents:
29
diff
changeset
|
242 |
} |
12
122ab6208c3c
Added resource binding and structures for <iq>, <message>, and <presence>.
Chris Jones <chris@cjones.org>
parents:
11
diff
changeset
|
243 |
} |
28 | 244 |
|
29
a456133ed0ac
Don't accept data on Client.Out until resource binding is
Chris Jones <chris@cjones.org>
parents:
28
diff
changeset
|
245 |
// bindDone is called when we've finished resource binding (and all |
a456133ed0ac
Don't accept data on Client.Out until resource binding is
Chris Jones <chris@cjones.org>
parents:
28
diff
changeset
|
246 |
// the negotiations that precede it). Now we can start accepting |
a456133ed0ac
Don't accept data on Client.Out until resource binding is
Chris Jones <chris@cjones.org>
parents:
28
diff
changeset
|
247 |
// traffic from the app. |
a456133ed0ac
Don't accept data on Client.Out until resource binding is
Chris Jones <chris@cjones.org>
parents:
28
diff
changeset
|
248 |
func (cl *Client) bindDone() { |
a456133ed0ac
Don't accept data on Client.Out until resource binding is
Chris Jones <chris@cjones.org>
parents:
28
diff
changeset
|
249 |
cl.inputControl <- 1 |
a456133ed0ac
Don't accept data on Client.Out until resource binding is
Chris Jones <chris@cjones.org>
parents:
28
diff
changeset
|
250 |
} |
a456133ed0ac
Don't accept data on Client.Out until resource binding is
Chris Jones <chris@cjones.org>
parents:
28
diff
changeset
|
251 |
|
33
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
252 |
// Start an XMPP session. A typical XMPP client should call this |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
253 |
// immediately after creating the Client in order to start the |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
254 |
// session, retrieve the roster, and broadcast an initial |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
255 |
// presence. The presence can be as simple as a newly-initialized |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
256 |
// Presence struct. See RFC 3921, Section 3. |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
257 |
func (cl *Client) StartSession(getRoster bool, pr *Presence) os.Error { |
30
a77fc342e013
Replaced Client.NextId() with a channel named Id.
Chris Jones <chris@cjones.org>
parents:
29
diff
changeset
|
258 |
id := <- cl.Id |
28 | 259 |
iq := &Iq{To: cl.Jid.Domain, Id: id, Type: "set", Any: |
260 |
&Generic{XMLName: xml.Name{Space: nsSession, Local: |
|
261 |
"session"}}} |
|
262 |
ch := make(chan os.Error) |
|
263 |
f := func(st Stanza) bool { |
|
264 |
if st.XType() == "error" { |
|
265 |
log.Printf("Can't start session: %v", st) |
|
266 |
ch <- st.XError() |
|
267 |
return false |
|
268 |
} |
|
269 |
ch <- nil |
|
270 |
return false |
|
271 |
} |
|
272 |
cl.HandleStanza(id, f) |
|
273 |
cl.Out <- iq |
|
33
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
274 |
|
28 | 275 |
// Now wait until the callback is called. |
33
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
276 |
if err := <- ch ; err != nil { |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
277 |
return err |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
278 |
} |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
279 |
if getRoster { |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
280 |
err := cl.fetchRoster() |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
281 |
if err != nil { |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
282 |
return err |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
283 |
} |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
284 |
} |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
285 |
if pr != nil { |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
286 |
cl.Out <- pr |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
287 |
} |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
288 |
return nil |
28 | 289 |
} |
33
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
290 |
|
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
291 |
// Synchronously fetch this entity's roster from the server and cache |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
292 |
// that information. |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
293 |
func (cl *Client) fetchRoster() os.Error { |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
294 |
iq := &Iq{From: cl.Jid.String(), Id: <- cl.Id, Type: "get", |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
295 |
Query: &RosterQuery{XMLName: xml.Name{Local: "query", |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
296 |
Space: NsRoster}}} |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
297 |
ch := make(chan os.Error) |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
298 |
f := func(st Stanza) bool { |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
299 |
iq, ok := st.(*Iq) |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
300 |
if !ok { |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
301 |
ch <- os.NewError(fmt.Sprintf( |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
302 |
"Roster query result not iq: %v", st)) |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
303 |
return false |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
304 |
} |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
305 |
if iq.Type == "error" { |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
306 |
ch <- iq.Error |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
307 |
return false |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
308 |
} |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
309 |
q := iq.Query |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
310 |
if q == nil { |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
311 |
ch <- os.NewError(fmt.Sprintf( |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
312 |
"Roster query result nil query: %v", |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
313 |
iq)) |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
314 |
return false |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
315 |
} |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
316 |
cl.roster = make(map[string] *RosterItem, len(q.Item)) |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
317 |
for _, item := range(q.Item) { |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
318 |
cl.roster[item.Jid] = &item |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
319 |
} |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
320 |
ch <- nil |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
321 |
return false |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
322 |
} |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
323 |
cl.HandleStanza(iq.Id, f) |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
324 |
cl.Out <- iq |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
325 |
// Wait for f to complete. |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
326 |
return <- ch |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
327 |
} |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
328 |
|
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
329 |
// BUG(cjyar) The roster isn't actually updated when things change. |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
330 |
|
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
331 |
// Returns the current roster of other entities which this one has a |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
332 |
// relationship with. Changes to the roster will be signaled by an |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
333 |
// appropriate Iq appearing on Client.In. See RFC 3921, Section 7.4. |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
334 |
func (cl *Client) Roster() map[string] *RosterItem { |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
335 |
r := make(map[string] *RosterItem) |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
336 |
for key, val := range(cl.roster) { |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
337 |
r[key] = val |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
338 |
} |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
339 |
return r |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
340 |
} |