func (ctx *Context) Protocol(trustedProxy ...bool) string {
	return ctx.Scheme(trustedProxy...)
}
Protocol -  Please use ctx.Scheme instead. This method will be changed in v2.
package gear
import (
	"bytes"
	"context"
	"encoding/json"
	"encoding/xml"
	"fmt"
	"io"
	"io/ioutil"
	"mime"
	"net"
	"net/http"
	"net/url"
	"strings"
	"time"
	"github.com/go-http-utils/cookie"
	"github.com/go-http-utils/negotiator"
)
type contextKey int
const (
	isInheritedContext contextKey = iota
	isGearContext
	paramsKey
	routerNodeKey
	routerRootKey
)
type Any interface {
	New(ctx *Context) (interface{}, error)
}
type BodyTemplate interface {
	Validate() error
}
type Context struct {
	app     *App
	Req     *http.Request
	Res     *Response
	Cookies *cookie.Cookies  
	Host    string
	Method  string
	Path    string
	StartAt time.Time
	query     url.Values
	ctx       context.Context
	cancelCtx context.CancelFunc
	done      <-chan struct{}
	kv        map[interface{}]interface{}
}
func NewContext(app *App, w http.ResponseWriter, r *http.Request) *Context {
	ctx := Context{
		app: app,
		Res: &Response{w: w, rw: w, handlerHeader: w.Header()},
		Host:    r.Host,
		Method:  r.Method,
		Path:    r.URL.Path,
		StartAt: time.Now().UTC(),
		Cookies: cookie.New(w, r, app.keys...),
		kv:      make(map[interface{}]interface{}),
	}
	if app.serverName != "" {
		ctx.SetHeader(HeaderServer, app.serverName)
	}
	if app.timeout <= 0 {
		ctx.ctx, ctx.cancelCtx = context.WithCancel(r.Context())
	} else {
		ctx.ctx, ctx.cancelCtx = context.WithTimeout(r.Context(), app.timeout)
	}
	ctx.ctx = context.WithValue(ctx.ctx, isInheritedContext, struct{}{})
	ctx.Req = r.WithContext(ctx.ctx)
	if app.withContext != nil {
		ctx.WithContext(app.withContext(ctx.Req))
	}
	ctx.done = ctx.ctx.Done()
	return &ctx
}
func (ctx *Context) Deadline() (time.Time, bool) {
	return ctx.ctx.Deadline()
}
func (ctx *Context) Done() <-chan struct{} {
	return ctx.ctx.Done()
}
func (ctx *Context) Err() error {
	return ctx.ctx.Err()
}
func (ctx *Context) Value(key interface{}) (val interface{}) {
	if key == isGearContext {
		return struct{}{}
	}
	return ctx.ctx.Value(key)
}
func (ctx *Context) Cancel() {
	ctx.Res.ended.setTrue()  
	ctx.Res.afterHooks = nil
	ctx.cancelCtx()
}
func (ctx *Context) WithCancel() (context.Context, context.CancelFunc) {
	return context.WithCancel(ctx.ctx)
}
func (ctx *Context) WithDeadline(deadline time.Time) (context.Context, context.CancelFunc) {
	return context.WithDeadline(ctx.ctx, deadline)
}
func (ctx *Context) WithTimeout(timeout time.Duration) (context.Context, context.CancelFunc) {
	return context.WithTimeout(ctx.ctx, timeout)
}
func (ctx *Context) WithValue(key, val interface{}) context.Context {
	return context.WithValue(ctx.ctx, key, val)
}
func (ctx *Context) Context() context.Context {
	return ctx.ctx
}
func (ctx *Context) WithContext(c context.Context) {
	if c.Value(isGearContext) != nil {
		panic(Err.WithMsg("should not use *gear.Context as parent context, please use ctx.Context()"))
	}
	if c.Value(isInheritedContext) == nil {
		panic(Err.WithMsg("the context is not created from ctx.Context()"))
	}
	ctx.Req = ctx.Req.WithContext(c)
	ctx.ctx = c
}
func (ctx *Context) LogErr(err error) {
	ctx.app.Error(err)
}
func (ctx *Context) Timing(dt time.Duration, fn func(context.Context)) (err error) {
	ct, cancel := ctx.WithTimeout(dt)
	defer cancel()
	ch := make(chan error, 1)  
	go tryRunTiming(ct, fn, ch)
	select {
	case <-ct.Done():
		err = ct.Err()
	case err = <-ch:
	}
	return
}
func (ctx *Context) Any(any interface{}) (val interface{}, err error) {
	var ok bool
	if val, ok = ctx.kv[any]; !ok {
		switch v := any.(type) {
		case Any:
			if val, err = v.New(ctx); err == nil {
				ctx.kv[any] = val
			}
		default:
			return nil, Err.WithMsg("non-existent key")
		}
	}
	return
}
func (ctx *Context) MustAny(any interface{}) interface{} {
	val, err := ctx.Any(any)
	if err != nil {
		panic(err)
	}
	return val
}
func (ctx *Context) SetAny(key, val interface{}) {
	ctx.kv[key] = val
}
func (ctx *Context) Setting(key interface{}) interface{} {
	if val, ok := ctx.app.settings[key]; ok {
		return val
	}
	return nil
}
func (ctx *Context) IP(trustedProxy ...bool) net.IP {
	trusted := ctx.Setting(SetTrustedProxy).(bool)
	if len(trustedProxy) > 0 {
		trusted = trustedProxy[0]
	}
	var ip string
	if trusted {
		ip = ctx.Req.Header.Get(HeaderXRealIP)
		if ip == "" {
			ip = ctx.Req.Header.Get(HeaderXForwardedFor)
			if i := strings.IndexByte(ip, ','); i > 0 {
				ip = ip[0:i]
			}
		}
	}
	if ip == "" {
		ra := ctx.Req.RemoteAddr
		ip, _, _ = net.SplitHostPort(ra)
	}
	return net.ParseIP(ip)
}