author | Chris Jones <chris@cjones.org> |
Sun, 01 Jan 2012 19:32:51 -0700 | |
changeset 46 | 4a4530b8f622 |
parent 45 | abf958bcc201 |
child 48 | 6b402eb552f5 |
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 |
||
27 |
// Various XML namespaces. |
|
34
7b1f924c75e2
Made the namespace constants public.
Chris Jones <chris@cjones.org>
parents:
33
diff
changeset
|
28 |
NsStreams = "urn:ietf:params:xml:ns:xmpp-streams" |
7b1f924c75e2
Made the namespace constants public.
Chris Jones <chris@cjones.org>
parents:
33
diff
changeset
|
29 |
NsStream = "http://etherx.jabber.org/streams" |
7b1f924c75e2
Made the namespace constants public.
Chris Jones <chris@cjones.org>
parents:
33
diff
changeset
|
30 |
NsTLS = "urn:ietf:params:xml:ns:xmpp-tls" |
7b1f924c75e2
Made the namespace constants public.
Chris Jones <chris@cjones.org>
parents:
33
diff
changeset
|
31 |
NsSASL = "urn:ietf:params:xml:ns:xmpp-sasl" |
7b1f924c75e2
Made the namespace constants public.
Chris Jones <chris@cjones.org>
parents:
33
diff
changeset
|
32 |
NsBind = "urn:ietf:params:xml:ns:xmpp-bind" |
7b1f924c75e2
Made the namespace constants public.
Chris Jones <chris@cjones.org>
parents:
33
diff
changeset
|
33 |
NsSession = "urn:ietf:params:xml:ns:xmpp-session" |
33
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
34 |
NsRoster = "jabber:iq:roster" |
10 | 35 |
|
36 |
// 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
|
37 |
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
|
38 |
clientSrv = "xmpp-client" |
10 | 39 |
|
20
e119444a1119
Replaced TODO comments with Go-style BUG(me) comments.
Chris Jones <chris@cjones.org>
parents:
17
diff
changeset
|
40 |
// BUG(cjyar) Make this a parameter to NewClient, not a |
17 | 41 |
// constant. We should have both a log level and a |
42 |
// syslog.Writer, so the app can control how much time we |
|
43 |
// spend generating log messages, as well as where they go. |
|
10 | 44 |
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
|
45 |
) |
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 |
// 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
|
48 |
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
|
49 |
// 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
|
50 |
// the time StartSession() returns. |
10 | 51 |
Jid JID |
11
48be1ae93fd4
Added SASL digest authentication.
Chris Jones <chris@cjones.org>
parents:
10
diff
changeset
|
52 |
password string |
10 | 53 |
socket net.Conn |
54 |
socketSync sync.WaitGroup |
|
11
48be1ae93fd4
Added SASL digest authentication.
Chris Jones <chris@cjones.org>
parents:
10
diff
changeset
|
55 |
saslExpected string |
12
122ab6208c3c
Added resource binding and structures for <iq>, <message>, and <presence>.
Chris Jones <chris@cjones.org>
parents:
11
diff
changeset
|
56 |
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
|
57 |
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
|
58 |
inputControl chan int |
30
a77fc342e013
Replaced Client.NextId() with a channel named Id.
Chris Jones <chris@cjones.org>
parents:
29
diff
changeset
|
59 |
// 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
|
60 |
// 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
|
61 |
Id <-chan string |
17 | 62 |
// Incoming XMPP stanzas from the server will be published on |
63 |
// this channel. Information which is only used by this |
|
64 |
// 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
|
65 |
In <-chan Stanza |
17 | 66 |
// Outgoing XMPP stanzas to the server should be sent to this |
67 |
// channel. |
|
23
b5de44679389
Made the input and output channels of type Stanza rather than
Chris Jones <chris@cjones.org>
parents:
22
diff
changeset
|
68 |
Out chan<- Stanza |
10 | 69 |
xmlOut chan<- interface{} |
32
4e68d8f89dc3
Make the server's advertised features available to the app.
Chris Jones <chris@cjones.org>
parents:
30
diff
changeset
|
70 |
// 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
|
71 |
// 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
|
72 |
// 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
|
73 |
// StartSession() returns. |
4e68d8f89dc3
Make the server's advertised features available to the app.
Chris Jones <chris@cjones.org>
parents:
30
diff
changeset
|
74 |
Features *Features |
33
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
75 |
roster map[string] *RosterItem |
45
abf958bcc201
Added a stack of filters which can intercept data before it gets to
Chris Jones <chris@cjones.org>
parents:
44
diff
changeset
|
76 |
filterOut chan<- <-chan Stanza |
abf958bcc201
Added a stack of filters which can intercept data before it gets to
Chris Jones <chris@cjones.org>
parents:
44
diff
changeset
|
77 |
filterIn <-chan <-chan Stanza |
2
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
78 |
} |
4
a8fbec71a194
Added an interactive test and made Client implement io.Closer.
Chris Jones <chris@cjones.org>
parents:
2
diff
changeset
|
79 |
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
|
80 |
|
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
81 |
// Connect to the appropriate server and authenticate as the given JID |
17 | 82 |
// with the given password. This function will return as soon as a TCP |
83 |
// connection has been established, but before XMPP stream negotiation |
|
27 | 84 |
// has completed. The negotiation will occur asynchronously, and any |
85 |
// send operation to Client.Out will block until negotiation (resource |
|
86 |
// binding) is complete. |
|
36
9fe022261dcc
Added a capability to use extensions. There are still some bugs with
Chris Jones <chris@cjones.org>
parents:
34
diff
changeset
|
87 |
func NewClient(jid *JID, password string, |
38 | 88 |
extStanza map[string] func(*xml.Name) interface{}) (*Client, os.Error) { |
2
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
89 |
// 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
|
90 |
_, 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
|
91 |
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
|
92 |
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
|
93 |
": " + 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
|
94 |
} |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
95 |
|
9
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
96 |
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
|
97 |
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
|
98 |
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
|
99 |
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
|
100 |
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
|
101 |
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
|
102 |
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
|
103 |
continue |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
104 |
} |
9
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
105 |
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
|
106 |
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
|
107 |
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
|
108 |
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
|
109 |
continue |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
110 |
} |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
111 |
} |
9
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
112 |
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
|
113 |
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
|
114 |
} |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
115 |
|
10 | 116 |
cl := new(Client) |
11
48be1ae93fd4
Added SASL digest authentication.
Chris Jones <chris@cjones.org>
parents:
10
diff
changeset
|
117 |
cl.password = password |
10 | 118 |
cl.Jid = *jid |
119 |
cl.socket = tcp |
|
33
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
120 |
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
|
121 |
cl.inputControl = make(chan int) |
30
a77fc342e013
Replaced Client.NextId() with a channel named Id.
Chris Jones <chris@cjones.org>
parents:
29
diff
changeset
|
122 |
idCh := make(chan string) |
a77fc342e013
Replaced Client.NextId() with a channel named Id.
Chris Jones <chris@cjones.org>
parents:
29
diff
changeset
|
123 |
cl.Id = idCh |
a77fc342e013
Replaced Client.NextId() with a channel named Id.
Chris Jones <chris@cjones.org>
parents:
29
diff
changeset
|
124 |
|
36
9fe022261dcc
Added a capability to use extensions. There are still some bugs with
Chris Jones <chris@cjones.org>
parents:
34
diff
changeset
|
125 |
if extStanza == nil { |
38 | 126 |
extStanza = make(map[string] func(*xml.Name) interface{}) |
36
9fe022261dcc
Added a capability to use extensions. There are still some bugs with
Chris Jones <chris@cjones.org>
parents:
34
diff
changeset
|
127 |
} |
38 | 128 |
extStanza[NsRoster] = newRosterQuery |
41
c8c9e6a7e6c9
Made a special-purpose bind structure for resource binding.
Chris Jones <chris@cjones.org>
parents:
38
diff
changeset
|
129 |
extStanza[NsBind] = newBind |
36
9fe022261dcc
Added a capability to use extensions. There are still some bugs with
Chris Jones <chris@cjones.org>
parents:
34
diff
changeset
|
130 |
|
30
a77fc342e013
Replaced Client.NextId() with a channel named Id.
Chris Jones <chris@cjones.org>
parents:
29
diff
changeset
|
131 |
// Start the unique id generator. |
a77fc342e013
Replaced Client.NextId() with a channel named Id.
Chris Jones <chris@cjones.org>
parents:
29
diff
changeset
|
132 |
go makeIds(idCh) |
10 | 133 |
|
9
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
134 |
// Start the transport handler, initially unencrypted. |
10 | 135 |
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
|
136 |
|
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
137 |
// Start the reader and writers that convert to and from XML. |
36
9fe022261dcc
Added a capability to use extensions. There are still some bugs with
Chris Jones <chris@cjones.org>
parents:
34
diff
changeset
|
138 |
xmlIn := startXmlReader(tlsr, extStanza) |
10 | 139 |
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
|
140 |
|
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
141 |
// 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
|
142 |
// events and responds to them. |
45
abf958bcc201
Added a stack of filters which can intercept data before it gets to
Chris Jones <chris@cjones.org>
parents:
44
diff
changeset
|
143 |
stIn := 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
|
144 |
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
|
145 |
|
45
abf958bcc201
Added a stack of filters which can intercept data before it gets to
Chris Jones <chris@cjones.org>
parents:
44
diff
changeset
|
146 |
// Start the manager for the filters that can modify what the |
abf958bcc201
Added a stack of filters which can intercept data before it gets to
Chris Jones <chris@cjones.org>
parents:
44
diff
changeset
|
147 |
// app sees. |
abf958bcc201
Added a stack of filters which can intercept data before it gets to
Chris Jones <chris@cjones.org>
parents:
44
diff
changeset
|
148 |
clIn := cl.startFilter(stIn) |
46 | 149 |
cl.startRosterFilter() |
45
abf958bcc201
Added a stack of filters which can intercept data before it gets to
Chris Jones <chris@cjones.org>
parents:
44
diff
changeset
|
150 |
|
8
30a7752cf8f7
Added the ability to parse <stream:features>.
Chris Jones <chris@cjones.org>
parents:
6
diff
changeset
|
151 |
// Initial handshake. |
22
d6b7b4cbf50d
Made the stream type non-public.
Chris Jones <chris@cjones.org>
parents:
20
diff
changeset
|
152 |
hsOut := &stream{To: jid.Domain, Version: Version} |
10 | 153 |
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
|
154 |
|
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
155 |
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
|
156 |
cl.Out = clOut |
8
30a7752cf8f7
Added the ability to parse <stream:features>.
Chris Jones <chris@cjones.org>
parents:
6
diff
changeset
|
157 |
|
6
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
158 |
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
|
159 |
} |
4
a8fbec71a194
Added an interactive test and made Client implement io.Closer.
Chris Jones <chris@cjones.org>
parents:
2
diff
changeset
|
160 |
|
a8fbec71a194
Added an interactive test and made Client implement io.Closer.
Chris Jones <chris@cjones.org>
parents:
2
diff
changeset
|
161 |
func (c *Client) Close() os.Error { |
26 | 162 |
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
|
163 |
return nil |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
164 |
} |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
165 |
|
10 | 166 |
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
|
167 |
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
|
168 |
outr, outw := io.Pipe() |
10 | 169 |
go cl.readTransport(inw) |
170 |
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
|
171 |
return inr, outw |
4
a8fbec71a194
Added an interactive test and made Client implement io.Closer.
Chris Jones <chris@cjones.org>
parents:
2
diff
changeset
|
172 |
} |
5
faef59c8db05
Added a goroutine to read data from the remote and parse it into
Chris Jones <chris@cjones.org>
parents:
4
diff
changeset
|
173 |
|
36
9fe022261dcc
Added a capability to use extensions. There are still some bugs with
Chris Jones <chris@cjones.org>
parents:
34
diff
changeset
|
174 |
func startXmlReader(r io.Reader, |
38 | 175 |
extStanza map[string] func(*xml.Name) interface{}) <-chan interface{} { |
9
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
176 |
ch := make(chan interface{}) |
36
9fe022261dcc
Added a capability to use extensions. There are still some bugs with
Chris Jones <chris@cjones.org>
parents:
34
diff
changeset
|
177 |
go readXml(r, ch, extStanza) |
9
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
178 |
return ch |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
179 |
} |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
180 |
|
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
181 |
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
|
182 |
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
|
183 |
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
|
184 |
return ch |
6
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
185 |
} |
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
186 |
|
23
b5de44679389
Made the input and output channels of type Stanza rather than
Chris Jones <chris@cjones.org>
parents:
22
diff
changeset
|
187 |
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
|
188 |
ch := make(chan Stanza) |
11
48be1ae93fd4
Added SASL digest authentication.
Chris Jones <chris@cjones.org>
parents:
10
diff
changeset
|
189 |
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
|
190 |
return ch |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
191 |
} |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
192 |
|
29
a456133ed0ac
Don't accept data on Client.Out until resource binding is
Chris Jones <chris@cjones.org>
parents:
28
diff
changeset
|
193 |
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
|
194 |
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
|
195 |
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
|
196 |
return ch |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
197 |
} |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
198 |
|
45
abf958bcc201
Added a stack of filters which can intercept data before it gets to
Chris Jones <chris@cjones.org>
parents:
44
diff
changeset
|
199 |
func (cl *Client) startFilter(srvIn <-chan Stanza) <-chan Stanza { |
abf958bcc201
Added a stack of filters which can intercept data before it gets to
Chris Jones <chris@cjones.org>
parents:
44
diff
changeset
|
200 |
cliOut := make(chan Stanza) |
abf958bcc201
Added a stack of filters which can intercept data before it gets to
Chris Jones <chris@cjones.org>
parents:
44
diff
changeset
|
201 |
filterOut := make(chan (<-chan Stanza)) |
abf958bcc201
Added a stack of filters which can intercept data before it gets to
Chris Jones <chris@cjones.org>
parents:
44
diff
changeset
|
202 |
filterIn := make(chan (<-chan Stanza)) |
abf958bcc201
Added a stack of filters which can intercept data before it gets to
Chris Jones <chris@cjones.org>
parents:
44
diff
changeset
|
203 |
go filter(srvIn, cliOut, filterOut, filterIn) |
46 | 204 |
cl.filterOut = filterOut |
205 |
cl.filterIn = filterIn |
|
45
abf958bcc201
Added a stack of filters which can intercept data before it gets to
Chris Jones <chris@cjones.org>
parents:
44
diff
changeset
|
206 |
return cliOut |
abf958bcc201
Added a stack of filters which can intercept data before it gets to
Chris Jones <chris@cjones.org>
parents:
44
diff
changeset
|
207 |
} |
abf958bcc201
Added a stack of filters which can intercept data before it gets to
Chris Jones <chris@cjones.org>
parents:
44
diff
changeset
|
208 |
|
6
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
209 |
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
|
210 |
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
|
211 |
|
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
212 |
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
|
213 |
for { |
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
214 |
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
|
215 |
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
|
216 |
if n == 0 { |
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
217 |
break |
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
218 |
} |
9
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
219 |
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
|
220 |
if n == 0 { |
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
221 |
break |
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
222 |
} |
9
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
223 |
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
|
224 |
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
|
225 |
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
|
226 |
buf.Reset() |
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
227 |
} |
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
228 |
} |
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
229 |
leftover := buf.String() |
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
230 |
if leftover != "" { |
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
231 |
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
|
232 |
} |
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
233 |
} |
9
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
234 |
|
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
235 |
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
|
236 |
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
|
237 |
defer func() { |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
238 |
recover() |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
239 |
}() |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
240 |
close(ch) |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
241 |
} |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
242 |
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
|
243 |
defer func() { |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
244 |
recover() |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
245 |
}() |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
246 |
close(ch) |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
247 |
} |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
248 |
|
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
249 |
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
|
250 |
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
|
251 |
c.Close() |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
252 |
} 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
|
253 |
f1(ch) |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
254 |
} 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
|
255 |
f2(ch) |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
256 |
} |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
257 |
} |
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
258 |
} |
12
122ab6208c3c
Added resource binding and structures for <iq>, <message>, and <presence>.
Chris Jones <chris@cjones.org>
parents:
11
diff
changeset
|
259 |
|
30
a77fc342e013
Replaced Client.NextId() with a channel named Id.
Chris Jones <chris@cjones.org>
parents:
29
diff
changeset
|
260 |
func makeIds(ch chan<- string) { |
a77fc342e013
Replaced Client.NextId() with a channel named Id.
Chris Jones <chris@cjones.org>
parents:
29
diff
changeset
|
261 |
id := int64(1) |
a77fc342e013
Replaced Client.NextId() with a channel named Id.
Chris Jones <chris@cjones.org>
parents:
29
diff
changeset
|
262 |
for { |
a77fc342e013
Replaced Client.NextId() with a channel named Id.
Chris Jones <chris@cjones.org>
parents:
29
diff
changeset
|
263 |
str := fmt.Sprintf("id_%d", id) |
a77fc342e013
Replaced Client.NextId() with a channel named Id.
Chris Jones <chris@cjones.org>
parents:
29
diff
changeset
|
264 |
ch <- str |
a77fc342e013
Replaced Client.NextId() with a channel named Id.
Chris Jones <chris@cjones.org>
parents:
29
diff
changeset
|
265 |
id++ |
a77fc342e013
Replaced Client.NextId() with a channel named Id.
Chris Jones <chris@cjones.org>
parents:
29
diff
changeset
|
266 |
} |
12
122ab6208c3c
Added resource binding and structures for <iq>, <message>, and <presence>.
Chris Jones <chris@cjones.org>
parents:
11
diff
changeset
|
267 |
} |
28 | 268 |
|
29
a456133ed0ac
Don't accept data on Client.Out until resource binding is
Chris Jones <chris@cjones.org>
parents:
28
diff
changeset
|
269 |
// 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
|
270 |
// 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
|
271 |
// 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
|
272 |
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
|
273 |
cl.inputControl <- 1 |
a456133ed0ac
Don't accept data on Client.Out until resource binding is
Chris Jones <chris@cjones.org>
parents:
28
diff
changeset
|
274 |
} |
a456133ed0ac
Don't accept data on Client.Out until resource binding is
Chris Jones <chris@cjones.org>
parents:
28
diff
changeset
|
275 |
|
33
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
276 |
// 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
|
277 |
// 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
|
278 |
// session, retrieve the roster, and broadcast an initial |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
279 |
// 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
|
280 |
// Presence struct. See RFC 3921, Section 3. |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
281 |
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
|
282 |
id := <- cl.Id |
28 | 283 |
iq := &Iq{To: cl.Jid.Domain, Id: id, Type: "set", Any: |
34
7b1f924c75e2
Made the namespace constants public.
Chris Jones <chris@cjones.org>
parents:
33
diff
changeset
|
284 |
&Generic{XMLName: xml.Name{Space: NsSession, Local: |
28 | 285 |
"session"}}} |
286 |
ch := make(chan os.Error) |
|
287 |
f := func(st Stanza) bool { |
|
42
f6bb47ca12f2
Renamed the somewhat obscure XTo(), etc. to GetTo(), etc.
Chris Jones <chris@cjones.org>
parents:
41
diff
changeset
|
288 |
if st.GetType() == "error" { |
28 | 289 |
log.Printf("Can't start session: %v", st) |
42
f6bb47ca12f2
Renamed the somewhat obscure XTo(), etc. to GetTo(), etc.
Chris Jones <chris@cjones.org>
parents:
41
diff
changeset
|
290 |
ch <- st.GetError() |
28 | 291 |
return false |
292 |
} |
|
293 |
ch <- nil |
|
294 |
return false |
|
295 |
} |
|
296 |
cl.HandleStanza(id, f) |
|
297 |
cl.Out <- iq |
|
33
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
298 |
|
28 | 299 |
// Now wait until the callback is called. |
33
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
300 |
if err := <- ch ; err != nil { |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
301 |
return err |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
302 |
} |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
303 |
if getRoster { |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
304 |
err := cl.fetchRoster() |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
305 |
if err != nil { |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
306 |
return err |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
307 |
} |
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 |
if pr != nil { |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
310 |
cl.Out <- pr |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
311 |
} |
571713f49494
Added roster retrieval to StartSession().
Chris Jones <chris@cjones.org>
parents:
32
diff
changeset
|
312 |
return nil |
28 | 313 |
} |
45
abf958bcc201
Added a stack of filters which can intercept data before it gets to
Chris Jones <chris@cjones.org>
parents:
44
diff
changeset
|
314 |
|
abf958bcc201
Added a stack of filters which can intercept data before it gets to
Chris Jones <chris@cjones.org>
parents:
44
diff
changeset
|
315 |
// AddFilter adds a new filter to the top of the stack through which |
abf958bcc201
Added a stack of filters which can intercept data before it gets to
Chris Jones <chris@cjones.org>
parents:
44
diff
changeset
|
316 |
// incoming stanzas travel on their way up to the client. The new |
abf958bcc201
Added a stack of filters which can intercept data before it gets to
Chris Jones <chris@cjones.org>
parents:
44
diff
changeset
|
317 |
// filter's output channel is given to this function, and it returns a |
abf958bcc201
Added a stack of filters which can intercept data before it gets to
Chris Jones <chris@cjones.org>
parents:
44
diff
changeset
|
318 |
// new input channel which the filter should read from. When its input |
abf958bcc201
Added a stack of filters which can intercept data before it gets to
Chris Jones <chris@cjones.org>
parents:
44
diff
changeset
|
319 |
// channel closes, the filter should close its output channel. |
abf958bcc201
Added a stack of filters which can intercept data before it gets to
Chris Jones <chris@cjones.org>
parents:
44
diff
changeset
|
320 |
func (cl *Client) AddFilter(out <-chan Stanza) <-chan Stanza { |
abf958bcc201
Added a stack of filters which can intercept data before it gets to
Chris Jones <chris@cjones.org>
parents:
44
diff
changeset
|
321 |
cl.filterOut <- out |
abf958bcc201
Added a stack of filters which can intercept data before it gets to
Chris Jones <chris@cjones.org>
parents:
44
diff
changeset
|
322 |
return <- cl.filterIn |
abf958bcc201
Added a stack of filters which can intercept data before it gets to
Chris Jones <chris@cjones.org>
parents:
44
diff
changeset
|
323 |
} |