Description: Fix http-upload
Origin: <upstream>, <https://salsa.debian.org/mdosch/go-sendxmpp/-/commit/ec98159c04d6d25b63c7aa522618ebc5eb5fa01b>
Applied-Upstream: <https://salsa.debian.org/mdosch/go-sendxmpp/-/commit/ec98159c04d6d25b63c7aa522618ebc5eb5fa01b>
---
This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
--- a/httpupload.go
+++ b/httpupload.go
@@ -22,108 +22,38 @@
 	"github.com/xmppo/go-xmpp"           // BSD-3-Clause
 )
 
-func httpUpload(client *xmpp.Client, iqc chan xmpp.IQ, jserver string, filePaths []string,
-	timeout time.Duration,
+func httpUpload(client *xmpp.Client, iqc chan xmpp.IQ, disc chan xmpp.DiscoItems, drc chan xmpp.DiscoResult,
+	jserver string, filePaths []string, timeout time.Duration,
 ) (urls []string, err error) {
 	var uploadComponent string
 	var maxFileSize int64
-	var iqDiscoItemsXMLQuery, iqDiscoInfoXMLQuery *etree.Element
 
 	// Query server for disco#items
-	iqContent, err := sendIQ(client, iqc, jserver, "get",
-		"<query xmlns='http://jabber.org/protocol/disco#items'/>")
+	discoItems, err := getDiscoItems(client, disc, jserver)
 	if err != nil {
-		return urls, err
+		return
 	}
-	iqDiscoItemsXML := etree.NewDocument()
-	err = iqDiscoItemsXML.ReadFromBytes(iqContent.Query)
-	if err != nil {
-		return urls, err
-	}
-	iqDiscoItemsXMLQuery = iqDiscoItemsXML.SelectElement("query")
-	if iqDiscoItemsXMLQuery == nil {
-		return urls, fmt.Errorf("http-upload: no query element in disco items reply")
-	}
-	iqDiscoItemsXMLItems := iqDiscoItemsXMLQuery.SelectElements("item")
 
 	// Check the services reported by disco#items for the http upload service
-	for _, r := range iqDiscoItemsXMLItems {
-		jid := r.SelectAttr("jid")
-		iqDiscoInfoReqXML := etree.NewDocument()
-		iqDiscoInfoReqXML.WriteSettings.AttrSingleQuote = true
-		iqDiscoInfoReqXMLQuery := iqDiscoInfoReqXML.CreateElement("query")
-		iqDiscoInfoReqXMLQuery.CreateAttr("xmlns", nsDiscoInfo)
-		iqdi, err := iqDiscoInfoReqXML.WriteToString()
-		if err != nil {
-			return urls, err
-		}
-		iqDiscoInfo, err := sendIQ(client, iqc, jid.Value, "get", iqdi)
-		if err != nil {
-			return urls, err
-		}
-		if iqDiscoInfo.Type != strResult {
-			continue
-		}
-		iqDiscoInfoXML := etree.NewDocument()
-		err = iqDiscoInfoXML.ReadFromBytes(iqDiscoInfo.Query)
+	for _, r := range discoItems.Items {
+		discoResult, err := getDiscoInfo(client, drc, r.Jid)
 		if err != nil {
 			return urls, err
 		}
-		iqDiscoInfoXMLQuery = iqDiscoInfoXML.SelectElement("query")
-		if iqDiscoInfoXMLQuery == nil {
-			continue
-		}
-		iqDiscoInfoXMLIdentity := iqDiscoInfoXMLQuery.SelectElement("identity")
-		if iqDiscoInfoXMLIdentity == nil {
-			continue
-		}
-		iqDiscoInfoXMLType := iqDiscoInfoXMLIdentity.SelectAttr("type")
-		if iqDiscoInfoXMLType == nil {
-			continue
-		}
-		iqDiscoInfoXMLCategory := iqDiscoInfoXMLIdentity.SelectAttr("category")
-		if iqDiscoInfoXMLCategory == nil {
-			continue
+		for _, identity := range discoResult.Identities {
+			if identity.Type == "file" &&
+				identity.Category == "store" {
+				uploadComponent = r.Jid
+				break
+			}
 		}
-		if iqDiscoInfoXMLType.Value == "file" &&
-			iqDiscoInfoXMLCategory.Value == "store" {
-			uploadComponent = jid.Value
+		if uploadComponent != "" {
 			break
 		}
 	}
 	if uploadComponent == "" {
 		return urls, fmt.Errorf("http-upload: no http upload component found")
 	}
-	iqDiscoInfoXMLX := iqDiscoInfoXMLQuery.SelectElements("x")
-	for _, r := range iqDiscoInfoXMLX {
-		field := r.SelectElements("field")
-		for i, t := range field {
-			varAttr := t.SelectAttr("var")
-			if varAttr == nil {
-				continue
-			}
-			curFieldVal := t.SelectElement("value")
-			if curFieldVal == nil {
-				continue
-			}
-			if varAttr.Value == "max-file-size" {
-				var prevFieldVal *etree.Element
-				if i > 0 {
-					prevFieldVal = field[i-1].SelectElement("value")
-					if prevFieldVal == nil {
-						continue
-					}
-				}
-				if prevFieldVal.Text() == nsHTTPUpload {
-					maxFileSize, err = strconv.ParseInt(curFieldVal.Text(), 10, 64)
-					if err != nil {
-						return urls, fmt.Errorf("http-upload: error while checking server maximum http upload file size")
-					}
-				}
-			}
-		}
-	}
-
 	for _, filePath := range filePaths {
 		// Get file size
 		fileInfo, err := os.Stat(filePath)
--- a/main.go
+++ b/main.go
@@ -439,8 +439,10 @@
 	}
 	iqc := make(chan xmpp.IQ, defaultBufferSize)
 	msgc := make(chan xmpp.Chat, defaultBufferSize)
+	disc := make(chan xmpp.DiscoItems, defaultBufferSize)
+	drc := make(chan xmpp.DiscoResult, defaultBufferSize)
 	ctx, cancel := context.WithCancel(context.Background())
-	go rcvStanzas(client, ctx, iqc, msgc)
+	go rcvStanzas(client, ctx, iqc, msgc, disc, drc)
 	for _, r := range getopt.Args() {
 		var re recipientsType
 		re.Jid = r
@@ -530,7 +532,7 @@
 
 	var uploadMessages []string
 	if len(*flagHTTPUpload) != 0 {
-		uploadMessages, err = httpUpload(client, iqc,
+		uploadMessages, err = httpUpload(client, iqc, disc, drc,
 			tlsConfig.ServerName, *flagHTTPUpload, timeout)
 		if err != nil {
 			cancel()
--- a/stanzahandling.go
+++ b/stanzahandling.go
@@ -17,6 +17,62 @@
 	"github.com/xmppo/go-xmpp" // BSD-3-Clause
 )
 
+func getDiscoInfo(client *xmpp.Client, drc chan xmpp.DiscoResult, target string) (dr xmpp.DiscoResult, err error) {
+	id := getID()
+	c := make(chan xmpp.DiscoResult, defaultBufferSize)
+	go getDr(target, c, drc)
+	_, err = client.RawInformation(client.JID(), target, id, "get",
+		fmt.Sprintf("<query xmlns='%s'/>", nsDiscoInfo))
+	if err != nil {
+		return
+	}
+	select {
+	case dr = <-c:
+	case <-time.After(60 * time.Second):
+		return dr, fmt.Errorf("get disco info: %s didn't reply to disco info request", target)
+	}
+	return
+}
+
+func getDr(jid string, c chan xmpp.DiscoResult, drc chan xmpp.DiscoResult) {
+	for {
+		println("getDr")
+		dr := <-drc
+		println("got dr")
+		c <- dr
+		return
+	}
+}
+
+func getDiscoItems(client *xmpp.Client, disc chan xmpp.DiscoItems, target string) (dis xmpp.DiscoItems, err error) {
+	id := getID()
+	c := make(chan xmpp.DiscoItems, defaultBufferSize)
+	go getDis(target, c, disc)
+	_, err = client.RawInformation(client.JID(), target, id, "get",
+		fmt.Sprintf("<query xmlns='%s'/>", nsDiscoItems))
+	if err != nil {
+		return
+	}
+	select {
+	case dis = <-c:
+	case <-time.After(60 * time.Second):
+		return dis, fmt.Errorf("get disco items: %s didn't reply to disco items request", target)
+	}
+	return
+}
+
+func getDis(jid string, c chan xmpp.DiscoItems, disc chan xmpp.DiscoItems) {
+	for {
+		println("getDis")
+		dis := <-disc
+		if dis.Jid == jid {
+			println("got dis")
+			c <- dis
+			return
+		}
+	}
+}
+
 func sendIQ(client *xmpp.Client, iqc chan xmpp.IQ, target string, iQtype string, content string) (xmpp.IQ, error) {
 	var iq xmpp.IQ
 	id := getID()
@@ -45,7 +101,7 @@
 	}
 }
 
-func rcvStanzas(client *xmpp.Client, ctx context.Context, iqc chan xmpp.IQ, msgc chan xmpp.Chat) {
+func rcvStanzas(client *xmpp.Client, ctx context.Context, iqc chan xmpp.IQ, msgc chan xmpp.Chat, disc chan xmpp.DiscoItems, drc chan xmpp.DiscoResult) {
 	type messageError struct {
 		XMLName xml.Name `xml:"message-error"`
 		Text    string   `xml:"text"`
@@ -97,6 +153,10 @@
 				}
 			}
 			msgc <- v
+		case xmpp.DiscoItems:
+			disc <- v
+		case xmpp.DiscoResult:
+			drc <- v
 		case xmpp.IQ:
 			switch v.Type {
 			case "get":
