// Package sRequest ----------------------------- // file : parser.go // author : JJXu // contact : wavingBear@163.com // time : 2022/12/10 00:48:45 // ------------------------------------------- package simpleRequest import ( "bytes" "encoding/json" "io" "mime/multipart" "os" "path/filepath" "strings" ) var bodyEntryParsers = map[string]IBodyEntryParser{ jsonContentType: new(JsonParser), formDataType: new(FormDataParser), } type IBodyEntryParser interface { Unmarshal(bodyType EntryMark, BodyEntry map[string]any) io.Reader } type JsonParser struct{} func (JsonParser) Unmarshal(bodyType EntryMark, BodyEntry map[string]any) io.Reader { switch bodyType { case StringEntryType: return strings.NewReader(BodyEntry[StringEntryType.string()].(string)) case BytesEntryType: return bytes.NewReader(BodyEntry[BytesEntryType.string()].([]byte)) case ModelEntryType: jsonData, err := json.Marshal(BodyEntry[ModelEntryType.string()]) if err == nil { return bytes.NewReader(jsonData) } return strings.NewReader("{}") case MapEntryType: jsonData, err := json.Marshal(BodyEntry) if err == nil { return bytes.NewReader(jsonData) } else { return strings.NewReader("{}") } default: if len(BodyEntry) > 0 { jsonData, err := json.Marshal(BodyEntry) if err == nil { return bytes.NewReader(jsonData) } } return strings.NewReader("{}") } } type FormDataParser struct { ContentType string } func (f *FormDataParser) Unmarshal(bodyType EntryMark, BodyEntry map[string]any) (body io.Reader) { switch bodyType { case MapEntryType: body, f.ContentType = multipartCommonParse(BodyEntry) case ModelEntryType: tb := BodyEntry[ModelEntryType.string()] buffer, err := json.Marshal(tb) if err != nil { panic(err.Error()) } var mapper map[string]any err = json.Unmarshal(buffer, &mapper) if err != nil { panic(err.Error()) } body, f.ContentType = multipartCommonParse(mapper) case StringEntryType: return strings.NewReader(BodyEntry[StringEntryType.string()].(string)) case BytesEntryType: return bytes.NewReader(BodyEntry[BytesEntryType.string()].([]byte)) default: body, f.ContentType = multipartCommonParse(BodyEntry) } return } func multipartCommonParse(BodyEntry map[string]any) (reader io.Reader, contentType string) { body := &bytes.Buffer{} writer := multipart.NewWriter(body) for k, sv := range BodyEntry { if strings.Contains(k, FormFilePathKey.string()) { key := k[len(FormFilePathKey):] path := sv.(string) filename := filepath.Base(path) filePart, _ := writer.CreateFormFile(key, filename) content, err := os.ReadFile(path) if err != nil { panic(err) } _, _ = filePart.Write(content) } else { switch sv.(type) { case string: strSv, _ := sv.(string) _ = writer.WriteField(k, strSv) case []string: sss, _ := sv.([]string) for _, v := range sss { _ = writer.WriteField(k, v) } case *multipart.FileHeader: file, _ := sv.(*multipart.FileHeader) filePart, _ := writer.CreateFormFile(k, file.Filename) src, err := file.Open() if err != nil { panic(err) return } defer src.Close() _, err = io.Copy(filePart, src) if err != nil { panic(err) return } } } } err := writer.Close() if err != nil { panic(err) } return body, writer.FormDataContentType() }