Merge branch 'gin-gonic:master' into dev/strings_builder

This commit is contained in:
hopehook 2022-10-16 10:11:39 +08:00 committed by GitHub
commit 8489cb280c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 70 additions and 20 deletions

View File

@ -31,7 +31,7 @@ jobs:
strategy: strategy:
matrix: matrix:
os: [ubuntu-latest, macos-latest] os: [ubuntu-latest, macos-latest]
go: [1.15, 1.16, 1.17, 1.18] go: [1.16, 1.17, 1.18, 1.19]
test-tags: ['', '-tags nomsgpack', '-tags "sonic avx"', '-tags go_json'] test-tags: ['', '-tags nomsgpack', '-tags "sonic avx"', '-tags go_json']
include: include:
- os: ubuntu-latest - os: ubuntu-latest

View File

@ -19,7 +19,7 @@ jobs:
fetch-depth: 0 fetch-depth: 0
- -
name: Set up Go name: Set up Go
uses: actions/setup-go@v2 uses: actions/setup-go@v3
with: with:
go-version: 1.17 go-version: 1.17
- -

View File

@ -87,7 +87,7 @@ Gin is a web framework written in Go (Golang). It features a martini-like API wi
To install Gin package, you need to install Go and set your Go workspace first. To install Gin package, you need to install Go and set your Go workspace first.
1. You first need [Go](https://golang.org/) installed (**version 1.15+ is required**), then you can use the below Go command to install Gin. 1. You first need [Go](https://golang.org/) installed (**version 1.16+ is required**), then you can use the below Go command to install Gin.
```sh ```sh
go get -u github.com/gin-gonic/gin go get -u github.com/gin-gonic/gin

View File

@ -1107,9 +1107,7 @@ func testFormBindingForType(t *testing.T, method, path, badPath, body, badBody s
assert.Equal(t, assert.Equal(t,
struct { struct {
Idx int "form:\"idx\"" Idx int "form:\"idx\""
}(struct { }{Idx: 123},
Idx int "form:\"idx\""
}{Idx: 123}),
obj.StructFoo) obj.StructFoo)
case "StructPointer": case "StructPointer":
obj := FooStructForStructPointerType{} obj := FooStructForStructPointerType{}
@ -1118,9 +1116,7 @@ func testFormBindingForType(t *testing.T, method, path, badPath, body, badBody s
assert.Equal(t, assert.Equal(t,
struct { struct {
Name string "form:\"name\"" Name string "form:\"name\""
}(struct { }{Name: "thinkerou"},
Name string "form:\"name\""
}{Name: "thinkerou"}),
*obj.StructPointerFoo) *obj.StructPointerFoo)
case "Map": case "Map":
obj := FooStructForMapType{} obj := FooStructForMapType{}

View File

@ -19,7 +19,7 @@ import (
var ( var (
errUnknownType = errors.New("unknown type") errUnknownType = errors.New("unknown type")
// ErrConvertMapStringSlice can not covert to map[string][]string // ErrConvertMapStringSlice can not convert to map[string][]string
ErrConvertMapStringSlice = errors.New("can not convert to map slices of strings") ErrConvertMapStringSlice = errors.New("can not convert to map slices of strings")
// ErrConvertToMapString can not convert to map[string]string // ErrConvertToMapString can not convert to map[string]string

View File

@ -114,7 +114,7 @@ func TestMappingPrivateField(t *testing.T) {
} }
err := mappingByPtr(&s, formSource{"field": {"6"}}, "form") err := mappingByPtr(&s, formSource{"field": {"6"}}, "form")
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, int(0), s.f) assert.Equal(t, 0, s.f)
} }
func TestMappingUnknownFieldType(t *testing.T) { func TestMappingUnknownFieldType(t *testing.T) {
@ -133,7 +133,7 @@ func TestMappingURI(t *testing.T) {
} }
err := mapURI(&s, map[string][]string{"field": {"6"}}) err := mapURI(&s, map[string][]string{"field": {"6"}})
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, int(6), s.F) assert.Equal(t, 6, s.F)
} }
func TestMappingForm(t *testing.T) { func TestMappingForm(t *testing.T) {
@ -142,7 +142,7 @@ func TestMappingForm(t *testing.T) {
} }
err := mapForm(&s, map[string][]string{"field": {"6"}}) err := mapForm(&s, map[string][]string{"field": {"6"}})
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, int(6), s.F) assert.Equal(t, 6, s.F)
} }
func TestMapFormWithTag(t *testing.T) { func TestMapFormWithTag(t *testing.T) {
@ -151,7 +151,7 @@ func TestMapFormWithTag(t *testing.T) {
} }
err := MapFormWithTag(&s, map[string][]string{"field": {"6"}}, "externalTag") err := MapFormWithTag(&s, map[string][]string{"field": {"6"}}, "externalTag")
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, int(6), s.F) assert.Equal(t, 6, s.F)
} }
func TestMappingTime(t *testing.T) { func TestMappingTime(t *testing.T) {

View File

@ -15,6 +15,7 @@ import (
"net/http" "net/http"
"net/url" "net/url"
"os" "os"
"path/filepath"
"strings" "strings"
"sync" "sync"
"time" "time"
@ -601,6 +602,10 @@ func (c *Context) SaveUploadedFile(file *multipart.FileHeader, dst string) error
} }
defer src.Close() defer src.Close()
if err = os.MkdirAll(filepath.Dir(dst), 0750); err != nil {
return err
}
out, err := os.Create(dst) out, err := os.Create(dst)
if err != nil { if err != nil {
return err return err

View File

@ -12,6 +12,8 @@ import (
"mime/multipart" "mime/multipart"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"runtime"
"strings"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -28,6 +30,9 @@ func (i interceptedWriter) WriteHeader(code int) {
} }
func TestContextFormFileFailed17(t *testing.T) { func TestContextFormFileFailed17(t *testing.T) {
if !isGo117OrGo118() {
return
}
buf := new(bytes.Buffer) buf := new(bytes.Buffer)
mw := multipart.NewWriter(buf) mw := multipart.NewWriter(buf)
defer func(mw *multipart.Writer) { defer func(mw *multipart.Writer) {
@ -75,3 +80,15 @@ func TestInterceptedHeader(t *testing.T) {
assert.Equal(t, "", w.Result().Header.Get("X-Test")) assert.Equal(t, "", w.Result().Header.Get("X-Test"))
assert.Equal(t, "present", w.Result().Header.Get("X-Test-2")) assert.Equal(t, "present", w.Result().Header.Get("X-Test-2"))
} }
func isGo117OrGo118() bool {
version := strings.Split(runtime.Version()[2:], ".")
if len(version) >= 2 {
x := version[0]
y := version[1]
if x == "1" && (y == "17" || y == "18") {
return true
}
}
return false
}

31
context_1.19_test.go Normal file
View File

@ -0,0 +1,31 @@
// Copyright 2022 Gin Core Team. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
//go:build go1.19
// +build go1.19
package gin
import (
"bytes"
"mime/multipart"
"net/http"
"net/http/httptest"
"testing"
"github.com/stretchr/testify/assert"
)
func TestContextFormFileFailed19(t *testing.T) {
buf := new(bytes.Buffer)
mw := multipart.NewWriter(buf)
mw.Close()
c, _ := CreateTestContext(httptest.NewRecorder())
c.Request, _ = http.NewRequest("POST", "/", nil)
c.Request.Header.Set("Content-Type", mw.FormDataContentType())
c.engine.MaxMultipartMemory = 8 << 20
f, err := c.FormFile("file")
assert.Error(t, err)
assert.Nil(t, f)
}

View File

@ -12,7 +12,7 @@ import (
"strings" "strings"
) )
const ginSupportMinGoVer = 15 const ginSupportMinGoVer = 16
// IsDebugging returns true if the framework is running in debug mode. // IsDebugging returns true if the framework is running in debug mode.
// Use SetMode(gin.ReleaseMode) to disable debug mode. // Use SetMode(gin.ReleaseMode) to disable debug mode.
@ -67,7 +67,7 @@ func getMinVer(v string) (uint64, error) {
func debugPrintWARNINGDefault() { func debugPrintWARNINGDefault() {
if v, e := getMinVer(runtime.Version()); e == nil && v < ginSupportMinGoVer { if v, e := getMinVer(runtime.Version()); e == nil && v < ginSupportMinGoVer {
debugPrint(`[WARNING] Now Gin requires Go 1.15+. debugPrint(`[WARNING] Now Gin requires Go 1.16+.
`) `)
} }

View File

@ -104,7 +104,7 @@ func TestDebugPrintWARNINGDefault(t *testing.T) {
}) })
m, e := getMinVer(runtime.Version()) m, e := getMinVer(runtime.Version())
if e == nil && m < ginSupportMinGoVer { if e == nil && m < ginSupportMinGoVer {
assert.Equal(t, "[GIN-debug] [WARNING] Now Gin requires Go 1.15+.\n\n[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.\n\n", re) assert.Equal(t, "[GIN-debug] [WARNING] Now Gin requires Go 1.16+.\n\n[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.\n\n", re)
} else { } else {
assert.Equal(t, "[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.\n\n", re) assert.Equal(t, "[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.\n\n", re)
} }

2
go.mod
View File

@ -12,7 +12,7 @@ require (
github.com/pelletier/go-toml/v2 v2.0.2 github.com/pelletier/go-toml/v2 v2.0.2
github.com/stretchr/testify v1.8.0 github.com/stretchr/testify v1.8.0
github.com/ugorji/go/codec v1.2.7 github.com/ugorji/go/codec v1.2.7
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 golang.org/x/net v0.0.0-20221004154528-8021a29435af
google.golang.org/protobuf v1.28.1 google.golang.org/protobuf v1.28.1
gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v2 v2.4.0
) )

3
go.sum
View File

@ -81,8 +81,9 @@ golang.org/x/arch v0.0.0-20220412001346-fc48f9fe4c15 h1:GVfVkciLYxn5mY5EncwAe0SX
golang.org/x/arch v0.0.0-20220412001346-fc48f9fe4c15/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.0.0-20220412001346-fc48f9fe4c15/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 h1:0es+/5331RGQPcXlMfP+WrnIIS6dNnNRe0WB02W0F4M= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 h1:0es+/5331RGQPcXlMfP+WrnIIS6dNnNRe0WB02W0F4M=
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20221004154528-8021a29435af h1:wv66FM3rLZGPdxpYL+ApnDe2HzHcTFta3z5nsc13wI4=
golang.org/x/net v0.0.0-20221004154528-8021a29435af/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

View File

@ -173,7 +173,7 @@ func TestRenderAsciiJSON(t *testing.T) {
assert.Equal(t, "application/json", w1.Header().Get("Content-Type")) assert.Equal(t, "application/json", w1.Header().Get("Content-Type"))
w2 := httptest.NewRecorder() w2 := httptest.NewRecorder()
data2 := float64(3.1415926) data2 := 3.1415926
err = (AsciiJSON{data2}).Render(w2) err = (AsciiJSON{data2}).Render(w2)
assert.NoError(t, err) assert.NoError(t, err)