func (c *Context) Next() {
	if c.cursor >= math.MaxInt8 {
		return
	}
	c.cursor++
	if c.cursor >= 0 && c.cursor < int8(len(c.filters)) {
		c.filters[c.cursor](c)
	}
}
Next executes the remain filters in the chain.

NOTE: It ONLY used in the filters!
package gogo
import (
	"crypto"
	"math"
	"net/http"
	"net/url"
	"strings"
	"sync"
	"time"
	"github.com/dolab/gogo/internal/params"
	"github.com/dolab/gogo/internal/render"
	"github.com/dolab/gogo/pkgs/hooks"
)
var (
	contextPool = sync.Pool{
		New: func() interface{} {
			return NewContext()
		},
	}
	contextNew = func(w http.ResponseWriter, r *http.Request, ps *params.Params, pkg, ctrl, action string) *Context {
		ctx := contextPool.Get().(*Context)
		ctx.Response.Hijack(w)
		ctx.Request = r
		ctx.Params = ps
		ctx.Logger = NewRequestLogger(r)
		ctx.pkg = pkg
		ctx.ctrl = ctrl
		ctx.action = action
		return ctx
	}
	contextReuse = func(ctx *Context) {
		contextPool.Put(ctx)
	}
)
type Context struct {
	Response Responser
	Request  *http.Request
	Params   *params.Params
	Logger   Logger
	mux            sync.RWMutex
	settings       map[string]interface{}
	frozenSettings map[string]interface{}
	cursor         int8
	pkg           string
	ctrl          string
	action        string
	filters       []Middleware
	responseReady *hooks.HookList
	issuedAt      time.Time
}
func NewContext() *Context {
	return &Context{
		Response: NewResponse(nil),
		cursor:   -1,
	}
}
func (c *Context) Package() string {
	return c.pkg
}
func (c *Context) Controller() string {
	return c.ctrl
}
func (c *Context) Action() string {
	return c.action
}
func (c *Context) ContentType() string {
	s := c.Header("Content-Type")
	i := strings.Index(s, ";")
	if i == -1 {
		i = len(s)
	}
	return strings.TrimSpace(strings.ToLower(s[:i]))
}
func (c *Context) Set(key string, value interface{}) {
	if c.settings == nil {
		c.settings = make(map[string]interface{})
	}
	c.settings[key] = value
}
func (c *Context) Get(key string) (v interface{}, ok bool) {
	if c.settings == nil {
		return
	}
	v, ok = c.settings[key]
	return
}
func (c *Context) MustGet(key string) interface{} {
	v, ok := c.Get(key)
	if !ok {
		c.Logger.Panicf("Key %s doesn't exist", key)
	}
	return v
}
func (c *Context) SetFinal(key string, value interface{}) error {
	if c.frozenSettings == nil {
		c.frozenSettings = make(map[string]interface{})
	}
	if _, ok := c.frozenSettings[key]; ok {
		return ErrSettingsKey
	}
	c.frozenSettings[key] = value
	return nil
}
func (c *Context) GetFinal(key string) (v interface{}, ok bool) {
	if c.frozenSettings == nil {
		return
	}
	v, ok = c.frozenSettings[key]
	return
}
func (c *Context) MustSetFinal(key string, value interface{}) {
	err := c.SetFinal(key, value)
	if err != nil {
		c.Logger.Panicf("Freeze key %s duplicated!", key)
	}
}
func (c *Context) MustGetFinal(key string) interface{} {
	v, ok := c.GetFinal(key)
	if !ok {
		c.Logger.Panicf("Freeze key %s doesn't exist", key)
	}
	return v
}
func (c *Context) RequestID() string {
	if c.Logger == nil {
		return ""
	}
	return c.Logger.RequestID()
}
func (c *Context) RequestURI() string {
	if c.Request.RequestURI != "" {
		return c.Request.RequestURI
	}
	uri, _ := url.QueryUnescape(c.Request.URL.EscapedPath())
	return uri
}
func (c *Context) HasRawHeader(key string) bool {
	for yek := range c.Request.Header {
		if key == yek {
			return true
		}
	}
	return false
}
func (c *Context) RawHeader(key string) []string {
	for yek, vals := range c.Request.Header {
		if key == yek {
			return vals
		}
	}
	return nil
}
func (c *Context) HasHeader(key string) bool {
	_, ok := c.Request.Header[http.CanonicalHeaderKey(key)]
	return ok
}
func (c *Context) Header(key string) string {
	return c.Request.Header.Get(key)
}
func (c *Context) SetStatus(code int) {
	c.Response.WriteHeader(code)
}
func (c *Context) AddHeader(key, value string) {
	c.Response.Header().Add(key, value)
}
func (c *Context) SetHeader(key, value string) {
	c.Response.Header().Set(key, value)
}
func (c *Context) Redirect(location string) {
	c.Abort()
	status := c.Response.Status()
	switch status {
	case http.StatusMovedPermanently, http.StatusSeeOther, http.StatusTemporaryRedirect:
	default:
		status = http.StatusFound
	}
	c.SetHeader("Location", location)
	http.Redirect(c.Response, c.Request, location, status)
}
func (c *Context) Return(body ...interface{}) error {
	var tmprender render.Render
	if len(c.Response.Header().Get("Content-Type")) == 0 {
		accept := c.Request.Header.Get("Accept")
		for _, enc := range strings.Split(accept, ",") {
			switch {
			case strings.Contains(enc, render.ContentTypeJSON), strings.Contains(enc, render.ContentTypeJSONP):
				tmprender = render.NewJsonRender(c.Response)
			case strings.Contains(enc, render.ContentTypeXML):
				tmprender = render.NewXmlRender(c.Response)
			}
			if tmprender != nil {
				break
			}
		}
	}
	if tmprender == nil {
		tmprender = render.NewDefaultRender(c.Response)
	}
	if len(body) > 0 {
		return c.Render(tmprender, body[0])
	}
	return c.Render(tmprender, nil)
}
func (c *Context) HashedReturn(hasher crypto.Hash, body ...interface{}) error {
	if len(body) > 0 {
		return c.Render(render.NewHashRender(c.Response, hasher), body[0])
	}
	return c.Render(render.NewHashRender(c.Response, hasher), "")
}
func (c *Context) Text(data interface{}) error {
	return c.Render(render.NewTextRender(c.Response), data)
}
func (c *Context) String(data interface{}) error {
	return c.Render(render.NewTextRender(c.Response), data)
}
func (c *Context) JSON(data interface{}) error {
	return c.Render(render.NewJsonRender(c.Response), data)
}
func (c *Context) JSONP(callback string, data interface{}) error {
	return c.Render(render.NewJsonpRender(c.Response, callback), data)
}
func (c *Context) XML(data interface{}) error {
	return c.Render(render.NewXmlRender(c.Response), data)
}
func (c *Context) Render(rr render.Render, data interface{}) error {
	c.Abort()
	if coder, ok := data.(StatusCoder); ok {
		c.SetStatus(coder.StatusCode())
	}
	if contentType := rr.ContentType(); contentType != "" {
		c.SetHeader("Content-Type", contentType)
	}
	c.Response.FlushHeader()
	if !c.responseReady.Run(c.Response, c.Request) {
		return nil
	}
	if data == nil {
		return nil
	}
	err := rr.Render(data)
	if err != nil {
		c.Logger.Errorf("%T.Render(?): %v", rr, err)
	}
	return err
}