Fixes routing bug
This commit is contained in:
parent
d10e2b6c0d
commit
1565111274
73
gin.go
73
gin.go
@ -26,22 +26,11 @@ type (
|
|||||||
Meta interface{} `json:"meta"`
|
Meta interface{} `json:"meta"`
|
||||||
}
|
}
|
||||||
|
|
||||||
ResponseWriter interface {
|
|
||||||
http.ResponseWriter
|
|
||||||
Status() int
|
|
||||||
Written() bool
|
|
||||||
}
|
|
||||||
|
|
||||||
responseWriter struct {
|
|
||||||
http.ResponseWriter
|
|
||||||
status int
|
|
||||||
}
|
|
||||||
|
|
||||||
// Context is the most important part of gin. It allows us to pass variables between middleware,
|
// Context is the most important part of gin. It allows us to pass variables between middleware,
|
||||||
// manage the flow, validate the JSON of a request and render a JSON response for example.
|
// manage the flow, validate the JSON of a request and render a JSON response for example.
|
||||||
Context struct {
|
Context struct {
|
||||||
Req *http.Request
|
Req *http.Request
|
||||||
Writer ResponseWriter
|
Writer http.ResponseWriter
|
||||||
Keys map[string]interface{}
|
Keys map[string]interface{}
|
||||||
Errors []ErrorMsg
|
Errors []ErrorMsg
|
||||||
Params httprouter.Params
|
Params httprouter.Params
|
||||||
@ -68,28 +57,11 @@ type (
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func (rw *responseWriter) WriteHeader(s int) {
|
|
||||||
rw.ResponseWriter.WriteHeader(s)
|
|
||||||
rw.status = s
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rw *responseWriter) Write(b []byte) (int, error) {
|
|
||||||
return rw.ResponseWriter.Write(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rw *responseWriter) Status() int {
|
|
||||||
return rw.status
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rw *responseWriter) Written() bool {
|
|
||||||
return rw.status != 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns a new blank Engine instance without any middleware attached.
|
// Returns a new blank Engine instance without any middleware attached.
|
||||||
// The most basic configuration
|
// The most basic configuration
|
||||||
func New() *Engine {
|
func New() *Engine {
|
||||||
engine := &Engine{}
|
engine := &Engine{}
|
||||||
engine.RouterGroup = &RouterGroup{nil, "/", nil, engine}
|
engine.RouterGroup = &RouterGroup{nil, "", nil, engine}
|
||||||
engine.router = httprouter.New()
|
engine.router = httprouter.New()
|
||||||
engine.router.NotFound = engine.handle404
|
engine.router.NotFound = engine.handle404
|
||||||
return engine
|
return engine
|
||||||
@ -112,13 +84,15 @@ func (engine *Engine) NotFound404(handlers ...HandlerFunc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (engine *Engine) handle404(w http.ResponseWriter, req *http.Request) {
|
func (engine *Engine) handle404(w http.ResponseWriter, req *http.Request) {
|
||||||
|
handlers := engine.combineHandlers(engine.handlers404)
|
||||||
handlers := engine.allHandlers(engine.handlers404)
|
|
||||||
c := engine.createContext(w, req, nil, handlers)
|
c := engine.createContext(w, req, nil, handlers)
|
||||||
c.Next()
|
if engine.handlers404 == nil {
|
||||||
if !c.Writer.Written() {
|
|
||||||
http.NotFound(c.Writer, c.Req)
|
http.NotFound(c.Writer, c.Req)
|
||||||
|
} else {
|
||||||
|
c.Writer.WriteHeader(404)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.Next()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServeFiles serves files from the given file system root.
|
// ServeFiles serves files from the given file system root.
|
||||||
@ -150,7 +124,7 @@ func (engine *Engine) Run(addr string) {
|
|||||||
|
|
||||||
func (group *RouterGroup) createContext(w http.ResponseWriter, req *http.Request, params httprouter.Params, handlers []HandlerFunc) *Context {
|
func (group *RouterGroup) createContext(w http.ResponseWriter, req *http.Request, params httprouter.Params, handlers []HandlerFunc) *Context {
|
||||||
return &Context{
|
return &Context{
|
||||||
Writer: &responseWriter{w, 0},
|
Writer: w,
|
||||||
Req: req,
|
Req: req,
|
||||||
index: -1,
|
index: -1,
|
||||||
engine: group.engine,
|
engine: group.engine,
|
||||||
@ -169,7 +143,7 @@ func (group *RouterGroup) Use(middlewares ...HandlerFunc) {
|
|||||||
func (group *RouterGroup) Group(component string, handlers ...HandlerFunc) *RouterGroup {
|
func (group *RouterGroup) Group(component string, handlers ...HandlerFunc) *RouterGroup {
|
||||||
prefix := path.Join(group.prefix, component)
|
prefix := path.Join(group.prefix, component)
|
||||||
return &RouterGroup{
|
return &RouterGroup{
|
||||||
Handlers: handlers,
|
Handlers: group.combineHandlers(handlers),
|
||||||
parent: group,
|
parent: group,
|
||||||
prefix: prefix,
|
prefix: prefix,
|
||||||
engine: group.engine,
|
engine: group.engine,
|
||||||
@ -188,7 +162,7 @@ func (group *RouterGroup) Group(component string, handlers ...HandlerFunc) *Rout
|
|||||||
// communication with a proxy).
|
// communication with a proxy).
|
||||||
func (group *RouterGroup) Handle(method, p string, handlers []HandlerFunc) {
|
func (group *RouterGroup) Handle(method, p string, handlers []HandlerFunc) {
|
||||||
p = path.Join(group.prefix, p)
|
p = path.Join(group.prefix, p)
|
||||||
handlers = group.allHandlers(handlers)
|
handlers = group.combineHandlers(handlers)
|
||||||
group.engine.router.Handle(method, p, func(w http.ResponseWriter, req *http.Request, params httprouter.Params) {
|
group.engine.router.Handle(method, p, func(w http.ResponseWriter, req *http.Request, params httprouter.Params) {
|
||||||
group.createContext(w, req, params, handlers).Next()
|
group.createContext(w, req, params, handlers).Next()
|
||||||
})
|
})
|
||||||
@ -219,13 +193,12 @@ func (group *RouterGroup) PUT(path string, handlers ...HandlerFunc) {
|
|||||||
group.Handle("PUT", path, handlers)
|
group.Handle("PUT", path, handlers)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (group *RouterGroup) allHandlers(handlers []HandlerFunc) []HandlerFunc {
|
func (group *RouterGroup) combineHandlers(handlers []HandlerFunc) []HandlerFunc {
|
||||||
local := append(group.Handlers, handlers...)
|
s := len(group.Handlers) + len(handlers)
|
||||||
if group.parent != nil {
|
h := make([]HandlerFunc, 0, s)
|
||||||
return group.parent.allHandlers(local)
|
h = append(h, group.Handlers...)
|
||||||
} else {
|
h = append(h, handlers...)
|
||||||
return local
|
return h
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************/
|
/************************************/
|
||||||
@ -327,7 +300,9 @@ func (c *Context) ParseBody(item interface{}) error {
|
|||||||
// Serializes the given struct as a JSON into the response body in a fast and efficient way.
|
// Serializes the given struct as a JSON into the response body in a fast and efficient way.
|
||||||
// It also sets the Content-Type as "application/json"
|
// It also sets the Content-Type as "application/json"
|
||||||
func (c *Context) JSON(code int, obj interface{}) {
|
func (c *Context) JSON(code int, obj interface{}) {
|
||||||
c.Writer.WriteHeader(code)
|
if code >= 0 {
|
||||||
|
c.Writer.WriteHeader(code)
|
||||||
|
}
|
||||||
c.Writer.Header().Set("Content-Type", "application/json")
|
c.Writer.Header().Set("Content-Type", "application/json")
|
||||||
encoder := json.NewEncoder(c.Writer)
|
encoder := json.NewEncoder(c.Writer)
|
||||||
if err := encoder.Encode(obj); err != nil {
|
if err := encoder.Encode(obj); err != nil {
|
||||||
@ -339,7 +314,9 @@ func (c *Context) JSON(code int, obj interface{}) {
|
|||||||
// Serializes the given struct as a XML into the response body in a fast and efficient way.
|
// Serializes the given struct as a XML into the response body in a fast and efficient way.
|
||||||
// It also sets the Content-Type as "application/xml"
|
// It also sets the Content-Type as "application/xml"
|
||||||
func (c *Context) XML(code int, obj interface{}) {
|
func (c *Context) XML(code int, obj interface{}) {
|
||||||
c.Writer.WriteHeader(code)
|
if code >= 0 {
|
||||||
|
c.Writer.WriteHeader(code)
|
||||||
|
}
|
||||||
c.Writer.Header().Set("Content-Type", "application/xml")
|
c.Writer.Header().Set("Content-Type", "application/xml")
|
||||||
encoder := xml.NewEncoder(c.Writer)
|
encoder := xml.NewEncoder(c.Writer)
|
||||||
if err := encoder.Encode(obj); err != nil {
|
if err := encoder.Encode(obj); err != nil {
|
||||||
@ -352,7 +329,9 @@ func (c *Context) XML(code int, obj interface{}) {
|
|||||||
// It also update the HTTP code and sets the Content-Type as "text/html".
|
// It also update the HTTP code and sets the Content-Type as "text/html".
|
||||||
// See http://golang.org/doc/articles/wiki/
|
// See http://golang.org/doc/articles/wiki/
|
||||||
func (c *Context) HTML(code int, name string, data interface{}) {
|
func (c *Context) HTML(code int, name string, data interface{}) {
|
||||||
c.Writer.WriteHeader(code)
|
if code >= 0 {
|
||||||
|
c.Writer.WriteHeader(code)
|
||||||
|
}
|
||||||
c.Writer.Header().Set("Content-Type", "text/html")
|
c.Writer.Header().Set("Content-Type", "text/html")
|
||||||
if err := c.engine.HTMLTemplates.ExecuteTemplate(c.Writer, name, data); err != nil {
|
if err := c.engine.HTMLTemplates.ExecuteTemplate(c.Writer, name, data); err != nil {
|
||||||
c.Error(err, map[string]interface{}{
|
c.Error(err, map[string]interface{}{
|
||||||
|
Loading…
Reference in New Issue
Block a user