参考自:
https://blog.csdn.net/u011304970/article/details/71081984
https://blog.cyeam.com/go/2019/03/15/form-post
func TestPicUpload(t *testing.T) {
// 签名
keyMap := make(map[string]string)
keyMap["version"] = "1.0"
keyMap["clientCode"] = "48310016"
keyMap["picMode"] = "01"
signature := GetSignature(keyMap, "fudhsyrgnbpdeibh") // A6004E72EE46C6A97451EBD7543EA58F
buf := new(bytes.Buffer)
writer := multipart.NewWriter(buf)
_ = writer.WriteField("version", "1.0")
_ = writer.WriteField("clientCode", "48310016")
_ = writer.WriteField("picMode", "01")
_ = writer.WriteField("MAC", signature) // 不参与签名
formFile, err := writer.CreateFormFile("fileName", "test.jpg") // 不参与签名
if err != nil {
t.Fatalf("create form file failed: %s", err)
}
// 从文件读取数据,写入表单
srcFile, err := os.Open("test.jpg")
if err != nil {
t.Fatalf("open source file failed: %s", err)
}
defer srcFile.Close()
_, err = io.Copy(formFile, srcFile)
if err != nil {
t.Fatalf("write to form file falied: %s", err)
}
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
req, err := http.NewRequest("POST", "https://.../imgUpl", buf)
if err != nil {
fmt.Println("发送报文失败", err)
return
}
req.Header.Set("Content-Type", writer.FormDataContentType())
client := &http.Client{Transport: tr, Timeout: time.Second * time.Duration(60)}
writer.Close()
resp, err := client.Do(req)
if err != nil {
fmt.Println("发送请求失败:", err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
t.Fatalf("readAll falied: %s", err)
}
t.Logf("body: %s", string(body))
assert.Equal(t, 200, resp.StatusCode)
}
func GetSignature(keyMap map[string]string, key string) string {
keySli := make([]string, 0)
for key := range keyMap {
keySli = append(keySli, key)
}
sort.Strings(keySli)
keySli = append(keySli, "key")
keyMap["key"] = key
var signBody string
for _, k := range keySli {
signBody += fmt.Sprintf("%s=%s&", k, keyMap[k])
}
signBody = signBody[:len(signBody)-1]
res := md5.Sum([]byte(signBody))
return strings.ToUpper(hex.EncodeToString(res[:]))
}