Ai
1 Star 0 Fork 0

k3x/go

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
request_body_multipart.go 2.06 KB
一键复制 编辑 原始数据 按行查看 历史
k3x 提交于 2022-01-05 06:05 +08:00 . init
package urlx
import (
"context"
"io"
"mime/multipart"
"net/url"
"os"
"path/filepath"
"sync"
)
type MultipartBody struct {
getFile func() (field, filename string, fileBody io.ReadCloser, err error)
params url.Values
w *io.PipeWriter
r *io.PipeReader
mw *multipart.Writer
done chan error
once sync.Once
}
func Multipart() *MultipartBody {
return &MultipartBody{}
}
func (m *MultipartBody) Params(params url.Values) *MultipartBody {
m.params = params
return m
}
func (m *MultipartBody) File(getFile func() (field, filename string, fileBody io.ReadCloser, err error)) *MultipartBody {
m.getFile = getFile
return m
}
func (m *MultipartBody) LocalFile(field string, filename string) *MultipartBody {
m.getFile = func() (field string, filename string, fileBody io.ReadCloser, err error) {
name := filepath.Base(filename)
f, err := os.Open(filename)
if err != nil {
return field, name, nil, err
}
return field, name, f, nil
}
return m
}
func (m *MultipartBody) Body() (contentType string, body io.Reader, err error) {
m.once.Do(m.init)
return m.mw.FormDataContentType(), io.NopCloser(m.r), nil
}
func (m *MultipartBody) WaitEnd(ctx context.Context) error {
m.once.Do(m.init)
select {
case <-ctx.Done():
return ctx.Err()
case err := <-m.done:
return err
}
}
func (m *MultipartBody) init() {
m.r, m.w = io.Pipe()
m.mw = multipart.NewWriter(m.w)
m.done = make(chan error, 1)
go func() {
defer close(m.done)
defer m.w.Close()
defer m.r.Close()
m.done <- m.readFile()
}()
}
func (m *MultipartBody) readFile() error {
for key, values := range m.params {
for _, value := range values {
if err := m.mw.WriteField(key, value); err != nil {
return err
}
}
}
field, filename, fileBody, err := m.getFile()
if err != nil {
return err
}
defer func() {
if closer, ok := fileBody.(io.Closer); ok {
closer.Close()
}
}()
formFile, err := m.mw.CreateFormFile(field, filepath.Base(filename))
if err != nil {
return err
}
if _, err := io.Copy(formFile, fileBody); err != nil {
return err
}
return m.mw.Close()
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/k3x/go.git
git@gitee.com:k3x/go.git
k3x
go
go
82f96e922e7b

搜索帮助