From d984e3df4c59efccf5b5f41f79659149abbd39e3 Mon Sep 17 00:00:00 2001 From: mappu Date: Sat, 9 Jun 2018 12:19:27 +1200 Subject: [PATCH] contented: replace octet-stream mime types with autodetected one, if possible; add timestamp to filenames --- contented.go | 43 +++++++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/contented.go b/contented.go index e27ca3a..0807df3 100644 --- a/contented.go +++ b/contented.go @@ -11,8 +11,10 @@ import ( "mime/multipart" "net/http" "net/textproto" + "time" telegram "github.com/go-telegram-bot-api/telegram-bot-api" + filetype "gopkg.in/h2non/filetype.v1" ) func (this *NTFServer) ContentedEnabled() bool { @@ -79,17 +81,39 @@ func (this *NTFServer) ContentedUploadSync(fileId string, expectSizeBytes int64) } defer resp.Body.Close() - // Determine a suitable pseudo-filename from the telegram content-type - - fileContentType := resp.Header.Get("Content-Type") // is it blank? who knows? - if this.verbose { log.Printf("Downloaded telegram file response headers: %#v\n", resp.Header) } - fileName := "telegram-upload" - if fileExts, err := mime.ExtensionsByType(fileContentType); err == nil && len(fileExts) > 0 { - fileName += fileExts[0] // Just pick the first one. They all contain a leading period + // Download + fileBuff := bytes.Buffer{} + _, err = io.CopyN(&fileBuff, resp.Body, expectSizeBytes) // CopyN asserts either err!=nil, or copiedBytes == expectSizeBytes. So we're safe + if err != nil { + return "", fmt.Errorf("CopyN: %s", err.Error()) + } + + // Determine a suitable pseudo-filename from the telegram content-type + // Telegram seems to always supply application/octet-stream + // If Telegram gives us something else, trust it; but otherwise, we can probably do better + + fileName := fmt.Sprintf("telegram-upload-%d", time.Now().Unix()) + fileContentType := resp.Header.Get("Content-Type") // is it blank? who knows? + + if fileContentType == `application/octet-stream` || fileContentType == `` { + + // Autodetect something better, if possible + if contentTypeMatches, err := filetype.Match(fileBuff.Bytes()); err == nil { + fileContentType = contentTypeMatches.MIME.Value + fileName += `.` + contentTypeMatches.Extension // no leading period + } + + } else { + + // We were supplied a good mime type, just need to find a good file extension + if fileExts, err := mime.ExtensionsByType(fileContentType); err == nil && len(fileExts) > 0 { + fileName += fileExts[0] // Just pick the first one. They all contain a leading period + } + } // Contented uploads are in multipart mime format @@ -105,10 +129,9 @@ func (this *NTFServer) ContentedUploadSync(fileId string, expectSizeBytes int64) return "", err } - // Download - _, err = io.CopyN(filePart, resp.Body, expectSizeBytes) // CopyN asserts either err!=nil, or copiedBytes == expectSizeBytes. So we're safe + _, err = io.CopyN(filePart, bytes.NewReader(fileBuff.Bytes()), expectSizeBytes) if err != nil { - return "", fmt.Errorf("CopyN: %s", err.Error()) + return "", err } // Upload