author | Chris Jones <chris@cjones.org> |
Sun, 29 Sep 2013 21:55:08 -0600 | |
changeset 160 | ba2428230f71 |
parent 158 | 2d948fcbb5d7 |
child 162 | 7b5586a5e109 |
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 |
// This package implements a simple XMPP client according to RFCs 3920 |
119
712aa5780660
Documentation cleanup.
Chris Jones <christian.jones@sri.com>
parents:
118
diff
changeset
|
2 |
// and 3921, plus the various XEPs at http://xmpp.org/protocols/. The |
712aa5780660
Documentation cleanup.
Chris Jones <christian.jones@sri.com>
parents:
118
diff
changeset
|
3 |
// implementation is structured as a stack of layers, with TCP at the |
712aa5780660
Documentation cleanup.
Chris Jones <christian.jones@sri.com>
parents:
118
diff
changeset
|
4 |
// bottom and the application at the top. The application receives and |
712aa5780660
Documentation cleanup.
Chris Jones <christian.jones@sri.com>
parents:
118
diff
changeset
|
5 |
// sends structures representing XMPP stanzas. Additional stanza |
712aa5780660
Documentation cleanup.
Chris Jones <christian.jones@sri.com>
parents:
118
diff
changeset
|
6 |
// parsers can be inserted into the stack of layers as extensions. |
2
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 |
|
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
9 |
import ( |
6
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
10 |
"bytes" |
105
aa895dfae3f6
Allow the user to override the TLS config. Also fixed up some log statements.
Chris Jones <christian.jones@sri.com>
parents:
102
diff
changeset
|
11 |
"crypto/tls" |
98
c9cc4eda6dce
Updated for Go 1.0 + upcoming XML fixes.
Chris Jones <chris@cjones.org>
parents:
72
diff
changeset
|
12 |
"encoding/xml" |
c9cc4eda6dce
Updated for Go 1.0 + upcoming XML fixes.
Chris Jones <chris@cjones.org>
parents:
72
diff
changeset
|
13 |
"errors" |
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" |
2
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
16 |
"net" |
128
8342afcffc92
Use reflection instead of constructor functions to create extended stanza structures.
Chris Jones <christian.jones@sri.com>
parents:
127
diff
changeset
|
17 |
"reflect" |
2
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
18 |
) |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
19 |
|
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
20 |
const ( |
10 | 21 |
// Version of RFC 3920 that we implement. |
118
fb9bb98a8d70
Code cleanup: Renamed the Version constant. Moved the unique-ID generator into its own file.
Chris Jones <christian.jones@sri.com>
parents:
116
diff
changeset
|
22 |
XMPPVersion = "1.0" |
10 | 23 |
|
24 |
// Various XML namespaces. |
|
98
c9cc4eda6dce
Updated for Go 1.0 + upcoming XML fixes.
Chris Jones <chris@cjones.org>
parents:
72
diff
changeset
|
25 |
NsClient = "jabber:client" |
34
7b1f924c75e2
Made the namespace constants public.
Chris Jones <chris@cjones.org>
parents:
33
diff
changeset
|
26 |
NsStreams = "urn:ietf:params:xml:ns:xmpp-streams" |
72 | 27 |
NsStream = "http://etherx.jabber.org/streams" |
28 |
NsTLS = "urn:ietf:params:xml:ns:xmpp-tls" |
|
29 |
NsSASL = "urn:ietf:params:xml:ns:xmpp-sasl" |
|
30 |
NsBind = "urn:ietf:params:xml:ns:xmpp-bind" |
|
34
7b1f924c75e2
Made the namespace constants public.
Chris Jones <chris@cjones.org>
parents:
33
diff
changeset
|
31 |
NsSession = "urn:ietf:params:xml:ns:xmpp-session" |
72 | 32 |
NsRoster = "jabber:iq:roster" |
10 | 33 |
|
34 |
// 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
|
35 |
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
|
36 |
clientSrv = "xmpp-client" |
62
6e2eea62ccca
Added global variables for logging.
Chris Jones <chris@cjones.org>
parents:
61
diff
changeset
|
37 |
) |
10 | 38 |
|
153
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
39 |
// Status of the connection. |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
40 |
type Status int |
148
b1b4900eee5b
Made layers 1 and 3 more modular, shrinking the surface area of the coupling between them.
Chris Jones <christian.jones@sri.com>
parents:
147
diff
changeset
|
41 |
|
b1b4900eee5b
Made layers 1 and 3 more modular, shrinking the surface area of the coupling between them.
Chris Jones <christian.jones@sri.com>
parents:
147
diff
changeset
|
42 |
const ( |
153
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
43 |
statusUnconnected = iota |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
44 |
statusConnected |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
45 |
statusConnectedTls |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
46 |
statusAuthenticated |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
47 |
statusBound |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
48 |
statusRunning |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
49 |
statusShutdown |
148
b1b4900eee5b
Made layers 1 and 3 more modular, shrinking the surface area of the coupling between them.
Chris Jones <christian.jones@sri.com>
parents:
147
diff
changeset
|
50 |
) |
146
aa9a0ae8f875
Changed the inputControl channel to send a custom type.
Chris Jones <christian.jones@sri.com>
parents:
144
diff
changeset
|
51 |
|
aa9a0ae8f875
Changed the inputControl channel to send a custom type.
Chris Jones <christian.jones@sri.com>
parents:
144
diff
changeset
|
52 |
var ( |
153
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
53 |
// The client has not yet connected, or it has been |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
54 |
// disconnected from the server. |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
55 |
StatusUnconnected Status = statusUnconnected |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
56 |
// Initial connection established. |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
57 |
StatusConnected Status = statusConnected |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
58 |
// Like StatusConnected, but with TLS. |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
59 |
StatusConnectedTls Status = statusConnectedTls |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
60 |
// Authentication succeeded. |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
61 |
StatusAuthenticated Status = statusAuthenticated |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
62 |
// Resource binding complete. |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
63 |
StatusBound Status = statusBound |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
64 |
// Session has started and normal message traffic can be sent |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
65 |
// and received. |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
66 |
StatusRunning Status = statusRunning |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
67 |
// The session has closed, or is in the process of closing. |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
68 |
StatusShutdown Status = statusShutdown |
146
aa9a0ae8f875
Changed the inputControl channel to send a custom type.
Chris Jones <christian.jones@sri.com>
parents:
144
diff
changeset
|
69 |
) |
aa9a0ae8f875
Changed the inputControl channel to send a custom type.
Chris Jones <christian.jones@sri.com>
parents:
144
diff
changeset
|
70 |
|
121
ebb86cbdd218
Changed the way filters work. They're now symmetrical, consisting of a paired send filter and receive filter.
Chris Jones <christian.jones@sri.com>
parents:
120
diff
changeset
|
71 |
// A filter can modify the XMPP traffic to or from the remote |
ebb86cbdd218
Changed the way filters work. They're now symmetrical, consisting of a paired send filter and receive filter.
Chris Jones <christian.jones@sri.com>
parents:
120
diff
changeset
|
72 |
// server. It's part of an Extension. The filter function will be |
ebb86cbdd218
Changed the way filters work. They're now symmetrical, consisting of a paired send filter and receive filter.
Chris Jones <christian.jones@sri.com>
parents:
120
diff
changeset
|
73 |
// called in a new goroutine, so it doesn't need to return. The filter |
ebb86cbdd218
Changed the way filters work. They're now symmetrical, consisting of a paired send filter and receive filter.
Chris Jones <christian.jones@sri.com>
parents:
120
diff
changeset
|
74 |
// should close its output when its input is closed. |
ebb86cbdd218
Changed the way filters work. They're now symmetrical, consisting of a paired send filter and receive filter.
Chris Jones <christian.jones@sri.com>
parents:
120
diff
changeset
|
75 |
type Filter func(in <-chan Stanza, out chan<- Stanza) |
ebb86cbdd218
Changed the way filters work. They're now symmetrical, consisting of a paired send filter and receive filter.
Chris Jones <christian.jones@sri.com>
parents:
120
diff
changeset
|
76 |
|
60
6d4f43f7dc19
Made a generic extension interface.
Chris Jones <chris@cjones.org>
parents:
59
diff
changeset
|
77 |
// Extensions can add stanza filters and/or new XML element types. |
6d4f43f7dc19
Made a generic extension interface.
Chris Jones <chris@cjones.org>
parents:
59
diff
changeset
|
78 |
type Extension struct { |
158
2d948fcbb5d7
Renamed Extension.StanzaHandlers to StanzaTypes, and updated the doc comment.
Chris Jones <chris@cjones.org>
parents:
157
diff
changeset
|
79 |
// Maps from an XML name to a structure which holds stanza |
2d948fcbb5d7
Renamed Extension.StanzaHandlers to StanzaTypes, and updated the doc comment.
Chris Jones <chris@cjones.org>
parents:
157
diff
changeset
|
80 |
// contents with that name. |
2d948fcbb5d7
Renamed Extension.StanzaHandlers to StanzaTypes, and updated the doc comment.
Chris Jones <chris@cjones.org>
parents:
157
diff
changeset
|
81 |
StanzaTypes map[xml.Name]reflect.Type |
121
ebb86cbdd218
Changed the way filters work. They're now symmetrical, consisting of a paired send filter and receive filter.
Chris Jones <christian.jones@sri.com>
parents:
120
diff
changeset
|
82 |
// If non-nil, will be called once to start the filter |
ebb86cbdd218
Changed the way filters work. They're now symmetrical, consisting of a paired send filter and receive filter.
Chris Jones <christian.jones@sri.com>
parents:
120
diff
changeset
|
83 |
// running. RecvFilter intercepts incoming messages on their |
ebb86cbdd218
Changed the way filters work. They're now symmetrical, consisting of a paired send filter and receive filter.
Chris Jones <christian.jones@sri.com>
parents:
120
diff
changeset
|
84 |
// way from the remote server to the application; SendFilter |
ebb86cbdd218
Changed the way filters work. They're now symmetrical, consisting of a paired send filter and receive filter.
Chris Jones <christian.jones@sri.com>
parents:
120
diff
changeset
|
85 |
// intercepts messages going the other direction. |
ebb86cbdd218
Changed the way filters work. They're now symmetrical, consisting of a paired send filter and receive filter.
Chris Jones <christian.jones@sri.com>
parents:
120
diff
changeset
|
86 |
RecvFilter Filter |
ebb86cbdd218
Changed the way filters work. They're now symmetrical, consisting of a paired send filter and receive filter.
Chris Jones <christian.jones@sri.com>
parents:
120
diff
changeset
|
87 |
SendFilter Filter |
60
6d4f43f7dc19
Made a generic extension interface.
Chris Jones <chris@cjones.org>
parents:
59
diff
changeset
|
88 |
} |
6d4f43f7dc19
Made a generic extension interface.
Chris Jones <chris@cjones.org>
parents:
59
diff
changeset
|
89 |
|
2
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
90 |
// 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
|
91 |
type Client struct { |
153
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
92 |
// This client's full JID, including resource |
72 | 93 |
Jid JID |
94 |
password string |
|
11
48be1ae93fd4
Added SASL digest authentication.
Chris Jones <chris@cjones.org>
parents:
10
diff
changeset
|
95 |
saslExpected string |
72 | 96 |
authDone bool |
144
9d7fdb1d2fc1
Renamed HandleStanza to SetCallback.
Chris Jones <christian.jones@sri.com>
parents:
142
diff
changeset
|
97 |
handlers chan *callback |
119
712aa5780660
Documentation cleanup.
Chris Jones <christian.jones@sri.com>
parents:
118
diff
changeset
|
98 |
// Incoming XMPP stanzas from the remote will be published on |
712aa5780660
Documentation cleanup.
Chris Jones <christian.jones@sri.com>
parents:
118
diff
changeset
|
99 |
// this channel. Information which is used by this library to |
712aa5780660
Documentation cleanup.
Chris Jones <christian.jones@sri.com>
parents:
118
diff
changeset
|
100 |
// set up the XMPP stream will not appear here. |
127
a8f9a0c07fc8
Renamed client.In and client.Out to Recv and Send, respectively.
Chris Jones <christian.jones@sri.com>
parents:
126
diff
changeset
|
101 |
Recv <-chan Stanza |
17 | 102 |
// Outgoing XMPP stanzas to the server should be sent to this |
103 |
// channel. |
|
127
a8f9a0c07fc8
Renamed client.In and client.Out to Recv and Send, respectively.
Chris Jones <christian.jones@sri.com>
parents:
126
diff
changeset
|
104 |
Send chan<- Stanza |
a8f9a0c07fc8
Renamed client.In and client.Out to Recv and Send, respectively.
Chris Jones <christian.jones@sri.com>
parents:
126
diff
changeset
|
105 |
sendXml chan<- interface{} |
153
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
106 |
statmgr *statmgr |
121
ebb86cbdd218
Changed the way filters work. They're now symmetrical, consisting of a paired send filter and receive filter.
Chris Jones <christian.jones@sri.com>
parents:
120
diff
changeset
|
107 |
// The client's roster is also known as the buddy list. It's |
ebb86cbdd218
Changed the way filters work. They're now symmetrical, consisting of a paired send filter and receive filter.
Chris Jones <christian.jones@sri.com>
parents:
120
diff
changeset
|
108 |
// the set of contacts which are known to this JID, or which |
ebb86cbdd218
Changed the way filters work. They're now symmetrical, consisting of a paired send filter and receive filter.
Chris Jones <christian.jones@sri.com>
parents:
120
diff
changeset
|
109 |
// this JID is known to. |
ebb86cbdd218
Changed the way filters work. They're now symmetrical, consisting of a paired send filter and receive filter.
Chris Jones <christian.jones@sri.com>
parents:
120
diff
changeset
|
110 |
Roster Roster |
153
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
111 |
// Features advertised by the remote. |
128
8342afcffc92
Use reflection instead of constructor functions to create extended stanza structures.
Chris Jones <christian.jones@sri.com>
parents:
127
diff
changeset
|
112 |
Features *Features |
121
ebb86cbdd218
Changed the way filters work. They're now symmetrical, consisting of a paired send filter and receive filter.
Chris Jones <christian.jones@sri.com>
parents:
120
diff
changeset
|
113 |
sendFilterAdd, recvFilterAdd chan Filter |
153
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
114 |
tlsConfig tls.Config |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
115 |
layer1 *layer1 |
2
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
116 |
} |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
117 |
|
153
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
118 |
// Creates an XMPP client identified by the given JID, authenticating |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
119 |
// with the provided password and TLS config. Zero or more extensions |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
120 |
// may be specified. The initial presence will be broadcast. If status |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
121 |
// is non-nil, connection progress information will be sent on it. |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
122 |
func NewClient(jid *JID, password string, tlsconf tls.Config, exts []Extension, |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
123 |
pr Presence, status chan<- Status) (*Client, error) { |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
124 |
|
60
6d4f43f7dc19
Made a generic extension interface.
Chris Jones <chris@cjones.org>
parents:
59
diff
changeset
|
125 |
// Include the mandatory extensions. |
121
ebb86cbdd218
Changed the way filters work. They're now symmetrical, consisting of a paired send filter and receive filter.
Chris Jones <christian.jones@sri.com>
parents:
120
diff
changeset
|
126 |
roster := newRosterExt() |
ebb86cbdd218
Changed the way filters work. They're now symmetrical, consisting of a paired send filter and receive filter.
Chris Jones <christian.jones@sri.com>
parents:
120
diff
changeset
|
127 |
exts = append(exts, roster.Extension) |
60
6d4f43f7dc19
Made a generic extension interface.
Chris Jones <chris@cjones.org>
parents:
59
diff
changeset
|
128 |
exts = append(exts, bindExt) |
6d4f43f7dc19
Made a generic extension interface.
Chris Jones <chris@cjones.org>
parents:
59
diff
changeset
|
129 |
|
153
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
130 |
cl := new(Client) |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
131 |
cl.Roster = *roster |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
132 |
cl.password = password |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
133 |
cl.Jid = *jid |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
134 |
cl.handlers = make(chan *callback, 100) |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
135 |
cl.tlsConfig = tlsconf |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
136 |
cl.sendFilterAdd = make(chan Filter) |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
137 |
cl.recvFilterAdd = make(chan Filter) |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
138 |
cl.statmgr = newStatmgr(status) |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
139 |
|
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
140 |
extStanza := make(map[xml.Name]reflect.Type) |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
141 |
for _, ext := range exts { |
158
2d948fcbb5d7
Renamed Extension.StanzaHandlers to StanzaTypes, and updated the doc comment.
Chris Jones <chris@cjones.org>
parents:
157
diff
changeset
|
142 |
for k, v := range ext.StanzaTypes { |
153
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
143 |
if _, ok := extStanza[k]; ok { |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
144 |
return nil, fmt.Errorf("duplicate handler %s", |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
145 |
k) |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
146 |
} |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
147 |
extStanza[k] = v |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
148 |
} |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
149 |
} |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
150 |
|
2
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
151 |
// 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
|
152 |
_, 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
|
153 |
if err != nil { |
131
f9ccfaf672ed
Address a bug that can happen if no SRV records can be found.
Chris Jones <christian.jones@sri.com>
parents:
130
diff
changeset
|
154 |
return nil, fmt.Errorf("LookupSrv %s: %v", jid.Domain, err) |
f9ccfaf672ed
Address a bug that can happen if no SRV records can be found.
Chris Jones <christian.jones@sri.com>
parents:
130
diff
changeset
|
155 |
} |
f9ccfaf672ed
Address a bug that can happen if no SRV records can be found.
Chris Jones <christian.jones@sri.com>
parents:
130
diff
changeset
|
156 |
if len(srvs) == 0 { |
f9ccfaf672ed
Address a bug that can happen if no SRV records can be found.
Chris Jones <christian.jones@sri.com>
parents:
130
diff
changeset
|
157 |
return nil, fmt.Errorf("LookupSrv %s: no results", jid.Domain) |
2
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
158 |
} |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
159 |
|
9
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
160 |
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
|
161 |
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
|
162 |
addrStr := fmt.Sprintf("%s:%d", srv.Target, srv.Port) |
135
a4755a42af19
Fixed another logic error, caused by a shadowed variable name.
Chris Jones <christian.jones@sri.com>
parents:
134
diff
changeset
|
163 |
var addr *net.TCPAddr |
a4755a42af19
Fixed another logic error, caused by a shadowed variable name.
Chris Jones <christian.jones@sri.com>
parents:
134
diff
changeset
|
164 |
addr, err = net.ResolveTCPAddr("tcp", addrStr) |
2
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
165 |
if err != nil { |
98
c9cc4eda6dce
Updated for Go 1.0 + upcoming XML fixes.
Chris Jones <chris@cjones.org>
parents:
72
diff
changeset
|
166 |
err = fmt.Errorf("ResolveTCPAddr(%s): %s", |
c9cc4eda6dce
Updated for Go 1.0 + upcoming XML fixes.
Chris Jones <chris@cjones.org>
parents:
72
diff
changeset
|
167 |
addrStr, err.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
|
168 |
continue |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
169 |
} |
9
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
170 |
tcp, err = net.DialTCP("tcp", nil, addr) |
135
a4755a42af19
Fixed another logic error, caused by a shadowed variable name.
Chris Jones <christian.jones@sri.com>
parents:
134
diff
changeset
|
171 |
if tcp != nil { |
120
9d7e8333948b
Fix a bug causing us to open a TCP connection to every server and use the last one.
Chris Jones <christian.jones@sri.com>
parents:
119
diff
changeset
|
172 |
break |
2
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
173 |
} |
4dabfef08c8c
Forgot to add the new xmpp.go from my last commit. Also added some
Chris Jones <chris@cjones.org>
parents:
diff
changeset
|
174 |
} |
9
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
175 |
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
|
176 |
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
|
177 |
} |
153
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
178 |
cl.setStatus(StatusConnected) |
36
9fe022261dcc
Added a capability to use extensions. There are still some bugs with
Chris Jones <chris@cjones.org>
parents:
34
diff
changeset
|
179 |
|
9
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
180 |
// Start the transport handler, initially unencrypted. |
121
ebb86cbdd218
Changed the way filters work. They're now symmetrical, consisting of a paired send filter and receive filter.
Chris Jones <christian.jones@sri.com>
parents:
120
diff
changeset
|
181 |
recvReader, recvWriter := io.Pipe() |
ebb86cbdd218
Changed the way filters work. They're now symmetrical, consisting of a paired send filter and receive filter.
Chris Jones <christian.jones@sri.com>
parents:
120
diff
changeset
|
182 |
sendReader, sendWriter := io.Pipe() |
153
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
183 |
cl.layer1 = startLayer1(tcp, recvWriter, sendReader, |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
184 |
cl.statmgr.newListener()) |
9
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
185 |
|
121
ebb86cbdd218
Changed the way filters work. They're now symmetrical, consisting of a paired send filter and receive filter.
Chris Jones <christian.jones@sri.com>
parents:
120
diff
changeset
|
186 |
// Start the reader and writer that convert to and from XML. |
147
d7679d991b17
Function renames and improved doc.
Chris Jones <christian.jones@sri.com>
parents:
146
diff
changeset
|
187 |
recvXmlCh := make(chan interface{}) |
d7679d991b17
Function renames and improved doc.
Chris Jones <christian.jones@sri.com>
parents:
146
diff
changeset
|
188 |
go recvXml(recvReader, recvXmlCh, extStanza) |
d7679d991b17
Function renames and improved doc.
Chris Jones <christian.jones@sri.com>
parents:
146
diff
changeset
|
189 |
sendXmlCh := make(chan interface{}) |
d7679d991b17
Function renames and improved doc.
Chris Jones <christian.jones@sri.com>
parents:
146
diff
changeset
|
190 |
cl.sendXml = sendXmlCh |
d7679d991b17
Function renames and improved doc.
Chris Jones <christian.jones@sri.com>
parents:
146
diff
changeset
|
191 |
go sendXml(sendWriter, sendXmlCh) |
121
ebb86cbdd218
Changed the way filters work. They're now symmetrical, consisting of a paired send filter and receive filter.
Chris Jones <christian.jones@sri.com>
parents:
120
diff
changeset
|
192 |
|
ebb86cbdd218
Changed the way filters work. They're now symmetrical, consisting of a paired send filter and receive filter.
Chris Jones <christian.jones@sri.com>
parents:
120
diff
changeset
|
193 |
// Start the reader and writer that convert between XML and |
ebb86cbdd218
Changed the way filters work. They're now symmetrical, consisting of a paired send filter and receive filter.
Chris Jones <christian.jones@sri.com>
parents:
120
diff
changeset
|
194 |
// XMPP stanzas. |
ebb86cbdd218
Changed the way filters work. They're now symmetrical, consisting of a paired send filter and receive filter.
Chris Jones <christian.jones@sri.com>
parents:
120
diff
changeset
|
195 |
recvRawXmpp := make(chan Stanza) |
153
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
196 |
go cl.recvStream(recvXmlCh, recvRawXmpp, cl.statmgr.newListener()) |
121
ebb86cbdd218
Changed the way filters work. They're now symmetrical, consisting of a paired send filter and receive filter.
Chris Jones <christian.jones@sri.com>
parents:
120
diff
changeset
|
197 |
sendRawXmpp := make(chan Stanza) |
153
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
198 |
go sendStream(sendXmlCh, sendRawXmpp, cl.statmgr.newListener()) |
5
faef59c8db05
Added a goroutine to read data from the remote and parse it into
Chris Jones <chris@cjones.org>
parents:
4
diff
changeset
|
199 |
|
153
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
200 |
// Start the managers for the filters that can modify what the |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
201 |
// app sees or sends. |
121
ebb86cbdd218
Changed the way filters work. They're now symmetrical, consisting of a paired send filter and receive filter.
Chris Jones <christian.jones@sri.com>
parents:
120
diff
changeset
|
202 |
recvFiltXmpp := make(chan Stanza) |
127
a8f9a0c07fc8
Renamed client.In and client.Out to Recv and Send, respectively.
Chris Jones <christian.jones@sri.com>
parents:
126
diff
changeset
|
203 |
cl.Recv = recvFiltXmpp |
121
ebb86cbdd218
Changed the way filters work. They're now symmetrical, consisting of a paired send filter and receive filter.
Chris Jones <christian.jones@sri.com>
parents:
120
diff
changeset
|
204 |
go filterMgr(cl.recvFilterAdd, recvRawXmpp, recvFiltXmpp) |
ebb86cbdd218
Changed the way filters work. They're now symmetrical, consisting of a paired send filter and receive filter.
Chris Jones <christian.jones@sri.com>
parents:
120
diff
changeset
|
205 |
sendFiltXmpp := make(chan Stanza) |
127
a8f9a0c07fc8
Renamed client.In and client.Out to Recv and Send, respectively.
Chris Jones <christian.jones@sri.com>
parents:
126
diff
changeset
|
206 |
cl.Send = sendFiltXmpp |
134
80b764fa2f08
Fixed some logic errors and initialized some things that needed to be initialized.
Chris Jones <christian.jones@sri.com>
parents:
132
diff
changeset
|
207 |
go filterMgr(cl.sendFilterAdd, sendFiltXmpp, sendRawXmpp) |
80b764fa2f08
Fixed some logic errors and initialized some things that needed to be initialized.
Chris Jones <christian.jones@sri.com>
parents:
132
diff
changeset
|
208 |
// Set up the initial filters. |
80b764fa2f08
Fixed some logic errors and initialized some things that needed to be initialized.
Chris Jones <christian.jones@sri.com>
parents:
132
diff
changeset
|
209 |
for _, ext := range exts { |
80b764fa2f08
Fixed some logic errors and initialized some things that needed to be initialized.
Chris Jones <christian.jones@sri.com>
parents:
132
diff
changeset
|
210 |
cl.AddRecvFilter(ext.RecvFilter) |
80b764fa2f08
Fixed some logic errors and initialized some things that needed to be initialized.
Chris Jones <christian.jones@sri.com>
parents:
132
diff
changeset
|
211 |
cl.AddSendFilter(ext.SendFilter) |
80b764fa2f08
Fixed some logic errors and initialized some things that needed to be initialized.
Chris Jones <christian.jones@sri.com>
parents:
132
diff
changeset
|
212 |
} |
45
abf958bcc201
Added a stack of filters which can intercept data before it gets to
Chris Jones <chris@cjones.org>
parents:
44
diff
changeset
|
213 |
|
8
30a7752cf8f7
Added the ability to parse <stream:features>.
Chris Jones <chris@cjones.org>
parents:
6
diff
changeset
|
214 |
// Initial handshake. |
118
fb9bb98a8d70
Code cleanup: Renamed the Version constant. Moved the unique-ID generator into its own file.
Chris Jones <christian.jones@sri.com>
parents:
116
diff
changeset
|
215 |
hsOut := &stream{To: jid.Domain, Version: XMPPVersion} |
127
a8f9a0c07fc8
Renamed client.In and client.Out to Recv and Send, respectively.
Chris Jones <christian.jones@sri.com>
parents:
126
diff
changeset
|
216 |
cl.sendXml <- hsOut |
9
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
217 |
|
153
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
218 |
// Wait until resource binding is complete. |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
219 |
if err := cl.statmgr.awaitStatus(StatusBound); err != nil { |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
220 |
return nil, err |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
221 |
} |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
222 |
|
157
eadf15a06ff5
Don't keep the password around after we've used it.
Chris Jones <chris@cjones.org>
parents:
153
diff
changeset
|
223 |
// Forget about the password, for paranoia's sake. |
eadf15a06ff5
Don't keep the password around after we've used it.
Chris Jones <chris@cjones.org>
parents:
153
diff
changeset
|
224 |
cl.password = "" |
eadf15a06ff5
Don't keep the password around after we've used it.
Chris Jones <chris@cjones.org>
parents:
153
diff
changeset
|
225 |
|
153
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
226 |
// Initialize the session. |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
227 |
id := NextId() |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
228 |
iq := &Iq{Header: Header{To: cl.Jid.Domain, Id: id, Type: "set", |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
229 |
Nested: []interface{}{Generic{XMLName: xml.Name{Space: NsSession, Local: "session"}}}}} |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
230 |
ch := make(chan error) |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
231 |
f := func(st Stanza) { |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
232 |
iq, ok := st.(*Iq) |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
233 |
if !ok { |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
234 |
Warn.Log("iq reply not iq; can't start session") |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
235 |
ch <- errors.New("bad session start reply") |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
236 |
} |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
237 |
if iq.Type == "error" { |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
238 |
Warn.Logf("Can't start session: %v", iq) |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
239 |
ch <- iq.Error |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
240 |
} |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
241 |
ch <- nil |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
242 |
} |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
243 |
cl.SetCallback(id, f) |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
244 |
cl.sendXml <- iq |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
245 |
// Now wait until the callback is called. |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
246 |
if err := <-ch; err != nil { |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
247 |
return nil, err |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
248 |
} |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
249 |
|
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
250 |
// This allows the client to receive stanzas. |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
251 |
cl.setStatus(StatusRunning) |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
252 |
|
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
253 |
// Request the roster. |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
254 |
cl.Roster.update() |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
255 |
|
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
256 |
// Send the initial presence. |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
257 |
cl.Send <- &pr |
bbd4166df95d
Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
258 |
|
6
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
259 |
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
|
260 |
} |
4
a8fbec71a194
Added an interactive test and made Client implement io.Closer.
Chris Jones <chris@cjones.org>
parents:
2
diff
changeset
|
261 |
|
6
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
262 |
func tee(r io.Reader, w io.Writer, prefix string) { |
64
ac0639692317
Properly close all the channels and writers if Client.Out is close.
Chris Jones <chris@cjones.org>
parents:
63
diff
changeset
|
263 |
defer func(w io.Writer) { |
72 | 264 |
if c, ok := w.(io.Closer); ok { |
64
ac0639692317
Properly close all the channels and writers if Client.Out is close.
Chris Jones <chris@cjones.org>
parents:
63
diff
changeset
|
265 |
c.Close() |
ac0639692317
Properly close all the channels and writers if Client.Out is close.
Chris Jones <chris@cjones.org>
parents:
63
diff
changeset
|
266 |
} |
ac0639692317
Properly close all the channels and writers if Client.Out is close.
Chris Jones <chris@cjones.org>
parents:
63
diff
changeset
|
267 |
}(w) |
6
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
268 |
|
62
6e2eea62ccca
Added global variables for logging.
Chris Jones <chris@cjones.org>
parents:
61
diff
changeset
|
269 |
buf := bytes.NewBuffer([]uint8(prefix)) |
6
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
270 |
for { |
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
271 |
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
|
272 |
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
|
273 |
if n == 0 { |
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
274 |
break |
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
275 |
} |
9
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
276 |
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
|
277 |
if n == 0 { |
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
278 |
break |
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
279 |
} |
9
4fe926b03827
Reorganize so we have a layered approach to IO with the server.
Chris Jones <chris@cjones.org>
parents:
8
diff
changeset
|
280 |
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
|
281 |
if c[0] == '\n' || c[0] == '>' { |
102
872e936f9f3f
Reworked the logging again, and also added namespaces to a couple of fields on Features.
Chris Jones <christian.jones@sri.com>
parents:
100
diff
changeset
|
282 |
Debug.Log(buf) |
106
ffb9d27fea79
Fixed up the client/server traffic logging.
Chris Jones <christian.jones@sri.com>
parents:
105
diff
changeset
|
283 |
buf = bytes.NewBuffer([]uint8(prefix)) |
6
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
284 |
} |
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
285 |
} |
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
286 |
leftover := buf.String() |
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
287 |
if leftover != "" { |
102
872e936f9f3f
Reworked the logging again, and also added namespaces to a couple of fields on Features.
Chris Jones <christian.jones@sri.com>
parents:
100
diff
changeset
|
288 |
Debug.Log(buf) |
6
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
289 |
} |
8e425e340ca1
Implemented writing to the remote. Now we have bidirectional communication.
Chris Jones <christian.jones@sri.com>
parents:
5
diff
changeset
|
290 |
} |