author | Chris Jones <chris@cjones.org> |
Sat, 09 Nov 2013 12:09:37 -0700 | |
changeset 178 | ccfebbd9f49b |
parent 163 | 3f891f7fe817 |
permissions | -rw-r--r-- |
143
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
1 |
// This layer of the XMPP protocol reads XMLish structures and |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
2 |
// responds to them. It negotiates TLS and authentication. |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
3 |
|
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
4 |
package xmpp |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
5 |
|
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
6 |
import ( |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
7 |
"encoding/xml" |
163
3f891f7fe817
Removed the weirdo logging facility. There's now a Debug variable which can be set which replaces the former debug log. NewClient() will return an error if something goes wrong setting up the connection.
Chris Jones <chris@cjones.org>
parents:
162
diff
changeset
|
8 |
"fmt" |
3f891f7fe817
Removed the weirdo logging facility. There's now a Debug variable which can be set which replaces the former debug log. NewClient() will return an error if something goes wrong setting up the connection.
Chris Jones <chris@cjones.org>
parents:
162
diff
changeset
|
9 |
"log" |
143
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
10 |
) |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
11 |
|
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
12 |
// Callback to handle a stanza with a particular id. |
144
9d7fdb1d2fc1
Renamed HandleStanza to SetCallback.
Chris Jones <christian.jones@sri.com>
parents:
143
diff
changeset
|
13 |
type callback struct { |
143
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
14 |
id string |
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:
150
diff
changeset
|
15 |
f func(Stanza) |
143
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
16 |
} |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
17 |
|
147
d7679d991b17
Function renames and improved doc.
Chris Jones <christian.jones@sri.com>
parents:
146
diff
changeset
|
18 |
// Receive XMPP stanzas from the client and send them on to the |
d7679d991b17
Function renames and improved doc.
Chris Jones <christian.jones@sri.com>
parents:
146
diff
changeset
|
19 |
// remote. Don't allow the client to send us any stanzas until |
d7679d991b17
Function renames and improved doc.
Chris Jones <christian.jones@sri.com>
parents:
146
diff
changeset
|
20 |
// negotiation has completed. This loop is paused until resource |
d7679d991b17
Function renames and improved doc.
Chris Jones <christian.jones@sri.com>
parents:
146
diff
changeset
|
21 |
// binding is complete. Otherwise the app might inject something |
d7679d991b17
Function renames and improved doc.
Chris Jones <christian.jones@sri.com>
parents:
146
diff
changeset
|
22 |
// inappropriate into our negotiations with the server. The control |
d7679d991b17
Function renames and improved doc.
Chris Jones <christian.jones@sri.com>
parents:
146
diff
changeset
|
23 |
// channel controls this loop's activity. |
d7679d991b17
Function renames and improved doc.
Chris Jones <christian.jones@sri.com>
parents:
146
diff
changeset
|
24 |
func sendStream(sendXml chan<- interface{}, recvXmpp <-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:
150
diff
changeset
|
25 |
status <-chan Status) { |
147
d7679d991b17
Function renames and improved doc.
Chris Jones <christian.jones@sri.com>
parents:
146
diff
changeset
|
26 |
defer close(sendXml) |
143
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
27 |
|
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
28 |
var input <-chan Stanza |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
29 |
for { |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
30 |
select { |
162
7b5586a5e109
Added a Close() function and fixed a couple of shutdown bugs.
Chris Jones <chris@cjones.org>
parents:
153
diff
changeset
|
31 |
case stat, ok := <-status: |
7b5586a5e109
Added a Close() function and fixed a couple of shutdown bugs.
Chris Jones <chris@cjones.org>
parents:
153
diff
changeset
|
32 |
if !ok { |
7b5586a5e109
Added a Close() function and fixed a couple of shutdown bugs.
Chris Jones <chris@cjones.org>
parents:
153
diff
changeset
|
33 |
return |
7b5586a5e109
Added a Close() function and fixed a couple of shutdown bugs.
Chris Jones <chris@cjones.org>
parents:
153
diff
changeset
|
34 |
} |
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:
150
diff
changeset
|
35 |
switch stat { |
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:
150
diff
changeset
|
36 |
default: |
143
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
37 |
input = nil |
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:
150
diff
changeset
|
38 |
case StatusRunning: |
147
d7679d991b17
Function renames and improved doc.
Chris Jones <christian.jones@sri.com>
parents:
146
diff
changeset
|
39 |
input = recvXmpp |
143
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
40 |
} |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
41 |
case x, ok := <-input: |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
42 |
if !ok { |
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
|
43 |
return |
143
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
44 |
} |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
45 |
if x == nil { |
163
3f891f7fe817
Removed the weirdo logging facility. There's now a Debug variable which can be set which replaces the former debug log. NewClient() will return an error if something goes wrong setting up the connection.
Chris Jones <chris@cjones.org>
parents:
162
diff
changeset
|
46 |
if Debug { |
3f891f7fe817
Removed the weirdo logging facility. There's now a Debug variable which can be set which replaces the former debug log. NewClient() will return an error if something goes wrong setting up the connection.
Chris Jones <chris@cjones.org>
parents:
162
diff
changeset
|
47 |
log.Println("Won't send nil stanza") |
3f891f7fe817
Removed the weirdo logging facility. There's now a Debug variable which can be set which replaces the former debug log. NewClient() will return an error if something goes wrong setting up the connection.
Chris Jones <chris@cjones.org>
parents:
162
diff
changeset
|
48 |
} |
143
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
49 |
continue |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
50 |
} |
147
d7679d991b17
Function renames and improved doc.
Chris Jones <christian.jones@sri.com>
parents:
146
diff
changeset
|
51 |
sendXml <- x |
143
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
52 |
} |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
53 |
} |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
54 |
} |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
55 |
|
150
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
56 |
// Receive XMLish structures, handle all the stream-related ones, and |
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:
150
diff
changeset
|
57 |
// send XMPP stanzas on to the client once the connection is running. |
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:
150
diff
changeset
|
58 |
func (cl *Client) recvStream(recvXml <-chan interface{}, sendXmpp chan<- 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:
150
diff
changeset
|
59 |
status <-chan Status) { |
150
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
60 |
defer close(sendXmpp) |
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:
150
diff
changeset
|
61 |
defer cl.statmgr.close() |
150
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
62 |
|
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:
150
diff
changeset
|
63 |
handlers := make(map[string]func(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:
150
diff
changeset
|
64 |
doSend := false |
150
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
65 |
for { |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
66 |
select { |
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:
150
diff
changeset
|
67 |
case stat := <-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:
150
diff
changeset
|
68 |
switch stat { |
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:
150
diff
changeset
|
69 |
default: |
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:
150
diff
changeset
|
70 |
doSend = false |
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:
150
diff
changeset
|
71 |
case 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:
150
diff
changeset
|
72 |
doSend = true |
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:
150
diff
changeset
|
73 |
} |
150
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
74 |
case h := <-cl.handlers: |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
75 |
handlers[h.id] = h.f |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
76 |
case x, ok := <-recvXml: |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
77 |
if !ok { |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
78 |
return |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
79 |
} |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
80 |
switch obj := x.(type) { |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
81 |
case *stream: |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
82 |
// Do nothing. |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
83 |
case *streamError: |
163
3f891f7fe817
Removed the weirdo logging facility. There's now a Debug variable which can be set which replaces the former debug log. NewClient() will return an error if something goes wrong setting up the connection.
Chris Jones <chris@cjones.org>
parents:
162
diff
changeset
|
84 |
cl.setError(fmt.Errorf("%#v", obj)) |
3f891f7fe817
Removed the weirdo logging facility. There's now a Debug variable which can be set which replaces the former debug log. NewClient() will return an error if something goes wrong setting up the connection.
Chris Jones <chris@cjones.org>
parents:
162
diff
changeset
|
85 |
return |
150
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
86 |
case *Features: |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
87 |
cl.handleFeatures(obj) |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
88 |
case *starttls: |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
89 |
cl.handleTls(obj) |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
90 |
case *auth: |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
91 |
cl.handleSasl(obj) |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
92 |
case Stanza: |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
93 |
id := obj.GetHeader().Id |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
94 |
if handlers[id] != nil { |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
95 |
f := handlers[id] |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
96 |
delete(handlers, id) |
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:
150
diff
changeset
|
97 |
f(obj) |
150
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
98 |
} |
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:
150
diff
changeset
|
99 |
if doSend { |
150
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
100 |
sendXmpp <- obj |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
101 |
} |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
102 |
default: |
163
3f891f7fe817
Removed the weirdo logging facility. There's now a Debug variable which can be set which replaces the former debug log. NewClient() will return an error if something goes wrong setting up the connection.
Chris Jones <chris@cjones.org>
parents:
162
diff
changeset
|
103 |
if Debug { |
3f891f7fe817
Removed the weirdo logging facility. There's now a Debug variable which can be set which replaces the former debug log. NewClient() will return an error if something goes wrong setting up the connection.
Chris Jones <chris@cjones.org>
parents:
162
diff
changeset
|
104 |
log.Printf("Unrecognized input: %T %#v", |
3f891f7fe817
Removed the weirdo logging facility. There's now a Debug variable which can be set which replaces the former debug log. NewClient() will return an error if something goes wrong setting up the connection.
Chris Jones <chris@cjones.org>
parents:
162
diff
changeset
|
105 |
x, x) |
3f891f7fe817
Removed the weirdo logging facility. There's now a Debug variable which can be set which replaces the former debug log. NewClient() will return an error if something goes wrong setting up the connection.
Chris Jones <chris@cjones.org>
parents:
162
diff
changeset
|
106 |
} |
150
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
107 |
} |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
108 |
} |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
109 |
} |
143
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
110 |
} |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
111 |
|
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
112 |
func (cl *Client) handleFeatures(fe *Features) { |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
113 |
cl.Features = fe |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
114 |
if fe.Starttls != nil { |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
115 |
start := &starttls{XMLName: xml.Name{Space: NsTLS, |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
116 |
Local: "starttls"}} |
163
3f891f7fe817
Removed the weirdo logging facility. There's now a Debug variable which can be set which replaces the former debug log. NewClient() will return an error if something goes wrong setting up the connection.
Chris Jones <chris@cjones.org>
parents:
162
diff
changeset
|
117 |
cl.sendRaw <- start |
143
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
118 |
return |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
119 |
} |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
120 |
|
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
121 |
if len(fe.Mechanisms.Mechanism) > 0 { |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
122 |
cl.chooseSasl(fe) |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
123 |
return |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
124 |
} |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
125 |
|
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
126 |
if fe.Bind != nil { |
149
22c96a9ab289
Removed an unused parameter.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
127 |
cl.bind() |
143
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
128 |
return |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
129 |
} |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
130 |
} |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
131 |
|
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
132 |
func (cl *Client) handleTls(t *starttls) { |
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
|
133 |
cl.layer1.startTls(&cl.tlsConfig) |
143
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
134 |
|
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:
150
diff
changeset
|
135 |
cl.setStatus(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:
150
diff
changeset
|
136 |
|
143
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
137 |
// Now re-send the initial handshake message to start the new |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
138 |
// session. |
178
ccfebbd9f49b
Changed the JID type to be an alias of string, rather than a struct. This allows it to be used as a key in a map, among other benefits.
Chris Jones <chris@cjones.org>
parents:
163
diff
changeset
|
139 |
cl.sendRaw <- &stream{To: cl.Jid.Domain(), Version: XMPPVersion} |
143
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
140 |
} |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
141 |
|
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
142 |
// Send a request to bind a resource. RFC 3920, section 7. |
149
22c96a9ab289
Removed an unused parameter.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
143 |
func (cl *Client) bind() { |
178
ccfebbd9f49b
Changed the JID type to be an alias of string, rather than a struct. This allows it to be used as a key in a map, among other benefits.
Chris Jones <chris@cjones.org>
parents:
163
diff
changeset
|
144 |
res := cl.Jid.Resource() |
143
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
145 |
bindReq := &bindIq{} |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
146 |
if res != "" { |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
147 |
bindReq.Resource = &res |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
148 |
} |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
149 |
msg := &Iq{Header: Header{Type: "set", Id: NextId(), |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
150 |
Nested: []interface{}{bindReq}}} |
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:
150
diff
changeset
|
151 |
f := func(st Stanza) { |
143
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
152 |
iq, ok := st.(*Iq) |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
153 |
if !ok { |
163
3f891f7fe817
Removed the weirdo logging facility. There's now a Debug variable which can be set which replaces the former debug log. NewClient() will return an error if something goes wrong setting up the connection.
Chris Jones <chris@cjones.org>
parents:
162
diff
changeset
|
154 |
cl.setError(fmt.Errorf("non-iq response to bind %#v", |
3f891f7fe817
Removed the weirdo logging facility. There's now a Debug variable which can be set which replaces the former debug log. NewClient() will return an error if something goes wrong setting up the connection.
Chris Jones <chris@cjones.org>
parents:
162
diff
changeset
|
155 |
st)) |
3f891f7fe817
Removed the weirdo logging facility. There's now a Debug variable which can be set which replaces the former debug log. NewClient() will return an error if something goes wrong setting up the connection.
Chris Jones <chris@cjones.org>
parents:
162
diff
changeset
|
156 |
return |
143
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
157 |
} |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
158 |
if iq.Type == "error" { |
163
3f891f7fe817
Removed the weirdo logging facility. There's now a Debug variable which can be set which replaces the former debug log. NewClient() will return an error if something goes wrong setting up the connection.
Chris Jones <chris@cjones.org>
parents:
162
diff
changeset
|
159 |
cl.setError(fmt.Errorf("Resource binding failed")) |
3f891f7fe817
Removed the weirdo logging facility. There's now a Debug variable which can be set which replaces the former debug log. NewClient() will return an error if something goes wrong setting up the connection.
Chris Jones <chris@cjones.org>
parents:
162
diff
changeset
|
160 |
return |
143
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
161 |
} |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
162 |
var bindRepl *bindIq |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
163 |
for _, ele := range iq.Nested { |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
164 |
if b, ok := ele.(*bindIq); ok { |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
165 |
bindRepl = b |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
166 |
break |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
167 |
} |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
168 |
} |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
169 |
if bindRepl == nil { |
163
3f891f7fe817
Removed the weirdo logging facility. There's now a Debug variable which can be set which replaces the former debug log. NewClient() will return an error if something goes wrong setting up the connection.
Chris Jones <chris@cjones.org>
parents:
162
diff
changeset
|
170 |
cl.setError(fmt.Errorf("Bad bind reply: %#v", iq)) |
3f891f7fe817
Removed the weirdo logging facility. There's now a Debug variable which can be set which replaces the former debug log. NewClient() will return an error if something goes wrong setting up the connection.
Chris Jones <chris@cjones.org>
parents:
162
diff
changeset
|
171 |
return |
143
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
172 |
} |
178
ccfebbd9f49b
Changed the JID type to be an alias of string, rather than a struct. This allows it to be used as a key in a map, among other benefits.
Chris Jones <chris@cjones.org>
parents:
163
diff
changeset
|
173 |
jid := bindRepl.Jid |
ccfebbd9f49b
Changed the JID type to be an alias of string, rather than a struct. This allows it to be used as a key in a map, among other benefits.
Chris Jones <chris@cjones.org>
parents:
163
diff
changeset
|
174 |
if jid == nil || *jid == "" { |
163
3f891f7fe817
Removed the weirdo logging facility. There's now a Debug variable which can be set which replaces the former debug log. NewClient() will return an error if something goes wrong setting up the connection.
Chris Jones <chris@cjones.org>
parents:
162
diff
changeset
|
175 |
cl.setError(fmt.Errorf("empty resource in bind %#v", |
3f891f7fe817
Removed the weirdo logging facility. There's now a Debug variable which can be set which replaces the former debug log. NewClient() will return an error if something goes wrong setting up the connection.
Chris Jones <chris@cjones.org>
parents:
162
diff
changeset
|
176 |
iq)) |
3f891f7fe817
Removed the weirdo logging facility. There's now a Debug variable which can be set which replaces the former debug log. NewClient() will return an error if something goes wrong setting up the connection.
Chris Jones <chris@cjones.org>
parents:
162
diff
changeset
|
177 |
return |
143
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
178 |
} |
178
ccfebbd9f49b
Changed the JID type to be an alias of string, rather than a struct. This allows it to be used as a key in a map, among other benefits.
Chris Jones <chris@cjones.org>
parents:
163
diff
changeset
|
179 |
cl.Jid = JID(*jid) |
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:
150
diff
changeset
|
180 |
cl.setStatus(StatusBound) |
143
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
181 |
} |
144
9d7fdb1d2fc1
Renamed HandleStanza to SetCallback.
Chris Jones <christian.jones@sri.com>
parents:
143
diff
changeset
|
182 |
cl.SetCallback(msg.Id, f) |
163
3f891f7fe817
Removed the weirdo logging facility. There's now a Debug variable which can be set which replaces the former debug log. NewClient() will return an error if something goes wrong setting up the connection.
Chris Jones <chris@cjones.org>
parents:
162
diff
changeset
|
183 |
cl.sendRaw <- msg |
143
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
184 |
} |
150
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
185 |
|
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
186 |
// Register a callback to handle the next XMPP stanza (iq, message, or |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
187 |
// presence) with a given id. The provided function will not be called |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
188 |
// more than once. If it returns false, the stanza will not be made |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
189 |
// available on the normal Client.Recv channel. The callback must not |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
190 |
// read from that channel, as deliveries on it cannot proceed until |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
191 |
// the handler returns true or false. |
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:
150
diff
changeset
|
192 |
func (cl *Client) SetCallback(id string, f func(Stanza)) { |
150
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
193 |
h := &callback{id: id, f: f} |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
194 |
cl.handlers <- h |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
195 |
} |