mirror of
https://github.com/gin-gonic/gin.git
synced 2025-10-24 02:32:17 +08:00
Merge branch 'master' into struct
This commit is contained in:
commit
9863ae8019
@ -540,7 +540,7 @@ import (
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gin-gonic/gin/binding"
|
||||
validator "gopkg.in/go-playground/validator.v8"
|
||||
"gopkg.in/go-playground/validator.v8"
|
||||
)
|
||||
|
||||
type Booking struct {
|
||||
|
@ -59,8 +59,6 @@ func BenchmarkOneRouteJSON(B *testing.B) {
|
||||
runRequest(B, router, "GET", "/json")
|
||||
}
|
||||
|
||||
var htmlContentType = []string{"text/html; charset=utf-8"}
|
||||
|
||||
func BenchmarkOneRouteHTML(B *testing.B) {
|
||||
router := New()
|
||||
t := template.Must(template.New("index").Parse(`
|
||||
|
@ -179,12 +179,3 @@ func setTimeField(val string, structField reflect.StructField, value reflect.Val
|
||||
value.Set(reflect.ValueOf(t))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Don't pass in pointers to bind to. Can lead to bugs. See:
|
||||
// https://github.com/codegangsta/martini-contrib/issues/40
|
||||
// https://github.com/codegangsta/martini-contrib/pull/34#issuecomment-29683659
|
||||
func ensureNotPointer(obj interface{}) {
|
||||
if reflect.TypeOf(obj).Kind() == reflect.Ptr {
|
||||
panic("Pointers are not accepted as binding models")
|
||||
}
|
||||
}
|
||||
|
@ -676,6 +676,7 @@ func TestContextRenderNoContentSecureJSON(t *testing.T) {
|
||||
func TestContextRenderHTML(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
c, router := CreateTestContext(w)
|
||||
|
||||
templ := template.Must(template.New("t").Parse(`Hello {{.name}}`))
|
||||
router.SetHTMLTemplate(templ)
|
||||
|
||||
@ -686,6 +687,30 @@ func TestContextRenderHTML(t *testing.T) {
|
||||
assert.Equal(t, "text/html; charset=utf-8", w.HeaderMap.Get("Content-Type"))
|
||||
}
|
||||
|
||||
func TestContextRenderHTML2(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
c, router := CreateTestContext(w)
|
||||
|
||||
// print debug warning log when Engine.trees > 0
|
||||
router.addRoute("GET", "/", HandlersChain{func(_ *Context) {}})
|
||||
assert.Len(t, router.trees, 1)
|
||||
|
||||
var b bytes.Buffer
|
||||
setup(&b)
|
||||
defer teardown()
|
||||
|
||||
templ := template.Must(template.New("t").Parse(`Hello {{.name}}`))
|
||||
router.SetHTMLTemplate(templ)
|
||||
|
||||
assert.Equal(t, "[GIN-debug] [WARNING] Since SetHTMLTemplate() is NOT thread-safe. It should only be called\nat initialization. ie. before any route is registered or the router is listening in a socket:\n\n\trouter := gin.Default()\n\trouter.SetHTMLTemplate(template) // << good place\n\n", b.String())
|
||||
|
||||
c.HTML(201, "t", H{"name": "alexandernyquist"})
|
||||
|
||||
assert.Equal(t, 201, w.Code)
|
||||
assert.Equal(t, "Hello alexandernyquist", w.Body.String())
|
||||
assert.Equal(t, "text/html; charset=utf-8", w.HeaderMap.Get("Content-Type"))
|
||||
}
|
||||
|
||||
// Tests that no HTML is rendered if code is 204
|
||||
func TestContextRenderNoContentHTML(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
|
31
deprecated_test.go
Normal file
31
deprecated_test.go
Normal file
@ -0,0 +1,31 @@
|
||||
// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
|
||||
// Use of this source code is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package gin
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/gin-gonic/gin/binding"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestBindWith(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := CreateTestContext(w)
|
||||
|
||||
c.Request, _ = http.NewRequest("POST", "/?foo=bar&bar=foo", bytes.NewBufferString("foo=unused"))
|
||||
|
||||
var obj struct {
|
||||
Foo string `form:"foo"`
|
||||
Bar string `form:"bar"`
|
||||
}
|
||||
assert.NoError(t, c.BindWith(&obj, binding.Form))
|
||||
assert.Equal(t, "foo", obj.Bar)
|
||||
assert.Equal(t, "bar", obj.Foo)
|
||||
assert.Equal(t, 0, w.Body.Len())
|
||||
}
|
@ -148,7 +148,7 @@ func (a errorMsgs) String() string {
|
||||
}
|
||||
var buffer bytes.Buffer
|
||||
for i, msg := range a {
|
||||
fmt.Fprintf(&buffer, "Error #%02d: %s\n", (i + 1), msg.Err)
|
||||
fmt.Fprintf(&buffer, "Error #%02d: %s\n", i+1, msg.Err)
|
||||
if msg.Meta != nil {
|
||||
fmt.Fprintf(&buffer, " Meta: %v\n", msg.Meta)
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gin-gonic/gin/binding"
|
||||
validator "gopkg.in/go-playground/validator.v8"
|
||||
"gopkg.in/go-playground/validator.v8"
|
||||
)
|
||||
|
||||
type Booking struct {
|
||||
|
@ -29,8 +29,8 @@ func statsWorker() {
|
||||
"timestamp": uint64(time.Now().Unix()),
|
||||
"HeapInuse": stats.HeapInuse,
|
||||
"StackInuse": stats.StackInuse,
|
||||
"Mallocs": (stats.Mallocs - lastMallocs),
|
||||
"Frees": (stats.Frees - lastFrees),
|
||||
"Mallocs": stats.Mallocs - lastMallocs,
|
||||
"Frees": stats.Frees - lastFrees,
|
||||
"Inbound": uint64(messages.Get("inbound")),
|
||||
"Outbound": uint64(messages.Get("outbound")),
|
||||
"Connected": connectedUsers(),
|
||||
|
21
gin.go
21
gin.go
@ -49,16 +49,6 @@ type RoutesInfo []RouteInfo
|
||||
// Create an instance of Engine, by using New() or Default()
|
||||
type Engine struct {
|
||||
RouterGroup
|
||||
delims render.Delims
|
||||
secureJsonPrefix string
|
||||
HTMLRender render.HTMLRender
|
||||
FuncMap template.FuncMap
|
||||
allNoRoute HandlersChain
|
||||
allNoMethod HandlersChain
|
||||
noRoute HandlersChain
|
||||
noMethod HandlersChain
|
||||
pool sync.Pool
|
||||
trees methodTrees
|
||||
|
||||
// Enables automatic redirection if the current route can't be matched but a
|
||||
// handler for the path with (without) the trailing slash exists.
|
||||
@ -102,6 +92,17 @@ type Engine struct {
|
||||
// Value of 'maxMemory' param that is given to http.Request's ParseMultipartForm
|
||||
// method call.
|
||||
MaxMultipartMemory int64
|
||||
|
||||
delims render.Delims
|
||||
secureJsonPrefix string
|
||||
HTMLRender render.HTMLRender
|
||||
FuncMap template.FuncMap
|
||||
allNoRoute HandlersChain
|
||||
allNoMethod HandlersChain
|
||||
noRoute HandlersChain
|
||||
noMethod HandlersChain
|
||||
pool sync.Pool
|
||||
trees methodTrees
|
||||
}
|
||||
|
||||
var _ IRouter = &Engine{}
|
||||
|
@ -94,7 +94,7 @@ func TestUnixSocket(t *testing.T) {
|
||||
c, err := net.Dial("unix", "/tmp/unix_unit_test")
|
||||
assert.NoError(t, err)
|
||||
|
||||
fmt.Fprintf(c, "GET /example HTTP/1.0\r\n\r\n")
|
||||
fmt.Fprint(c, "GET /example HTTP/1.0\r\n\r\n")
|
||||
scanner := bufio.NewScanner(c)
|
||||
var response string
|
||||
for scanner.Scan() {
|
||||
|
6
mode.go
6
mode.go
@ -14,9 +14,9 @@ import (
|
||||
const ENV_GIN_MODE = "GIN_MODE"
|
||||
|
||||
const (
|
||||
DebugMode string = "debug"
|
||||
ReleaseMode string = "release"
|
||||
TestMode string = "test"
|
||||
DebugMode = "debug"
|
||||
ReleaseMode = "release"
|
||||
TestMode = "test"
|
||||
)
|
||||
const (
|
||||
debugCode = iota
|
||||
|
14
tree.go
14
tree.go
@ -87,13 +87,13 @@ const (
|
||||
|
||||
type node struct {
|
||||
path string
|
||||
wildChild bool
|
||||
nType nodeType
|
||||
maxParams uint8
|
||||
indices string
|
||||
children []*node
|
||||
handlers HandlersChain
|
||||
priority uint32
|
||||
nType nodeType
|
||||
maxParams uint8
|
||||
wildChild bool
|
||||
}
|
||||
|
||||
// increments priority of the given child and reorders if necessary.
|
||||
@ -384,7 +384,7 @@ walk: // Outer loop for walking the tree
|
||||
// Nothing found.
|
||||
// We can recommend to redirect to the same URL without a
|
||||
// trailing slash if a leaf exists for that path.
|
||||
tsr = (path == "/" && n.handlers != nil)
|
||||
tsr = path == "/" && n.handlers != nil
|
||||
return
|
||||
}
|
||||
|
||||
@ -424,7 +424,7 @@ walk: // Outer loop for walking the tree
|
||||
}
|
||||
|
||||
// ... but we can't
|
||||
tsr = (len(path) == end+1)
|
||||
tsr = len(path) == end+1
|
||||
return
|
||||
}
|
||||
|
||||
@ -435,7 +435,7 @@ walk: // Outer loop for walking the tree
|
||||
// No handle found. Check if a handle for this path + a
|
||||
// trailing slash exists for TSR recommendation
|
||||
n = n.children[0]
|
||||
tsr = (n.path == "/" && n.handlers != nil)
|
||||
tsr = n.path == "/" && n.handlers != nil
|
||||
}
|
||||
|
||||
return
|
||||
@ -530,7 +530,7 @@ func (n *node) findCaseInsensitivePath(path string, fixTrailingSlash bool) (ciPa
|
||||
|
||||
// Nothing found. We can recommend to redirect to the same URL
|
||||
// without a trailing slash if a leaf exists for that path
|
||||
found = (fixTrailingSlash && path == "/" && n.handlers != nil)
|
||||
found = fixTrailingSlash && path == "/" && n.handlers != nil
|
||||
return
|
||||
}
|
||||
|
||||
|
11
tree_test.go
11
tree_test.go
@ -5,22 +5,11 @@
|
||||
package gin
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func printChildren(n *node, prefix string) {
|
||||
fmt.Printf(" %02d:%02d %s%s[%d] %v %t %d \r\n", n.priority, n.maxParams, prefix, n.path, len(n.children), n.handlers, n.wildChild, n.nType)
|
||||
for l := len(n.path); l > 0; l-- {
|
||||
prefix += " "
|
||||
}
|
||||
for _, child := range n.children {
|
||||
printChildren(child, prefix)
|
||||
}
|
||||
}
|
||||
|
||||
// Used as a workaround since we can't compare functions or their addressses
|
||||
var fakeHandlerValue string
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user