From 5a72ea681439dd22b56ea4c29bd8c58ef52dd751 Mon Sep 17 00:00:00 2001 From: Syfaro Date: Mon, 10 Aug 2015 07:41:44 -0500 Subject: [PATCH] switch to streaming multipart, reduces memory usage for uploads --- methods.go | 34 +++++++++------------------------- 1 file changed, 9 insertions(+), 25 deletions(-) diff --git a/methods.go b/methods.go index 7b25dc3..c345a96 100644 --- a/methods.go +++ b/methods.go @@ -1,14 +1,12 @@ package tgbotapi import ( - "bytes" "encoding/json" "errors" "fmt" - "io" + "github.com/technoweenie/multipartstreamer" "io/ioutil" "log" - "mime/multipart" "net/http" "net/url" "os" @@ -180,46 +178,32 @@ func (bot *BotAPI) MakeRequest(endpoint string, params url.Values) (APIResponse, // // Requires the parameter to hold the file not be in the params. func (bot *BotAPI) UploadFile(endpoint string, params map[string]string, fieldname string, filename string) (APIResponse, error) { - var b bytes.Buffer - w := multipart.NewWriter(&b) - f, err := os.Open(filename) if err != nil { return APIResponse{}, err } + defer f.Close() - fw, err := w.CreateFormFile(fieldname, filename) + fi, err := os.Stat(filename) if err != nil { return APIResponse{}, err } - if _, err = io.Copy(fw, f); err != nil { - return APIResponse{}, err - } - - for key, val := range params { - if fw, err = w.CreateFormField(key); err != nil { - return APIResponse{}, err - } - - if _, err = fw.Write([]byte(val)); err != nil { - return APIResponse{}, err - } - } - - w.Close() + ms := multipartstreamer.New() + ms.WriteFields(params) + ms.WriteReader(fieldname, f.Name(), fi.Size(), f) - req, err := http.NewRequest("POST", fmt.Sprintf(APIEndpoint, bot.Token, endpoint), &b) + req, err := http.NewRequest("POST", fmt.Sprintf(APIEndpoint, bot.Token, endpoint), nil) + ms.SetupRequest(req) if err != nil { return APIResponse{}, err } - req.Header.Set("Content-Type", w.FormDataContentType()) - res, err := bot.Client.Do(req) if err != nil { return APIResponse{}, err } + defer res.Body.Close() bytes, err := ioutil.ReadAll(res.Body) if err != nil {