1 Star 2 Fork 1

孤爺仔/BaiduPCS-Go

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
multipartreader.go 3.21 KB
一键复制 编辑 原始数据 按行查看 历史
konica 提交于 2018-06-01 18:55 . 修复 bug, 更新文件上传
// Package multipartreader helps you encode large files in MIME multipart format
// without reading the entire content into memory.
package multipartreader
import (
"errors"
"fmt"
"github.com/iikira/BaiduPCS-Go/requester/rio"
"io"
"mime/multipart"
"strings"
"sync"
"sync/atomic"
)
type (
// MultipartReader MIME multipart format
MultipartReader struct {
length int64
contentType string
boundary string
formBody string
parts []*part
part64s []*part64
formClose string
mu sync.Mutex
closed bool
multiReader io.Reader
}
part struct {
form string
readerlen rio.ReaderLen
}
part64 struct {
form string
readerlen64 rio.ReaderLen64
}
)
// NewMultipartReader 返回初始化的 *MultipartReader
func NewMultipartReader() (mr *MultipartReader) {
builder := &strings.Builder{}
writer := multipart.NewWriter(builder)
mr = &MultipartReader{
contentType: writer.FormDataContentType(),
boundary: writer.Boundary(),
}
mr.length += int64(builder.Len())
mr.formBody = builder.String()
return
}
// AddFormFeild 增加 form 表单
func (mr *MultipartReader) AddFormFeild(fieldname string, readerlen rio.ReaderLen) {
mpart := &part{
form: fmt.Sprintf("--%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n", mr.boundary, fieldname),
readerlen: readerlen,
}
atomic.AddInt64(&mr.length, int64(len(mpart.form)+mpart.readerlen.Len()))
mr.parts = append(mr.parts, mpart)
}
// AddFormFile 增加 form 文件表单
func (mr *MultipartReader) AddFormFile(fieldname, filename string, readerlen64 rio.ReaderLen64) {
mpart64 := &part64{
form: fmt.Sprintf("--%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\n\r\n", mr.boundary, fieldname, filename),
readerlen64: readerlen64,
}
atomic.AddInt64(&mr.length, int64(len(mpart64.form))+mpart64.readerlen64.Len())
mr.part64s = append(mr.part64s, mpart64)
}
//CloseMultipart 关闭multipartreader
func (mr *MultipartReader) CloseMultipart() error {
mr.mu.Lock()
defer mr.mu.Unlock()
if mr.closed {
return errors.New("multipartreader already closed")
}
mr.formClose = "\r\n--" + mr.boundary + "--\r\n"
atomic.AddInt64(&mr.length, int64(len(mr.formClose)))
numReaders := 0
if mr.formBody != "" {
numReaders++
}
numReaders += 2*len(mr.parts) + 2*len(mr.part64s)
if mr.formClose != "" {
numReaders++
}
readers := make([]io.Reader, 0, numReaders)
readers = append(readers, strings.NewReader(mr.formBody))
for k := range mr.parts {
readers = append(readers, strings.NewReader(mr.parts[k].form), mr.parts[k].readerlen)
}
for k := range mr.part64s {
readers = append(readers, strings.NewReader(mr.part64s[k].form), mr.part64s[k].readerlen64)
}
readers = append(readers, strings.NewReader(mr.formClose))
mr.multiReader = io.MultiReader(readers...)
mr.closed = true
return nil
}
//ContentType 返回Content-Type
func (mr *MultipartReader) ContentType() string {
return mr.contentType
}
func (mr *MultipartReader) Read(p []byte) (n int, err error) {
if !mr.closed {
return 0, errors.New("multipartreader not closed")
}
n, err = mr.multiReader.Read(p)
return n, err
}
// Len 返回表单内容总长度
func (mr *MultipartReader) Len() int64 {
return atomic.LoadInt64(&mr.length)
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/guyezi/BaiduPCS-Go.git
git@gitee.com:guyezi/BaiduPCS-Go.git
guyezi
BaiduPCS-Go
BaiduPCS-Go
v3.5.6

搜索帮助

23e8dbc6 1850385 7e0993f3 1850385