author | Chris Jones <christian.jones@sri.com> |
Sat, 28 Sep 2013 13:11:44 -0600 | |
changeset 155 | fdd637733628 |
parent 153 | bbd4166df95d |
child 162 | 7b5586a5e109 |
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" |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
8 |
) |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
9 |
|
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
10 |
// 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
|
11 |
type callback struct { |
143
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
12 |
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
|
13 |
f func(Stanza) |
143
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
14 |
} |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
15 |
|
147
d7679d991b17
Function renames and improved doc.
Chris Jones <christian.jones@sri.com>
parents:
146
diff
changeset
|
16 |
// 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
|
17 |
// 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
|
18 |
// 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
|
19 |
// 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
|
20 |
// 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
|
21 |
// channel controls this loop's activity. |
d7679d991b17
Function renames and improved doc.
Chris Jones <christian.jones@sri.com>
parents:
146
diff
changeset
|
22 |
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
|
23 |
status <-chan Status) { |
147
d7679d991b17
Function renames and improved doc.
Chris Jones <christian.jones@sri.com>
parents:
146
diff
changeset
|
24 |
defer close(sendXml) |
143
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
25 |
|
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
26 |
var input <-chan Stanza |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
27 |
for { |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
28 |
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
|
29 |
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
|
30 |
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
|
31 |
default: |
143
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
32 |
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
|
33 |
case StatusRunning: |
147
d7679d991b17
Function renames and improved doc.
Chris Jones <christian.jones@sri.com>
parents:
146
diff
changeset
|
34 |
input = recvXmpp |
143
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
35 |
} |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
36 |
case x, ok := <-input: |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
37 |
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
|
38 |
return |
143
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
39 |
} |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
40 |
if x == nil { |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
41 |
Info.Log("Refusing to send nil stanza") |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
42 |
continue |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
43 |
} |
147
d7679d991b17
Function renames and improved doc.
Chris Jones <christian.jones@sri.com>
parents:
146
diff
changeset
|
44 |
sendXml <- x |
143
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
45 |
} |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
46 |
} |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
47 |
} |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
48 |
|
150
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
49 |
// 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
|
50 |
// 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
|
51 |
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
|
52 |
status <-chan Status) { |
150
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
53 |
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
|
54 |
defer cl.statmgr.close() |
150
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
55 |
|
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
|
56 |
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
|
57 |
doSend := false |
150
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
58 |
for { |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
59 |
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
|
60 |
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
|
61 |
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
|
62 |
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
|
63 |
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
|
64 |
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
|
65 |
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
|
66 |
} |
150
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
67 |
case h := <-cl.handlers: |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
68 |
handlers[h.id] = h.f |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
69 |
case x, ok := <-recvXml: |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
70 |
if !ok { |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
71 |
return |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
72 |
} |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
73 |
switch obj := x.(type) { |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
74 |
case *stream: |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
75 |
// Do nothing. |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
76 |
case *streamError: |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
77 |
cl.handleStreamError(obj) |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
78 |
case *Features: |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
79 |
cl.handleFeatures(obj) |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
80 |
case *starttls: |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
81 |
cl.handleTls(obj) |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
82 |
case *auth: |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
83 |
cl.handleSasl(obj) |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
84 |
case Stanza: |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
85 |
id := obj.GetHeader().Id |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
86 |
if handlers[id] != nil { |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
87 |
f := handlers[id] |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
88 |
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
|
89 |
f(obj) |
150
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
90 |
} |
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
|
91 |
if doSend { |
150
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
92 |
sendXmpp <- obj |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
93 |
} |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
94 |
default: |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
95 |
Warn.Logf("Unhandled non-stanza: %T %#v", x, x) |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
96 |
} |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
97 |
} |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
98 |
} |
143
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
99 |
} |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
100 |
|
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
101 |
func (cl *Client) handleStreamError(se *streamError) { |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
102 |
Info.Logf("Received stream error: %v", se) |
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
|
103 |
cl.setStatus(StatusShutdown) |
143
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
104 |
} |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
105 |
|
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
106 |
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
|
107 |
cl.Features = fe |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
108 |
if fe.Starttls != nil { |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
109 |
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
|
110 |
Local: "starttls"}} |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
111 |
cl.sendXml <- start |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
112 |
return |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
113 |
} |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
114 |
|
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
115 |
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
|
116 |
cl.chooseSasl(fe) |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
117 |
return |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
118 |
} |
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 |
if fe.Bind != nil { |
149
22c96a9ab289
Removed an unused parameter.
Chris Jones <christian.jones@sri.com>
parents:
148
diff
changeset
|
121 |
cl.bind() |
143
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
122 |
return |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
123 |
} |
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 |
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
|
127 |
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
|
128 |
|
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
|
129 |
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
|
130 |
|
143
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
131 |
// 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
|
132 |
// session. |
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.sendXml <- &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
|
134 |
} |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
135 |
|
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
136 |
// 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
|
137 |
func (cl *Client) bind() { |
143
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
138 |
res := cl.Jid.Resource |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
139 |
bindReq := &bindIq{} |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
140 |
if res != "" { |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
141 |
bindReq.Resource = &res |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
142 |
} |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
143 |
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
|
144 |
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
|
145 |
f := func(st Stanza) { |
143
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
146 |
iq, ok := st.(*Iq) |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
147 |
if !ok { |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
148 |
Warn.Log("non-iq response") |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
149 |
} |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
150 |
if iq.Type == "error" { |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
151 |
Warn.Log("Resource binding failed") |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
152 |
} |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
153 |
var bindRepl *bindIq |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
154 |
for _, ele := range iq.Nested { |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
155 |
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
|
156 |
bindRepl = b |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
157 |
break |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
158 |
} |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
159 |
} |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
160 |
if bindRepl == nil { |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
161 |
Warn.Logf("Bad bind reply: %#v", iq) |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
162 |
} |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
163 |
jidStr := bindRepl.Jid |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
164 |
if jidStr == nil || *jidStr == "" { |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
165 |
Warn.Log("Can't bind empty resource") |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
166 |
} |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
167 |
jid := new(JID) |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
168 |
if err := jid.Set(*jidStr); err != nil { |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
169 |
Warn.Logf("Can't parse JID %s: %s", *jidStr, err) |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
170 |
} |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
171 |
cl.Jid = *jid |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
172 |
Info.Logf("Bound resource: %s", cl.Jid.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
|
173 |
cl.setStatus(StatusBound) |
143
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
174 |
} |
144
9d7fdb1d2fc1
Renamed HandleStanza to SetCallback.
Chris Jones <christian.jones@sri.com>
parents:
143
diff
changeset
|
175 |
cl.SetCallback(msg.Id, f) |
143
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
176 |
cl.sendXml <- msg |
62166e57800e
Split stream.go into layer1, layer2, layer3, and sasl.
Chris Jones <christian.jones@sri.com>
parents:
diff
changeset
|
177 |
} |
150
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
178 |
|
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
179 |
// 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
|
180 |
// 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
|
181 |
// 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
|
182 |
// 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
|
183 |
// 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
|
184 |
// 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
|
185 |
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
|
186 |
h := &callback{id: id, f: f} |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
187 |
cl.handlers <- h |
fa7f6ff10c67
Code reorder and doc cleanup.
Chris Jones <christian.jones@sri.com>
parents:
149
diff
changeset
|
188 |
} |