mirror of
https://gitee.com/johng/gf
synced 2026-07-06 21:45:34 +08:00
@ -1,6 +1,6 @@
|
||||
## This file contains all available configuration options
|
||||
## with their default values.
|
||||
#
|
||||
|
||||
# See https://github.com/golangci/golangci-lint#config-file
|
||||
run:
|
||||
issues-exit-code: 1 #Default
|
||||
|
||||
@ -16,6 +16,7 @@ import (
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/internal/intlog"
|
||||
"github.com/gogf/gf/v2/internal/json"
|
||||
"github.com/gogf/gf/v2/os/gfile"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/util/grand"
|
||||
@ -27,6 +28,11 @@ type UploadFile struct {
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
// MarshalJSON implements the interface MarshalJSON for json.Marshal.
|
||||
func (f UploadFile) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(f.FileHeader)
|
||||
}
|
||||
|
||||
// UploadFiles is an array type of *UploadFile.
|
||||
type UploadFiles []*UploadFile
|
||||
|
||||
|
||||
@ -216,3 +216,39 @@ func Test_Params_Strict_Route_File_Single(t *testing.T) {
|
||||
t.Assert(gfile.GetContents(dstPath), gfile.GetContents(srcPath))
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Params_File_Upload_Required(t *testing.T) {
|
||||
type Req struct {
|
||||
gmeta.Meta `method:"post" mime:"multipart/form-data"`
|
||||
File *ghttp.UploadFile `type:"file" v:"required#upload file is required"`
|
||||
}
|
||||
type Res struct{}
|
||||
|
||||
dstDirPath := gfile.Temp(gtime.TimestampNanoStr())
|
||||
s := g.Server(guid.S())
|
||||
s.BindHandler("/upload/required", func(ctx context.Context, req *Req) (res *Res, err error) {
|
||||
var (
|
||||
r = g.RequestFromCtx(ctx)
|
||||
)
|
||||
|
||||
file := req.File
|
||||
if name, err := file.Save(dstDirPath); err == nil {
|
||||
r.Response.WriteExit(name)
|
||||
}
|
||||
r.Response.WriteExit("upload failed")
|
||||
return
|
||||
})
|
||||
s.SetDumpRouterMap(false)
|
||||
s.Start()
|
||||
defer s.Shutdown()
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
// file is empty
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
client := g.Client()
|
||||
client.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", s.GetListenedPort()))
|
||||
_, err := client.Post(ctx, "/upload/required")
|
||||
if err != nil {
|
||||
t.Assert(err.Error(), "upload file is required")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@ -79,7 +79,7 @@ func Bytes(any interface{}) []byte {
|
||||
ok = true
|
||||
bytes = make([]byte, originValueAndKind.OriginValue.Len())
|
||||
)
|
||||
for i, _ := range bytes {
|
||||
for i := range bytes {
|
||||
int32Value := Int32(originValueAndKind.OriginValue.Index(i).Interface())
|
||||
if int32Value < 0 || int32Value > math.MaxUint8 {
|
||||
ok = false
|
||||
@ -112,7 +112,7 @@ func Runes(any interface{}) []rune {
|
||||
}
|
||||
|
||||
// String converts `any` to string.
|
||||
// It's most commonly used converting function.
|
||||
// It's most commonly used converting function
|
||||
func String(any interface{}) string {
|
||||
if any == nil {
|
||||
return ""
|
||||
|
||||
@ -53,7 +53,6 @@ func Scan(params interface{}, pointer interface{}, mapping ...map[string]string)
|
||||
pointerType,
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
// Direct assignment checks!
|
||||
var (
|
||||
|
||||
@ -66,7 +66,7 @@ func IsEmpty(value interface{}) bool {
|
||||
func Keys(mapOrStruct interface{}) (keysOrAttrs []string) {
|
||||
keysOrAttrs = make([]string, 0)
|
||||
if m, ok := mapOrStruct.(map[string]interface{}); ok {
|
||||
for k, _ := range m {
|
||||
for k := range m {
|
||||
keysOrAttrs = append(keysOrAttrs, k)
|
||||
}
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user