mirror of
https://github.com/gin-gonic/gin.git
synced 2025-10-24 02:32:17 +08:00
Merge branch 'master' into master
This commit is contained in:
commit
ad18194d9e
@ -163,6 +163,14 @@ func setTimeField(val string, structField reflect.StructField, value reflect.Val
|
|||||||
l = time.UTC
|
l = time.UTC
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if locTag := structField.Tag.Get("time_location"); locTag != "" {
|
||||||
|
loc, err := time.LoadLocation(locTag)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
l = loc
|
||||||
|
}
|
||||||
|
|
||||||
t, err := time.ParseInLocation(timeFormat, val, l)
|
t, err := time.ParseInLocation(timeFormat, val, l)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -45,6 +45,7 @@ func createMultipartRequest() *http.Request {
|
|||||||
must(mw.WriteField("id", ""))
|
must(mw.WriteField("id", ""))
|
||||||
must(mw.WriteField("time_local", "31/12/2016 14:55"))
|
must(mw.WriteField("time_local", "31/12/2016 14:55"))
|
||||||
must(mw.WriteField("time_utc", "31/12/2016 14:55"))
|
must(mw.WriteField("time_utc", "31/12/2016 14:55"))
|
||||||
|
must(mw.WriteField("time_location", "31/12/2016 14:55"))
|
||||||
req, err := http.NewRequest("POST", "/", body)
|
req, err := http.NewRequest("POST", "/", body)
|
||||||
must(err)
|
must(err)
|
||||||
req.Header.Set("Content-Type", MIMEMultipartPOSTForm+"; boundary="+boundary)
|
req.Header.Set("Content-Type", MIMEMultipartPOSTForm+"; boundary="+boundary)
|
||||||
@ -444,14 +445,15 @@ func TestContextPostFormMultipart(t *testing.T) {
|
|||||||
c.Request = createMultipartRequest()
|
c.Request = createMultipartRequest()
|
||||||
|
|
||||||
var obj struct {
|
var obj struct {
|
||||||
Foo string `form:"foo"`
|
Foo string `form:"foo"`
|
||||||
Bar string `form:"bar"`
|
Bar string `form:"bar"`
|
||||||
BarAsInt int `form:"bar"`
|
BarAsInt int `form:"bar"`
|
||||||
Array []string `form:"array"`
|
Array []string `form:"array"`
|
||||||
ID string `form:"id"`
|
ID string `form:"id"`
|
||||||
TimeLocal time.Time `form:"time_local" time_format:"02/01/2006 15:04"`
|
TimeLocal time.Time `form:"time_local" time_format:"02/01/2006 15:04"`
|
||||||
TimeUTC time.Time `form:"time_utc" time_format:"02/01/2006 15:04" time_utc:"1"`
|
TimeUTC time.Time `form:"time_utc" time_format:"02/01/2006 15:04" time_utc:"1"`
|
||||||
BlankTime time.Time `form:"blank_time" time_format:"02/01/2006 15:04"`
|
TimeLocation time.Time `form:"time_location" time_format:"02/01/2006 15:04" time_location:"Asia/Tokyo"`
|
||||||
|
BlankTime time.Time `form:"blank_time" time_format:"02/01/2006 15:04"`
|
||||||
}
|
}
|
||||||
assert.NoError(t, c.Bind(&obj))
|
assert.NoError(t, c.Bind(&obj))
|
||||||
assert.Equal(t, obj.Foo, "bar")
|
assert.Equal(t, obj.Foo, "bar")
|
||||||
@ -463,6 +465,9 @@ func TestContextPostFormMultipart(t *testing.T) {
|
|||||||
assert.Equal(t, obj.TimeLocal.Location(), time.Local)
|
assert.Equal(t, obj.TimeLocal.Location(), time.Local)
|
||||||
assert.Equal(t, obj.TimeUTC.Format("02/01/2006 15:04"), "31/12/2016 14:55")
|
assert.Equal(t, obj.TimeUTC.Format("02/01/2006 15:04"), "31/12/2016 14:55")
|
||||||
assert.Equal(t, obj.TimeUTC.Location(), time.UTC)
|
assert.Equal(t, obj.TimeUTC.Location(), time.UTC)
|
||||||
|
loc, _ := time.LoadLocation("Asia/Tokyo")
|
||||||
|
assert.Equal(t, obj.TimeLocation.Format("02/01/2006 15:04"), "31/12/2016 14:55")
|
||||||
|
assert.Equal(t, obj.TimeLocation.Location(), loc)
|
||||||
assert.True(t, obj.BlankTime.IsZero())
|
assert.True(t, obj.BlankTime.IsZero())
|
||||||
|
|
||||||
value, ok := c.GetQuery("foo")
|
value, ok := c.GetQuery("foo")
|
||||||
|
48
gin.go
48
gin.go
@ -20,9 +20,11 @@ const (
|
|||||||
defaultMultipartMemory = 32 << 20 // 32 MB
|
defaultMultipartMemory = 32 << 20 // 32 MB
|
||||||
)
|
)
|
||||||
|
|
||||||
var default404Body = []byte("404 page not found")
|
var (
|
||||||
var default405Body = []byte("405 method not allowed")
|
default404Body = []byte("404 page not found")
|
||||||
var defaultAppEngine bool
|
default405Body = []byte("405 method not allowed")
|
||||||
|
defaultAppEngine bool
|
||||||
|
)
|
||||||
|
|
||||||
type HandlerFunc func(*Context)
|
type HandlerFunc func(*Context)
|
||||||
type HandlersChain []HandlerFunc
|
type HandlersChain []HandlerFunc
|
||||||
@ -91,6 +93,7 @@ type Engine struct {
|
|||||||
|
|
||||||
// If enabled, the url.RawPath will be used to find parameters.
|
// If enabled, the url.RawPath will be used to find parameters.
|
||||||
UseRawPath bool
|
UseRawPath bool
|
||||||
|
|
||||||
// If true, the path value will be unescaped.
|
// If true, the path value will be unescaped.
|
||||||
// If UseRawPath is false (by default), the UnescapePathValues effectively is true,
|
// If UseRawPath is false (by default), the UnescapePathValues effectively is true,
|
||||||
// as url.Path gonna be used, which is already unescaped.
|
// as url.Path gonna be used, which is already unescaped.
|
||||||
@ -161,13 +164,16 @@ func (engine *Engine) SecureJsonPrefix(prefix string) *Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (engine *Engine) LoadHTMLGlob(pattern string) {
|
func (engine *Engine) LoadHTMLGlob(pattern string) {
|
||||||
|
left := engine.delims.Left
|
||||||
|
right := engine.delims.Right
|
||||||
|
|
||||||
if IsDebugging() {
|
if IsDebugging() {
|
||||||
debugPrintLoadTemplate(template.Must(template.New("").Delims(engine.delims.Left, engine.delims.Right).Funcs(engine.FuncMap).ParseGlob(pattern)))
|
debugPrintLoadTemplate(template.Must(template.New("").Delims(left, right).Funcs(engine.FuncMap).ParseGlob(pattern)))
|
||||||
engine.HTMLRender = render.HTMLDebug{Glob: pattern, FuncMap: engine.FuncMap, Delims: engine.delims}
|
engine.HTMLRender = render.HTMLDebug{Glob: pattern, FuncMap: engine.FuncMap, Delims: engine.delims}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
templ := template.Must(template.New("").Delims(engine.delims.Left, engine.delims.Right).Funcs(engine.FuncMap).ParseGlob(pattern))
|
templ := template.Must(template.New("").Delims(left, right).Funcs(engine.FuncMap).ParseGlob(pattern))
|
||||||
engine.SetHTMLTemplate(templ)
|
engine.SetHTMLTemplate(templ)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,12 +328,12 @@ func (engine *Engine) HandleContext(c *Context) {
|
|||||||
engine.pool.Put(c)
|
engine.pool.Put(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (engine *Engine) handleHTTPRequest(context *Context) {
|
func (engine *Engine) handleHTTPRequest(c *Context) {
|
||||||
httpMethod := context.Request.Method
|
httpMethod := c.Request.Method
|
||||||
path := context.Request.URL.Path
|
path := c.Request.URL.Path
|
||||||
unescape := false
|
unescape := false
|
||||||
if engine.UseRawPath && len(context.Request.URL.RawPath) > 0 {
|
if engine.UseRawPath && len(c.Request.URL.RawPath) > 0 {
|
||||||
path = context.Request.URL.RawPath
|
path = c.Request.URL.RawPath
|
||||||
unescape = engine.UnescapePathValues
|
unescape = engine.UnescapePathValues
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -337,20 +343,20 @@ func (engine *Engine) handleHTTPRequest(context *Context) {
|
|||||||
if t[i].method == httpMethod {
|
if t[i].method == httpMethod {
|
||||||
root := t[i].root
|
root := t[i].root
|
||||||
// Find route in tree
|
// Find route in tree
|
||||||
handlers, params, tsr := root.getValue(path, context.Params, unescape)
|
handlers, params, tsr := root.getValue(path, c.Params, unescape)
|
||||||
if handlers != nil {
|
if handlers != nil {
|
||||||
context.handlers = handlers
|
c.handlers = handlers
|
||||||
context.Params = params
|
c.Params = params
|
||||||
context.Next()
|
c.Next()
|
||||||
context.writermem.WriteHeaderNow()
|
c.writermem.WriteHeaderNow()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if httpMethod != "CONNECT" && path != "/" {
|
if httpMethod != "CONNECT" && path != "/" {
|
||||||
if tsr && engine.RedirectTrailingSlash {
|
if tsr && engine.RedirectTrailingSlash {
|
||||||
redirectTrailingSlash(context)
|
redirectTrailingSlash(c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if engine.RedirectFixedPath && redirectFixedPath(context, root, engine.RedirectFixedPath) {
|
if engine.RedirectFixedPath && redirectFixedPath(c, root, engine.RedirectFixedPath) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -362,15 +368,15 @@ func (engine *Engine) handleHTTPRequest(context *Context) {
|
|||||||
for _, tree := range engine.trees {
|
for _, tree := range engine.trees {
|
||||||
if tree.method != httpMethod {
|
if tree.method != httpMethod {
|
||||||
if handlers, _, _ := tree.root.getValue(path, nil, unescape); handlers != nil {
|
if handlers, _, _ := tree.root.getValue(path, nil, unescape); handlers != nil {
|
||||||
context.handlers = engine.allNoMethod
|
c.handlers = engine.allNoMethod
|
||||||
serveError(context, 405, default405Body)
|
serveError(c, 405, default405Body)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
context.handlers = engine.allNoRoute
|
c.handlers = engine.allNoRoute
|
||||||
serveError(context, 404, default404Body)
|
serveError(c, 404, default404Body)
|
||||||
}
|
}
|
||||||
|
|
||||||
var mimePlain = []string{MIMEPlain}
|
var mimePlain = []string{MIMEPlain}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user