equal
deleted
inserted
replaced
16 "encoding/xml" |
16 "encoding/xml" |
17 "errors" |
17 "errors" |
18 "fmt" |
18 "fmt" |
19 "io" |
19 "io" |
20 "net" |
20 "net" |
|
21 "reflect" |
21 "sync" |
22 "sync" |
22 ) |
23 ) |
23 |
24 |
24 const ( |
25 const ( |
25 // Version of RFC 3920 that we implement. |
26 // Version of RFC 3920 that we implement. |
49 // Extensions can add stanza filters and/or new XML element types. |
50 // Extensions can add stanza filters and/or new XML element types. |
50 type Extension struct { |
51 type Extension struct { |
51 // Maps from an XML namespace to a function which constructs a |
52 // Maps from an XML namespace to a function which constructs a |
52 // structure to hold the contents of stanzas in that |
53 // structure to hold the contents of stanzas in that |
53 // namespace. |
54 // namespace. |
54 StanzaHandlers map[string]func(*xml.Name) interface{} |
55 StanzaHandlers map[xml.Name]reflect.Type |
55 // If non-nil, will be called once to start the filter |
56 // If non-nil, will be called once to start the filter |
56 // running. RecvFilter intercepts incoming messages on their |
57 // running. RecvFilter intercepts incoming messages on their |
57 // way from the remote server to the application; SendFilter |
58 // way from the remote server to the application; SendFilter |
58 // intercepts messages going the other direction. |
59 // intercepts messages going the other direction. |
59 RecvFilter Filter |
60 RecvFilter Filter |
89 Roster Roster |
90 Roster Roster |
90 // Features advertised by the remote. This will be updated |
91 // Features advertised by the remote. This will be updated |
91 // asynchronously as new features are received throughout the |
92 // asynchronously as new features are received throughout the |
92 // connection process. It should not be updated once |
93 // connection process. It should not be updated once |
93 // StartSession() returns. |
94 // StartSession() returns. |
94 Features *Features |
95 Features *Features |
95 sendFilterAdd, recvFilterAdd chan Filter |
96 sendFilterAdd, recvFilterAdd chan Filter |
96 } |
97 } |
97 |
98 |
98 // Connect to the appropriate server and authenticate as the given JID |
99 // Connect to the appropriate server and authenticate as the given JID |
99 // with the given password. This function will return as soon as a TCP |
100 // with the given password. This function will return as soon as a TCP |
139 cl.Jid = *jid |
140 cl.Jid = *jid |
140 cl.socket = tcp |
141 cl.socket = tcp |
141 cl.handlers = make(chan *stanzaHandler, 100) |
142 cl.handlers = make(chan *stanzaHandler, 100) |
142 cl.inputControl = make(chan int) |
143 cl.inputControl = make(chan int) |
143 |
144 |
144 extStanza := make(map[string]func(*xml.Name) interface{}) |
145 extStanza := make(map[xml.Name]reflect.Type) |
145 for _, ext := range exts { |
146 for _, ext := range exts { |
146 for k, v := range ext.StanzaHandlers { |
147 for k, v := range ext.StanzaHandlers { |
|
148 if _, ok := extStanza[k]; !ok { |
|
149 return nil, fmt.Errorf("duplicate handler %s", |
|
150 k) |
|
151 } |
147 extStanza[k] = v |
152 extStanza[k] = v |
148 } |
153 } |
149 } |
154 } |
150 |
155 |
151 // Start the transport handler, initially unencrypted. |
156 // Start the transport handler, initially unencrypted. |