package requester import ( "fmt" "io" "mime/multipart" "path" ) type FormBuilder interface { CreateFormFile(fieldname string, fileHeader *multipart.FileHeader) error CreateFormFileReader(fieldname string, r io.Reader, filename string) error WriteField(fieldname, value string) error Close() error FormDataContentType() string } type DefaultFormBuilder struct { writer *multipart.Writer } func NewFormBuilder(body io.Writer) *DefaultFormBuilder { return &DefaultFormBuilder{ writer: multipart.NewWriter(body), } } func (fb *DefaultFormBuilder) CreateFormFile(fieldname string, fileHeader *multipart.FileHeader) error { file, err := fileHeader.Open() if err != nil { return err } defer file.Close() return fb.createFormFile(fieldname, file, fileHeader.Filename) } func (fb *DefaultFormBuilder) CreateFormFileReader(fieldname string, r io.Reader, filename string) error { return fb.createFormFile(fieldname, r, path.Base(filename)) } func (fb *DefaultFormBuilder) createFormFile(fieldname string, r io.Reader, filename string) error { if filename == "" { return fmt.Errorf("filename cannot be empty") } fieldWriter, err := fb.writer.CreateFormFile(fieldname, filename) if err != nil { return err } _, err = io.Copy(fieldWriter, r) if err != nil { return err } return nil } func (fb *DefaultFormBuilder) WriteField(fieldname, value string) error { return fb.writer.WriteField(fieldname, value) } func (fb *DefaultFormBuilder) Close() error { return fb.writer.Close() } func (fb *DefaultFormBuilder) FormDataContentType() string { return fb.writer.FormDataContentType() }