From 3b0249153241ae0c16e9f5a0dd095dfe56eae1cf Mon Sep 17 00:00:00 2001 From: Eric Chen Date: Wed, 9 Oct 2019 16:37:36 -0700 Subject: [PATCH] Attach file size to each multipart file converted to http request. Read/set size for each Readerfile on parsing file. --- multifilereader.go | 9 +++++++-- multipartfile.go | 22 +++++++++++++++++++--- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/multifilereader.go b/multifilereader.go index f6f225a..3bdc8fc 100644 --- a/multifilereader.go +++ b/multifilereader.go @@ -93,8 +93,6 @@ func (mfr *MultiFileReader) Read(buf []byte) (written int, err error) { dispositionPrefix = "form-data; name=\"file\"" } - header.Set("Content-Disposition", fmt.Sprintf("%s; filename=\"%s\"", dispositionPrefix, filename)) - var contentType string switch f := entry.Node().(type) { @@ -115,8 +113,15 @@ func (mfr *MultiFileReader) Read(buf []byte) (written int, err error) { header.Set("Content-Type", contentType) if rf, ok := entry.Node().(FileInfo); ok { header.Set("abspath", rf.AbsPath()) + // attach file size to content-disposition when available + // according to https://tools.ietf.org/html/rfc2183 + if stat := rf.Stat(); stat != nil { + dispositionPrefix += fmt.Sprintf("; size=%d", stat.Size()) + } } + header.Set("Content-Disposition", fmt.Sprintf("%s; filename=\"%s\"", dispositionPrefix, filename)) + _, err := mfr.mpWriter.CreatePart(header) if err != nil { return 0, err diff --git a/multipartfile.go b/multipartfile.go index d4593ad..d2480d5 100644 --- a/multipartfile.go +++ b/multipartfile.go @@ -7,6 +7,7 @@ import ( "mime/multipart" "net/url" "path" + "strconv" "strings" ) @@ -18,7 +19,8 @@ const ( applicationSymlink = "application/symlink" applicationFile = "application/octet-stream" - contentTypeHeader = "Content-Type" + contentTypeHeader = "Content-Type" + contentDispositionHeader = "Content-Disposition" ) type multipartDirectory struct { @@ -101,10 +103,24 @@ func (w *multipartWalker) nextFile() (Node, error) { return NewLinkFile(string(out), nil), nil default: - return &ReaderFile{ + rf := &ReaderFile{ reader: part, abspath: part.Header.Get("abspath"), - }, nil + } + cdh := part.Header.Get(contentDispositionHeader) + _, params, err := mime.ParseMediaType(cdh) + if err != nil { + return nil, err + } + // ignore if size is not available + if size, ok := params["size"]; ok { + fsize, err := strconv.ParseInt(size, 10, 64) + if err != nil { + return nil, err + } + rf.fsize = fsize + } + return rf, nil } }