mirror of
https://salsa.debian.org/mdosch/go-sendxmpp
synced 2024-11-15 00:15:10 +00:00
Merge branch 'master' into code-cleanup
This commit is contained in:
commit
a3bebd365b
@ -7,6 +7,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
@ -14,14 +15,12 @@ import (
|
|||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"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
|
"github.com/mattn/go-xmpp" // BSD-3-Clause
|
||||||
)
|
)
|
||||||
|
|
||||||
func httpUpload(client *xmpp.Client, jserver string, filePath string) string {
|
func httpUpload(client *xmpp.Client, jserver string, filePath string) string {
|
||||||
var iqDiscoItemsXML IQDiscoItemsType
|
|
||||||
var iqDiscoInfoXML IQDiscoInfoType
|
|
||||||
var iqHttpUploadSlotXML IQHttpUploadSlot
|
|
||||||
var uploadComponent string
|
var uploadComponent string
|
||||||
var maxFileSize int64
|
var maxFileSize int64
|
||||||
|
|
||||||
@ -59,14 +58,18 @@ func httpUpload(client *xmpp.Client, jserver string, filePath string) string {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
err = xml.Unmarshal(iqContent.Query, &iqDiscoItemsXML)
|
iqDiscoItemsXML := etree.NewDocument()
|
||||||
|
err = iqDiscoItemsXML.ReadFromBytes(iqContent.Query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
iqDiscoItemsXMLQuery := iqDiscoItemsXML.SelectElement("query")
|
||||||
|
iqDiscoItemsXMLItems := iqDiscoItemsXMLQuery.SelectElements("item")
|
||||||
|
|
||||||
// Check the services reported by disco#items for the http upload service
|
// Check the services reported by disco#items for the http upload service
|
||||||
for _, r := range iqDiscoItemsXML.Item {
|
for _, r := range iqDiscoItemsXMLItems {
|
||||||
iqDiscoInfo, err := sendIQ(client, r.Jid, "get",
|
jid := r.SelectAttr("jid")
|
||||||
|
iqDiscoInfo, err := sendIQ(client, jid.Value, "get",
|
||||||
"<query xmlns='http://jabber.org/protocol/disco#info'/>")
|
"<query xmlns='http://jabber.org/protocol/disco#info'/>")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
@ -74,23 +77,34 @@ func httpUpload(client *xmpp.Client, jserver string, filePath string) string {
|
|||||||
if iqDiscoInfo.Type != "result" {
|
if iqDiscoInfo.Type != "result" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
err = xml.Unmarshal(iqDiscoInfo.Query, &iqDiscoInfoXML)
|
iqDiscoInfoXML := etree.NewDocument()
|
||||||
|
err = iqDiscoInfoXML.ReadFromBytes(iqDiscoInfo.Query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
iqDiscoInfoXMLQuery := iqDiscoInfoXML.SelectElement("query")
|
||||||
|
iqDiscoInfoXMLIdentity := iqDiscoInfoXMLQuery.SelectElement("identity")
|
||||||
|
iqDiscoInfoXMLType := iqDiscoInfoXMLIdentity.SelectAttr("type")
|
||||||
|
iqDiscoInfoXMLCategory := iqDiscoInfoXMLIdentity.SelectAttr("category")
|
||||||
|
|
||||||
if iqDiscoInfoXML.Identity.Type == "file" && iqDiscoInfoXML.Identity.Category == "store" {
|
if iqDiscoInfoXMLType.Value == "file" &&
|
||||||
uploadComponent = r.Jid
|
iqDiscoInfoXMLCategory.Value == "store" {
|
||||||
|
uploadComponent = jid.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if uploadComponent == "" {
|
if uploadComponent == "" {
|
||||||
log.Fatal("No http upload component found.")
|
log.Fatal("No http upload component found.")
|
||||||
}
|
}
|
||||||
for _, r := range iqDiscoInfoXML.X {
|
iqDiscoInfoXMLX := iqDiscoItemsXMLQuery.SelectElements("x")
|
||||||
for i, t := range r.Field {
|
for _, r := range iqDiscoInfoXMLX {
|
||||||
if t.Var == "max-file-size" && r.Field[i-1].Value == nsHttpUpload {
|
field := r.SelectElements("field")
|
||||||
maxFileSize, err = strconv.ParseInt(t.Value, 10, 64)
|
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 {
|
if err != nil {
|
||||||
log.Fatal("Error while checking server maximum http upload file size.")
|
log.Fatal("Error while checking server maximum http upload file size.")
|
||||||
}
|
}
|
||||||
@ -108,40 +122,48 @@ func httpUpload(client *xmpp.Client, jserver string, filePath string) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var request IQHttpUploadSlotRequest
|
request := etree.NewDocument()
|
||||||
request.Xmlns = nsHttpUpload
|
requestReq := request.CreateElement("request")
|
||||||
request.FileName = fileNameEscaped
|
requestReq.CreateAttr("xmlns", nsHttpUpload)
|
||||||
request.FileSize = fileSize
|
requestReq.CreateAttr("filename", fileNameEscaped)
|
||||||
request.FileType = mimeType
|
requestReq.CreateAttr("size", fmt.Sprint(fileSize))
|
||||||
r, err := xml.Marshal(request)
|
requestReq.CreateAttr("content-type", mimeType)
|
||||||
|
r, err := request.WriteToString()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Request http upload slot
|
// Request http upload slot
|
||||||
uploadSlot, err := sendIQ(client, uploadComponent, "get", string(r))
|
uploadSlot, err := sendIQ(client, uploadComponent, "get", r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
if uploadSlot.Type != "result" {
|
if uploadSlot.Type != "result" {
|
||||||
log.Fatal("Error while requesting upload slot.")
|
log.Fatal("Error while requesting upload slot.")
|
||||||
}
|
}
|
||||||
err = xml.Unmarshal(uploadSlot.Query, &iqHttpUploadSlotXML)
|
iqHttpUploadSlotXML := etree.NewDocument()
|
||||||
|
err = iqHttpUploadSlotXML.ReadFromBytes(uploadSlot.Query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
iqHttpUploadSlotXMLSlot := iqHttpUploadSlotXML.SelectElement("slot")
|
||||||
|
iqHttpUploadSlotXMLPut := iqHttpUploadSlotXMLSlot.SelectElement("put")
|
||||||
|
iqHttpUploadSlotXMLPutURL := iqHttpUploadSlotXMLPut.SelectAttr("url")
|
||||||
|
|
||||||
// Upload file
|
// Upload file
|
||||||
httpClient := &http.Client{}
|
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 {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
req.Header.Set("Content-Type", mimeTypeEscaped.String())
|
req.Header.Set("Content-Type", mimeTypeEscaped.String())
|
||||||
for _, h := range iqHttpUploadSlotXML.Put.Headers {
|
iqHttpUploadSlotXMLPutHeaders := iqHttpUploadSlotXMLPut.SelectElements("header")
|
||||||
switch h.Name {
|
for _, h := range iqHttpUploadSlotXMLPutHeaders {
|
||||||
|
name := h.SelectAttr("name")
|
||||||
|
switch name.Value {
|
||||||
case "Authorization", "Cookie", "Expires":
|
case "Authorization", "Cookie", "Expires":
|
||||||
req.Header.Set(h.Name, h.Value)
|
req.Header.Set(name.Value, h.Text())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
resp, err := httpClient.Do(req)
|
resp, err := httpClient.Do(req)
|
||||||
@ -154,5 +176,7 @@ func httpUpload(client *xmpp.Client, jserver string, filePath string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Return http link
|
// Return http link
|
||||||
return iqHttpUploadSlotXML.Get.URL
|
iqHttpUploadSlotXMLGet := iqHttpUploadSlotXMLSlot.SelectElement("get")
|
||||||
|
iqHttpUploadSlotXMLGetURL := iqHttpUploadSlotXMLGet.SelectAttr("url")
|
||||||
|
return iqHttpUploadSlotXMLGetURL.Value
|
||||||
}
|
}
|
||||||
|
73
iqstructs.go
73
iqstructs.go
@ -1,73 +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"`
|
|
||||||
}
|
|
||||||
|
|
||||||
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"`
|
|
||||||
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"`
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user