@ -7,8 +7,8 @@ package main
import (
"bytes"
"encoding/xml"
"errors"
"fmt"
"log"
"net/http"
"net/url"
"os"
@ -25,21 +25,21 @@ import (
func httpUpload ( client * xmpp . Client , iqc chan xmpp . IQ , jserver string , filePath string ,
timeout time . Duration ,
) string {
) ( string , error ) {
var uploadComponent string
var maxFileSize int64
// Get file size
fileInfo , err := os . Stat ( filePath )
if err != nil {
log . Fatal ( err )
return "" , err
}
fileSize := fileInfo . Size ( )
// Read file
buffer , err := readFile ( filePath )
if err != nil {
log . Fatal ( err )
return "" , err
}
// Get mime type
@ -58,16 +58,16 @@ func httpUpload(client *xmpp.Client, iqc chan xmpp.IQ, jserver string, filePath
iqContent , err := sendIQ ( client , iqc , jserver , "get" ,
"<query xmlns='http://jabber.org/protocol/disco#items'/>" )
if err != nil {
log . Fatal ( err )
return "" , err
}
iqDiscoItemsXML := etree . NewDocument ( )
err = iqDiscoItemsXML . ReadFromBytes ( iqContent . Query )
if err != nil {
log . Fatal ( err )
return "" , err
}
iqDiscoItemsXMLQuery := iqDiscoItemsXML . SelectElement ( "query" )
if iqDiscoItemsXMLQuery == nil {
log . Fatal ( " no query element in disco items reply")
return "" , errors . New ( "http-upload: no query element in disco items reply")
}
iqDiscoItemsXMLItems := iqDiscoItemsXMLQuery . SelectElements ( "item" )
@ -80,11 +80,11 @@ func httpUpload(client *xmpp.Client, iqc chan xmpp.IQ, jserver string, filePath
iqDiscoInfoReqXMLQuery . CreateAttr ( "xmlns" , nsDiscoInfo )
iqdi , err := iqDiscoInfoReqXML . WriteToString ( )
if err != nil {
log . Fatal ( err )
return "" , err
}
iqDiscoInfo , err := sendIQ ( client , iqc , jid . Value , "get" , iqdi )
if err != nil {
log . Fatal ( err )
return "" , err
}
if iqDiscoInfo . Type != strResult {
continue
@ -92,7 +92,7 @@ func httpUpload(client *xmpp.Client, iqc chan xmpp.IQ, jserver string, filePath
iqDiscoInfoXML := etree . NewDocument ( )
err = iqDiscoInfoXML . ReadFromBytes ( iqDiscoInfo . Query )
if err != nil {
log . Fatal ( err )
return "" , err
}
iqDiscoInfoXMLQuery := iqDiscoInfoXML . SelectElement ( "query" )
if iqDiscoInfoXMLQuery == nil {
@ -116,9 +116,9 @@ func httpUpload(client *xmpp.Client, iqc chan xmpp.IQ, jserver string, filePath
}
}
if uploadComponent == "" {
log . Fatal ( "N o http upload component found.")
return "" , errors . New ( "http-upload: n o http upload component found.")
}
iqDiscoInfoXMLX := iqDiscoItemsXMLQuery . SelectElements ( " x ")
iqDiscoInfoXMLX := iqDiscoItemsXMLQuery . SelectElements ( " X ")
for _ , r := range iqDiscoInfoXMLX {
field := r . SelectElements ( "field" )
for i , t := range field {
@ -137,7 +137,7 @@ func httpUpload(client *xmpp.Client, iqc chan xmpp.IQ, jserver string, filePath
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.")
return "" , errors . New ( "http-upload: error while checking server maximum http upload file size.")
}
}
}
@ -147,7 +147,7 @@ func httpUpload(client *xmpp.Client, iqc chan xmpp.IQ, jserver string, filePath
// the best.
if maxFileSize != 0 {
if fileSize > maxFileSize {
log . Fatal ( "F ile size " + strconv . FormatInt ( fileSize / 1024 / 1024 , 10 ) +
return "" , errors . New ( "http-upload: f ile size " + strconv . FormatInt ( fileSize / 1024 / 1024 , 10 ) +
" MB is larger than the maximum file size allowed (" +
strconv . FormatInt ( maxFileSize / 1024 / 1024 , 10 ) + " MB)." )
}
@ -162,36 +162,36 @@ func httpUpload(client *xmpp.Client, iqc chan xmpp.IQ, jserver string, filePath
requestReq . CreateAttr ( "content-type" , mimeType )
r , err := request . WriteToString ( )
if err != nil {
log . Fatal ( err )
return "" , err
}
// Request http upload slot
uploadSlot , err := sendIQ ( client , iqc , uploadComponent , "get" , r )
if err != nil {
log . Fatal ( err )
return "" , err
}
if uploadSlot . Type != strResult {
log . Fatal ( " error while requesting upload slot.")
return "" , errors . New ( "http-upload: error while requesting upload slot.")
}
iqHTTPUploadSlotXML := etree . NewDocument ( )
err = iqHTTPUploadSlotXML . ReadFromBytes ( uploadSlot . Query )
if err != nil {
log . Fatal ( err )
return "" , err
}
iqHTTPUploadSlotXMLSlot := iqHTTPUploadSlotXML . SelectElement ( "slot" )
if iqHTTPUploadSlotXMLSlot == nil {
log . Fatal ( "http-upload: no slot element" )
return "" , errors . New ( "http-upload: no slot element" )
}
iqHTTPUploadSlotXMLPut := iqHTTPUploadSlotXMLSlot . SelectElement ( "put" )
if iqHTTPUploadSlotXMLPut == nil {
log . Fatal ( "http-upload: no put element" )
return "" , errors . New ( "http-upload: no put element" )
}
iqHTTPUploadSlotXMLPutURL := iqHTTPUploadSlotXMLPut . SelectAttr ( "url" )
if iqHTTPUploadSlotXMLPutURL == nil {
log . Fatal ( "http-upload: no url attribute" )
return "" , errors . New ( "http-upload: no url attribute" )
}
if ! strings . HasPrefix ( iqHTTPUploadSlotXMLPutURL . Value , "https://" ) {
log . Fatal ( "http-upload: upload slot does not provide https" )
return "" , errors . New ( "http-upload: upload slot does not provide https" )
}
// Upload file
httpTransport := & http . Transport {
@ -202,7 +202,7 @@ func httpUpload(client *xmpp.Client, iqc chan xmpp.IQ, jserver string, filePath
if proxyEnv != "" {
proxyURL , err := url . Parse ( proxyEnv )
if err != nil {
log . Fatal ( err )
return "" , err
}
httpTransport . Proxy = http . ProxyURL ( proxyURL )
}
@ -210,7 +210,7 @@ func httpUpload(client *xmpp.Client, iqc chan xmpp.IQ, jserver string, filePath
req , err := http . NewRequest ( http . MethodPut , iqHTTPUploadSlotXMLPutURL . Value ,
buffer )
if err != nil {
log . Fatal ( err )
return "" , err
}
req . Header . Set ( "Content-Type" , mimeTypeEscaped . String ( ) )
iqHTTPUploadSlotXMLPutHeaders := iqHTTPUploadSlotXMLPut . SelectElements ( "header" )
@ -226,25 +226,25 @@ func httpUpload(client *xmpp.Client, iqc chan xmpp.IQ, jserver string, filePath
}
resp , err := httpClient . Do ( req )
if err != nil {
log . Fatal ( err )
return "" , err
}
// Test for http status code "200 OK" or "201 Created"
if resp . StatusCode != 200 && resp . StatusCode != 201 {
log . Fatal ( "Http upload failed.")
return "" , errors . New ( "http-upload: upload failed.")
}
// Return http link
iqHTTPUploadSlotXMLGet := iqHTTPUploadSlotXMLSlot . SelectElement ( "get" )
if iqHTTPUploadSlotXMLGet == nil {
log . Fatal ( "http-upload: no get element" )
return "" , errors . New ( "http-upload: no get element" )
}
iqHTTPUploadSlotXMLGetURL := iqHTTPUploadSlotXMLGet . SelectAttr ( "url" )
if iqHTTPUploadSlotXMLGetURL == nil {
log . Fatal ( "http-upload: no url attribute" )
return "" , errors . New ( "http-upload: no url attribute" )
}
err = resp . Body . Close ( )
if err != nil {
fmt . Println ( "error while closing http request body:" , err )
}
return iqHTTPUploadSlotXMLGetURL . Value
return iqHTTPUploadSlotXMLGetURL . Value , nil
}