mirror of
https://gitee.com/johng/gf
synced 2026-06-06 02:25:47 +08:00
improve urlencoding handling for parameters posted along with file uploading
This commit is contained in:
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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))
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user