From 03f744a886cbabf37ed344df4c70875d8cb53f14 Mon Sep 17 00:00:00 2001 From: Martin Dosch Date: Sun, 24 Apr 2022 01:45:20 +0200 Subject: [PATCH 1/3] Change from encoding/xml to etree. --- httpupload.go | 20 ++++++++++++-------- iqstructs.go | 8 -------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/httpupload.go b/httpupload.go index 67d418b..e0c779c 100644 --- a/httpupload.go +++ b/httpupload.go @@ -7,6 +7,7 @@ package main import ( "bytes" "encoding/xml" + "fmt" "log" "net/http" "os" @@ -14,7 +15,8 @@ import ( "regexp" "strconv" - "github.com/gabriel-vasile/mimetype" // MIT License + "github.com/beevik/etree" // BSD-2-clause + "github.com/gabriel-vasile/mimetype" // MIT License) "github.com/mattn/go-xmpp" // BSD-3-Clause ) @@ -108,18 +110,20 @@ func httpUpload(client *xmpp.Client, jserver string, filePath string) string { } } - var request IQHttpUploadSlotRequest - request.Xmlns = nsHttpUpload - request.FileName = fileNameEscaped - request.FileSize = fileSize - request.FileType = mimeType - r, err := xml.Marshal(request) + request := etree.NewDocument() + requestReq := request.CreateElement("request") + requestReq.CreateAttr("xmlns", nsHttpUpload) + requestReq.CreateAttr("filename", fileNameEscaped) + requestReq.CreateAttr("size", fmt.Sprint(fileSize)) + requestReq.CreateAttr("content-type", mimeType) + r, err := request.WriteToString() + println(r) if err != nil { log.Fatal(err) } // Request http upload slot - uploadSlot, err := sendIQ(client, uploadComponent, "get", string(r)) + uploadSlot, err := sendIQ(client, uploadComponent, "get", r) if err != nil { log.Fatal(err) } diff --git a/iqstructs.go b/iqstructs.go index 4e4bbf7..aa18c03 100644 --- a/iqstructs.go +++ b/iqstructs.go @@ -45,14 +45,6 @@ type IQDiscoInfoType struct { } `xml:"x"` } -type IQHttpUploadSlotRequest struct { - XMLName xml.Name `xml:"request"` - Xmlns string `xml:"xmlns,attr"` - FileName string `xml:"filename,attr"` - FileType string `xml:"mime-type,attr"` - FileSize int64 `xml:"size,attr"` -} - // Created with https://github.com/miku/zek type IQHttpUploadSlot struct { XMLName xml.Name `xml:"slot"` From 8369d28f9efc4e74f4b5e9645f7e7277f1876dbe Mon Sep 17 00:00:00 2001 From: Martin Dosch Date: Sun, 24 Apr 2022 01:45:55 +0200 Subject: [PATCH 2/3] =?UTF-8?q?Remove=20debug=20println=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- httpupload.go | 1 - 1 file changed, 1 deletion(-) diff --git a/httpupload.go b/httpupload.go index e0c779c..863765b 100644 --- a/httpupload.go +++ b/httpupload.go @@ -117,7 +117,6 @@ func httpUpload(client *xmpp.Client, jserver string, filePath string) string { requestReq.CreateAttr("size", fmt.Sprint(fileSize)) requestReq.CreateAttr("content-type", mimeType) r, err := request.WriteToString() - println(r) if err != nil { log.Fatal(err) } From d3cdd71f03867ce26750978fa49e430deb9ed9df Mon Sep 17 00:00:00 2001 From: Martin Dosch Date: Mon, 25 Apr 2022 11:59:26 +0200 Subject: [PATCH 3/3] Move from encoding/xml to etree. --- httpupload.go | 61 +++++++++++++++++++++++++++++++---------------- iqstructs.go | 65 --------------------------------------------------- 2 files changed, 41 insertions(+), 85 deletions(-) delete mode 100644 iqstructs.go diff --git a/httpupload.go b/httpupload.go index 863765b..624dd34 100644 --- a/httpupload.go +++ b/httpupload.go @@ -21,9 +21,6 @@ import ( ) func httpUpload(client *xmpp.Client, jserver string, filePath string) string { - var iqDiscoItemsXML IQDiscoItemsType - var iqDiscoInfoXML IQDiscoInfoType - var iqHttpUploadSlotXML IQHttpUploadSlot var uploadComponent string var maxFileSize int64 @@ -61,14 +58,18 @@ func httpUpload(client *xmpp.Client, jserver string, filePath string) string { if err != nil { log.Fatal(err) } - err = xml.Unmarshal(iqContent.Query, &iqDiscoItemsXML) + iqDiscoItemsXML := etree.NewDocument() + err = iqDiscoItemsXML.ReadFromBytes(iqContent.Query) if err != nil { log.Fatal(err) } + iqDiscoItemsXMLQuery := iqDiscoItemsXML.SelectElement("query") + iqDiscoItemsXMLItems := iqDiscoItemsXMLQuery.SelectElements("item") // Check the services reported by disco#items for the http upload service - for _, r := range iqDiscoItemsXML.Item { - iqDiscoInfo, err := sendIQ(client, r.Jid, "get", + for _, r := range iqDiscoItemsXMLItems { + jid := r.SelectAttr("jid") + iqDiscoInfo, err := sendIQ(client, jid.Value, "get", "") if err != nil { log.Fatal(err) @@ -76,23 +77,34 @@ func httpUpload(client *xmpp.Client, jserver string, filePath string) string { if iqDiscoInfo.Type != "result" { continue } - err = xml.Unmarshal(iqDiscoInfo.Query, &iqDiscoInfoXML) + iqDiscoInfoXML := etree.NewDocument() + err = iqDiscoInfoXML.ReadFromBytes(iqDiscoInfo.Query) if err != nil { log.Fatal(err) } - - if iqDiscoInfoXML.Identity.Type == "file" && iqDiscoInfoXML.Identity.Category == "store" { - uploadComponent = r.Jid + iqDiscoInfoXMLQuery := iqDiscoInfoXML.SelectElement("query") + iqDiscoInfoXMLIdentity := iqDiscoInfoXMLQuery.SelectElement("identity") + iqDiscoInfoXMLType := iqDiscoInfoXMLIdentity.SelectAttr("type") + iqDiscoInfoXMLCategory := iqDiscoInfoXMLIdentity.SelectAttr("category") + + if iqDiscoInfoXMLType.Value == "file" && + iqDiscoInfoXMLCategory.Value == "store" { + uploadComponent = jid.Value } } if uploadComponent == "" { log.Fatal("No http upload component found.") } - for _, r := range iqDiscoInfoXML.X { - for i, t := range r.Field { - if t.Var == "max-file-size" && r.Field[i-1].Value == nsHttpUpload { - maxFileSize, err = strconv.ParseInt(t.Value, 10, 64) + iqDiscoInfoXMLX := iqDiscoItemsXMLQuery.SelectElements("x") + for _, r := range iqDiscoInfoXMLX { + field := r.SelectElements("field") + for i, t := range field { + varAttr := t.SelectAttr("var") + prevFieldVal := field[i-1].SelectElement("value") + curFieldVal := t.SelectElement("value") + if varAttr.Value == "max-file-size" && prevFieldVal.Text() == nsHttpUpload { + maxFileSize, err = strconv.ParseInt(curFieldVal.Text(), 10, 64) if err != nil { log.Fatal("Error while checking server maximum http upload file size.") } @@ -129,22 +141,29 @@ func httpUpload(client *xmpp.Client, jserver string, filePath string) string { if uploadSlot.Type != "result" { log.Fatal("Error while requesting upload slot.") } - err = xml.Unmarshal(uploadSlot.Query, &iqHttpUploadSlotXML) + iqHttpUploadSlotXML := etree.NewDocument() + err = iqHttpUploadSlotXML.ReadFromBytes(uploadSlot.Query) if err != nil { log.Fatal(err) } + iqHttpUploadSlotXMLSlot := iqHttpUploadSlotXML.SelectElement("slot") + iqHttpUploadSlotXMLPut := iqHttpUploadSlotXMLSlot.SelectElement("put") + iqHttpUploadSlotXMLPutURL := iqHttpUploadSlotXMLPut.SelectAttr("url") // Upload file httpClient := &http.Client{} - req, err := http.NewRequest(http.MethodPut, iqHttpUploadSlotXML.Put.URL, buffer) + req, err := http.NewRequest(http.MethodPut, iqHttpUploadSlotXMLPutURL.Value, + buffer) if err != nil { log.Fatal(err) } req.Header.Set("Content-Type", mimeTypeEscaped.String()) - for _, h := range iqHttpUploadSlotXML.Put.Headers { - switch h.Name { + iqHttpUploadSlotXMLPutHeaders := iqHttpUploadSlotXMLPut.SelectElements("header") + for _, h := range iqHttpUploadSlotXMLPutHeaders { + name := h.SelectAttr("name") + switch name.Value { case "Authorization", "Cookie", "Expires": - req.Header.Set(h.Name, h.Value) + req.Header.Set(name.Value, h.Text()) } } resp, err := httpClient.Do(req) @@ -157,5 +176,7 @@ func httpUpload(client *xmpp.Client, jserver string, filePath string) string { } // Return http link - return iqHttpUploadSlotXML.Get.URL + iqHttpUploadSlotXMLGet := iqHttpUploadSlotXMLSlot.SelectElement("get") + iqHttpUploadSlotXMLGetURL := iqHttpUploadSlotXMLGet.SelectAttr("url") + return iqHttpUploadSlotXMLGetURL.Value } diff --git a/iqstructs.go b/iqstructs.go deleted file mode 100644 index aa18c03..0000000 --- a/iqstructs.go +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright 2022 Martin Dosch. -// Use of this source code is governed by the BSD-2-clause -// license that can be found in the LICENSE file. - -package main - -import "encoding/xml" - -// Created with https://github.com/miku/zek -type IQDiscoItemsType struct { - XMLName xml.Name `xml:"query"` - Text string `xml:",chardata"` - Xmlns string `xml:"xmlns,attr"` - Item []struct { - Text string `xml:",chardata"` - Jid string `xml:"jid,attr"` - } `xml:"item"` -} - -// Created with https://github.com/miku/zek -type IQDiscoInfoType struct { - XMLName xml.Name `xml:"query"` - Text string `xml:",chardata"` - Xmlns string `xml:"xmlns,attr"` - Identity struct { - Text string `xml:",chardata"` - Type string `xml:"type,attr"` - Name string `xml:"name,attr"` - Category string `xml:"category,attr"` - } `xml:"identity"` - Feature []struct { - Text string `xml:",chardata"` - Var string `xml:"var,attr"` - } `xml:"feature"` - X []struct { - Text string `xml:",chardata"` - Type string `xml:"type,attr"` - Xmlns string `xml:"xmlns,attr"` - Field []struct { - Text string `xml:",chardata"` - Type string `xml:"type,attr"` - Var string `xml:"var,attr"` - Value string `xml:"value"` - } `xml:"field"` - } `xml:"x"` -} - -// Created with https://github.com/miku/zek -type IQHttpUploadSlot struct { - XMLName xml.Name `xml:"slot"` - Text string `xml:",chardata"` - Xmlns string `xml:"xmlns,attr"` - Get struct { - Text string `xml:",chardata"` - URL string `xml:"url,attr"` - } `xml:"get"` - Put struct { - Text string `xml:",chardata"` - URL string `xml:"url,attr"` - Headers []struct { - Name string `xml:"name,attr"` - Value string `xml:",chardata"` - } `xml:"header"` - } `xml:"put"` -}