Made a special-purpose bind structure for resource binding.
authorChris Jones <chris@cjones.org>
Sun, 01 Jan 2012 17:19:03 -0700
changeset 41 c8c9e6a7e6c9
parent 40 33e7f25f1fd2
child 42 f6bb47ca12f2
Made a special-purpose bind structure for resource binding.
stream.go
structs.go
xmpp.go
--- a/stream.go	Sat Dec 31 12:11:02 2011 -0700
+++ b/stream.go	Sun Jan 01 17:19:03 2012 -0700
@@ -553,40 +553,31 @@
 	return response
 }
 
-// BUG(cjyar) This should use iq.nested rather than iq.generic.
-
 // Send a request to bind a resource. RFC 3920, section 7.
-func (cl *Client) bind(bind *Generic) {
+func (cl *Client) bind(bindAdv *bindIq) {
 	res := cl.Jid.Resource
-	msg := &Iq{Type: "set", Id: <- cl.Id, Any:
-		&Generic{XMLName: xml.Name{Space: NsBind, Local:
-					"bind"}}}
+	bindReq := &bindIq{}
 	if res != "" {
-		msg.Any.Any = &Generic{XMLName: xml.Name{Local:
-				"resource"}, Chardata: res}
+		bindReq.Resource = &res
 	}
+	msg := &Iq{Type: "set", Id: <- cl.Id, Nested: &bindReq}
 	f := func(st Stanza) bool {
 		if st.XType() == "error" {
 			log.Println("Resource binding failed")
 			return false
 		}
-		bind := st.generic()
-		if bind == nil {
-			log.Println("nil resource bind")
+		bindRepl, ok := st.XNested().(*bindIq)
+		if !ok {
+			log.Printf("bad bind reply: %v", bindRepl)
 			return false
 		}
-		jidEle := bind.Any
-		if jidEle == nil {
-			log.Println("nil resource")
-			return false
-		}
-		jidStr := jidEle.Chardata
-		if jidStr == "" {
+		jidStr := bindRepl.Jid
+		if jidStr == nil || *jidStr == "" {
 			log.Println("empty resource")
 			return false
 		}
 		jid := new(JID)
-		if !jid.Set(jidStr) {
+		if !jid.Set(*jidStr) {
 			log.Println("Can't parse JID %s", jidStr)
 			return false
 		}
--- a/structs.go	Sat Dec 31 12:11:02 2011 -0700
+++ b/structs.go	Sun Jan 01 17:19:03 2012 -0700
@@ -55,7 +55,7 @@
 type Features struct {
 	Starttls *starttls
 	Mechanisms mechs
-	Bind *Generic
+	Bind *bindIq
 	Session *Generic
 	Any *Generic
 }
@@ -163,6 +163,13 @@
 var _ xml.Marshaler = &Error{}
 var _ os.Error = &Error{}
 
+// Used for resource binding as a nested element inside <iq/>.
+type bindIq struct {
+	XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-bind bind"`
+	Resource *string `xml:"resource"`
+	Jid *string `xml:"jid"`
+}
+
 // Holds an XML element not described by the more specific types.
 type Generic struct {
 	XMLName xml.Name
@@ -538,3 +545,7 @@
 	}
 	return stan, nil
 }
+
+func newBind(name *xml.Name) interface{} {
+	return &bindIq{}
+}
--- a/xmpp.go	Sat Dec 31 12:11:02 2011 -0700
+++ b/xmpp.go	Sun Jan 01 17:19:03 2012 -0700
@@ -125,6 +125,7 @@
 		extStanza = make(map[string] func(*xml.Name) interface{})
 	}
 	extStanza[NsRoster] = newRosterQuery
+	extStanza[NsBind] = newBind
 
 	// Start the unique id generator.
 	go makeIds(idCh)