diff --git a/multipart.go b/multipart.go index cb1b3af..6361de6 100644 --- a/multipart.go +++ b/multipart.go @@ -35,6 +35,11 @@ func createMultipart(postParams IBody, params []interface{}) { param.FieldName = "file0" } writeFormUploadFile(mwriter, param) + case UploadFile: + if param.FieldName == "" { + param.FieldName = "file0" + } + writeFormUploadFile(mwriter, ¶m) case []*UploadFile: for i, p := range param { if p.FieldName == "" { @@ -42,6 +47,13 @@ func createMultipart(postParams IBody, params []interface{}) { } writeFormUploadFile(mwriter, p) } + case []UploadFile: + for i, p := range param { + if p.FieldName == "" { + p.FieldName = "file" + strconv.Itoa(i) + } + writeFormUploadFile(mwriter, &p) + } case string: uploadFiles, err := UploadFileFromGlob(param) if err != nil { diff --git a/session.go b/session.go index eebb3ae..1d28ee4 100644 --- a/session.go +++ b/session.go @@ -134,15 +134,12 @@ const ( // TypeStream application/octet-stream 只能提交一个二进制流, 很少用 TypeStream = "application/octet-stream" - // TypeFormData 类型 + // TypeFormData 类型 Upload File 支持path(string) 自动转换成UploadFile TypeFormData = "multipart/form-data" // TypeMixed Mixed类型 TypeMixed = "multipart/mixed" - // TypeUploadFile 类型 Upload File 支持path(string) 自动转换成UploadFile - TypeUploadFile = "uploadfile/form-data" - // HeaderKeyHost Host HeaderKeyHost = "Host" diff --git a/session_test.go b/session_test.go index 2a3c3fb..6cd2e4a 100644 --- a/session_test.go +++ b/session_test.go @@ -169,7 +169,7 @@ func TestSession_PostUploadFile(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { ses := NewSession() - got, err := ses.Post("http://httpbin.org/post").SetBodyAuto(tt.args.params, TypeUploadFile).Execute() + got, err := ses.Post("http://httpbin.org/post").SetBodyAuto(tt.args.params, TypeFormData).Execute() if err != nil { t.Errorf("Metchod error = %v", err) @@ -213,7 +213,7 @@ func TestSession_Put(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { ses := NewSession() - got, err := ses.Put("http://httpbin.org/put").SetBodyAuto(tt.args.params, TypeUploadFile).Execute() + got, err := ses.Put("http://httpbin.org/put").SetBodyAuto(tt.args.params, TypeFormData).Execute() if err != nil { t.Errorf("Metchod error = %v", err) @@ -257,7 +257,7 @@ func TestSession_Patch(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { ses := NewSession() - got, err := ses.Patch("http://httpbin.org/patch").SetBodyAuto(tt.args.params, TypeUploadFile).Execute() + got, err := ses.Patch("http://httpbin.org/patch").SetBodyAuto(tt.args.params, TypeFormData).Execute() if err != nil { t.Errorf("Metchod error = %v", err) diff --git a/upload_file.go b/upload_file.go index e034e27..6690579 100644 --- a/upload_file.go +++ b/upload_file.go @@ -14,6 +14,51 @@ type UploadFile struct { FileReaderCloser io.ReadCloser } +// SetFileName 设置FileName属性 +func (ufile *UploadFile) SetFileName(filename string) { + ufile.FileName = filename +} + +// GetFileName 设置FileName属性 +func (ufile *UploadFile) GetFileName() string { + return ufile.FileName +} + +// SetFileReaderCloser 设置FileName属性 +func (ufile *UploadFile) SetFileReaderCloser(readerCloser io.ReadCloser) { + ufile.FileReaderCloser = readerCloser +} + +// SetFileReaderCloserFromFile 设置FileName属性 +func (ufile *UploadFile) SetFileReaderCloserFromFile(filename string) error { + fd, err := os.Open(filename) + if err != nil { + return err + } + ufile.SetFileReaderCloser(fd) + return nil +} + +// GetFileReaderCloser 设置FileName属性 +func (ufile *UploadFile) GetFileReaderCloser() io.ReadCloser { + return ufile.FileReaderCloser +} + +// SetFieldName 设置FileName属性 +func (ufile *UploadFile) SetFieldName(fieldname string) { + ufile.FieldName = fieldname +} + +// GetFieldName 设置FileName属性 +func (ufile *UploadFile) GetFieldName() string { + return ufile.FieldName +} + +// NewUploadFile 创建一个空的UploadFile, 必须设置 FileName FieldName FileReaderCloser 三个属性 +func NewUploadFile() *UploadFile { + return &UploadFile{} +} + // UploadFileFromPath 从本地文件获取上传文件 func UploadFileFromPath(fileName string) (*UploadFile, error) { fd, err := os.Open(fileName) diff --git a/upload_file_test.go b/upload_file_test.go index a7f4bbe..027a138 100644 --- a/upload_file_test.go +++ b/upload_file_test.go @@ -10,19 +10,53 @@ func TestUploadFile(t *testing.T) { ses := NewSession() wf := ses.Put("http://httpbin.org/put") - ufile, err := UploadFileFromPath("go.mod") + ufile, err := UploadFileFromPath("tests/json.file") if err != nil { t.Error(err) } - wf.SetBodyAuto(ufile, TypeUploadFile) + wf.SetBodyAuto(ufile, TypeFormData) resp, _ := wf.Execute() if _, ok := gjson.Get(resp.Content(), "files").Map()["file0"]; !ok { t.Error("file error", resp.Content()) } - wf.SetBodyAuto("go.mod", TypeUploadFile) + wf.SetBodyAuto("tests/json.file", TypeFormData) resp, _ = wf.Execute() if _, ok := gjson.Get(resp.Content(), "files").Map()["file0"]; !ok { t.Error("file error", resp.Content()) } + + ufile = NewUploadFile() + ufile.SetFileName("MyFile") + ufile.SetFieldName("MyField") + ufile.SetFileReaderCloserFromFile("tests/json.file") + wf.SetBodyAuto(ufile) + resp, _ = wf.Execute() + if _, ok := gjson.Get(resp.Content(), "files").Map()["MyField"]; !ok { + t.Error("file error", resp.Content()) + } + + ufile.SetFileReaderCloserFromFile("tests/json.file") + wf.SetBodyAuto(*ufile) + resp, _ = wf.Execute() + if _, ok := gjson.Get(resp.Content(), "files").Map()["MyField"]; !ok { + t.Error("file error", resp.Content()) + } + + ufile = NewUploadFile() + ufile.SetFileName("MyFile") + ufile.SetFileReaderCloserFromFile("tests/json.file") + wf.SetBodyAuto(ufile) + resp, _ = wf.Execute() + if _, ok := gjson.Get(resp.Content(), "files").Map()["file0"]; !ok { + t.Error("file error", resp.Content()) + } + + ufile.SetFileReaderCloserFromFile("tests/json.file") + wf.SetBodyAuto(*ufile) + resp, _ = wf.Execute() + if _, ok := gjson.Get(resp.Content(), "files").Map()["MyField"]; !ok { + t.Error("file error", resp.Content()) + } + } diff --git a/workflow.go b/workflow.go index 33da19e..989515e 100644 --- a/workflow.go +++ b/workflow.go @@ -225,14 +225,10 @@ func (wf *Workflow) SetBodyAuto(params ...interface{}) *Workflow { defaultContentType = t.(string) } - if defaultContentType == TypeUploadFile { - wf.Body.SetPrefix(TypeFormData) - } else { - wf.Body.SetPrefix(defaultContentType) - } + wf.Body.SetPrefix(defaultContentType) switch defaultContentType { - case TypeUploadFile: + case TypeFormData: createMultipart(wf.Body, params) // 还存在 Mixed的可能 default: var values url.Values @@ -250,6 +246,23 @@ func (wf *Workflow) SetBodyAuto(params ...interface{}) *Workflow { wf.Body.SetIOBody([]byte(param)) case []byte: wf.Body.SetIOBody(param) + + case *UploadFile: + params = append(params, TypeFormData) + wf.Body.SetPrefix(TypeFormData) + createMultipart(wf.Body, params) + case UploadFile: + params = append(params, TypeFormData) + wf.Body.SetPrefix(TypeFormData) + createMultipart(wf.Body, params) + case []*UploadFile: + params = append(params, TypeFormData) + wf.Body.SetPrefix(TypeFormData) + createMultipart(wf.Body, params) + case []UploadFile: + params = append(params, TypeFormData) + wf.Body.SetPrefix(TypeFormData) + createMultipart(wf.Body, params) } }