improve urlencoding handling for parameters posted along with file uploading

This commit is contained in:
John
2020-10-26 20:21:09 +08:00
parent 87650557fd
commit cee67a8d4e
3 changed files with 25 additions and 8 deletions

View File

@ -123,7 +123,7 @@ func (c *Client) DoRequest(method, url string, data ...interface{}) (resp *Clien
param = BuildParams(data[0])
}
}
req := (*http.Request)(nil)
var req *http.Request
if strings.Contains(param, "@file:") {
// File uploading request.
buffer := new(bytes.Buffer)

View File

@ -8,12 +8,17 @@ package ghttp
import (
"github.com/gogf/gf/errors/gerror"
"github.com/gogf/gf/text/gstr"
"strings"
"github.com/gogf/gf/encoding/gurl"
"github.com/gogf/gf/util/gconv"
)
const (
fileUploadingKey = "@file:"
)
// BuildParams builds the request string for the http client. The <params> can be type of:
// string/[]byte/map/struct/*struct.
//
@ -38,13 +43,22 @@ func BuildParams(params interface{}, noUrlEncode ...bool) (encodedParamStr strin
if len(noUrlEncode) == 1 {
urlEncode = !noUrlEncode[0]
}
// If there's file uploading, it ignores the url encoding.
if urlEncode {
for k, v := range m {
if gstr.Contains(k, fileUploadingKey) || gstr.Contains(gconv.String(v), fileUploadingKey) {
urlEncode = false
break
}
}
}
s := ""
for k, v := range m {
if len(encodedParamStr) > 0 {
encodedParamStr += "&"
}
s = gconv.String(v)
if urlEncode && len(s) > 6 && strings.Compare(s[0:6], "@file:") != 0 {
if urlEncode && len(s) > 6 && strings.Compare(s[0:6], fileUploadingKey) != 0 {
s = gurl.Encode(s)
}
encodedParamStr += k + "=" + s

View File

@ -295,6 +295,8 @@ func Test_Client_Param_Containing_Special_Char(t *testing.T) {
})
}
// It posts data along with file uploading.
// It does not url-encodes the parameters.
func Test_Client_File_And_Param(t *testing.T) {
p, _ := ports.PopRand()
s := g.Server(p)
@ -308,7 +310,7 @@ func Test_Client_File_And_Param(t *testing.T) {
_, err = file.Save(tmpPath)
gtest.Assert(err, nil)
r.Response.Write(
r.Get("key"),
r.Get("json"),
gfile.GetContents(gfile.Join(tmpPath, gfile.Basename(file.Filename))),
)
})
@ -320,12 +322,13 @@ func Test_Client_File_And_Param(t *testing.T) {
time.Sleep(100 * time.Millisecond)
gtest.C(t, func(t *gtest.T) {
path := gdebug.TestDataPath("upload", "file1.txt")
data := g.Map{
"file": "@file:" + path,
"json": `{"uuid": "luijquiopm", "isRelative": false, "fileName": "test111.xls"}`,
}
c := g.Client()
c.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", p))
filePath := gdebug.TestDataPath("upload", "file1.txt")
t.Assert(
c.PostContent("/", "key=1&file=@file:"+filePath),
"1"+gfile.GetContents(filePath),
)
t.Assert(c.PostContent("/", data), data["json"].(string)+gfile.GetContents(path))
})
}