func Decompress(encoding string, r io.Reader) (io.ReadCloser, error) {
	switch encoding {
	case "gzip":
		return gzip.NewReader(r)
	case "deflate", "zlib":
		return zlib.NewReader(r)
	default:
		return nil, ErrUnsupportedMediaType.WithMsgf("Unsupported Content-Encoding: %s", encoding)
	}
}
Decompress wrap the reader for decompressing, It support gzip and zlib, and compatible for deflate.
package gear
import (
	"bytes"
	"compress/gzip"
	"compress/zlib"
	"context"
	"encoding"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"net/textproto"
	"net/url"
	"os"
	"os/signal"
	"reflect"
	"runtime"
	"strconv"
	"strings"
	"sync/atomic"
	"syscall"
	"unicode/utf8"
)
type middlewares []Middleware
func (m middlewares) run(ctx *Context) (err error) {
	for _, fn := range m {
		if err = fn(ctx); !IsNil(err) || ctx.Res.ended.isTrue() {
			return
		}
	}
	return
}
func Compose(mds ...Middleware) Middleware {
	switch len(mds) {
	case 0:
		return noOp
	case 1:
		return mds[0]
	default:
		return middlewares(mds).run
	}
}
var noOp Middleware = func(ctx *Context) error { return nil }
func WrapHandler(handler http.Handler) Middleware {
	return func(ctx *Context) error {
		handler.ServeHTTP(ctx.Res, ctx.Req)
		return nil
	}
}
func WrapHandlerFunc(fn http.HandlerFunc) Middleware {
	return func(ctx *Context) error {
		fn(ctx.Res, ctx.Req)
		return nil
	}
}
func IsNil(val interface{}) bool {
	if val == nil {
		return true
	}
	value := reflect.ValueOf(val)
	switch value.Kind() {
	case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Interface, reflect.Slice:
		return value.IsNil()
	default:
		return false
	}
}
type Error struct {
	Code  int         `json:"-"`
	Err   string      `json:"error"`
	Msg   string      `json:"message"`
	Data  interface{} `json:"data,omitempty"`
	Stack string      `json:"-"`
}
type ErrorResponse struct {
	Error struct {
		Code    int         `json:"code"`
		Status  string      `json:"status"`
		Message string      `json:"message"`
		Data    interface{} `json:"data,omitempty"`
	} `json:"error"`
}
func ToErrorResponse(e error) ErrorResponse {
	res := ErrorResponse{}
	err := Err.From(e)
	res.Error.Code = err.Code
	res.Error.Status = err.Err
	res.Error.Message = err.Msg
	res.Error.Data = err.Data
	return res
}
type errorForLog struct {
	Code  int         `json:"code"`
	Err   string      `json:"error"`
	Msg   string      `json:"message"`
	Data  interface{} `json:"data,omitempty"`
	Stack string      `json:"stack"`
}
func (err *Error) Status() int {
	return err.Code
}
func (err *Error) Error() string {
	return fmt.Sprintf("%s: %s", err.Err, err.Msg)
}
func (err Error) String() string {
	return err.GoString()
}
func (err Error) GoString() string {
	if v, ok := err.Data.([]byte); ok && utf8.Valid(v) {
		err.Data = string(v)
	}
	return fmt.Sprintf(`Error{Code:%d, Err:%s, Msg:%s, Data:%#v, Stack:%s}`,
		err.Code, strconv.Quote(err.Err), strconv.Quote(err.Msg), err.Data, strconv.Quote(err.Stack))
}
func (err Error) Format() (string, error) {
	errlog := errorForLog{err.Code, err.Err, err.Msg, err.Data, err.Stack}
	res, e := json.Marshal(errlog)
	if e == nil {
		return string(res), nil
	}
	return "", e
}
func (err Error) WithErr(name string) *Error {
	err.Err = name
	return &err
}
func (err Error) WithMsg(msgs ...string) *Error {
	if len(msgs) > 0 {
		err.Msg = strings.Join(msgs, ", ")
	}
	return &err
}
func (err Error) WithMsgf(format string, args ...interface{}) *Error {
	return err.WithMsg(fmt.Sprintf(format, args...))
}
func (err Error) WithCode(code int) *Error {
	err.Code = code
	if text := http.StatusText(code); text != "" {
		err.Err = text
	}
	return &err
}
func (err Error) WithStack(skip ...int) *Error {
	return ErrorWithStack(&err, skip...)
}
func (err Error) From(e error) *Error {
	if IsNil(e) {
		return nil
	}
	switch v := e.(type) {
	case *Error:
		return v
	case HTTPError:
		err.Code = v.Status()
		err.Msg = v.Error()
	case *textproto.Error:
		err.Code = v.Code
		err.Msg = v.Msg
	default:
		err.Msg = e.Error()
	}
	if err.Err == "" {
		err.Err = http.StatusText(err.Code)
	}
	return &err
}
func ParseError(e error, code ...int) HTTPError {
	if IsNil(e) {
		return nil
	}
	switch v := e.(type) {
	case HTTPError:
		return v
	case *textproto.Error:
		err := Err.WithCode(v.Code)
		err.Msg = v.Msg
		return err
	default:
		err := ErrInternalServerError.WithMsg(e.Error())
		if len(code) > 0 && code[0] > 0 {
			err = err.WithCode(code[0])
		}
		return err
	}
}
func ErrorWithStack(val interface{}, skip ...int) *Error {
	if IsNil(val) {
		return nil
	}
	var err *Error
	switch v := val.(type) {
	case *Error:
		err = v.WithMsg()  
	case error:
		err = ErrInternalServerError.From(v)
	case string:
		err = ErrInternalServerError.WithMsg(v)
	default:
		err = ErrInternalServerError.WithMsgf("%#v", v)
	}
	if err.Stack == "" {
		buf := make([]byte, 8192)
		buf = buf[:runtime.Stack(buf, false)]
		s := 0
		if len(skip) != 0 {
			s = skip[0]
		}
		err.Stack = pruneStack(buf, s)
	}
	return err
}
func ValuesToStruct(values map[string][]string, target interface{}, tag string) (err error) {
	if values == nil {
		return fmt.Errorf("invalid values: %v", values)
	}
	if len(values) == 0 {
		return
	}
	rv := reflect.ValueOf(target)
	if rv.Kind() != reflect.Ptr || rv.IsNil() {
		return fmt.Errorf("invalid struct: %v", rv)
	}
	return valuesToStruct(values, rv, tag)
}
func valuesToStruct(values map[string][]string, rv reflect.Value, tag string) (err error) {
	rv = rv.Elem()
	rt := rv.Type()
	n := rv.NumField()
	for i := 0; i < n; i++ {
		structField := rt.Field(i)
		value := rv.Field(i)
		if structField.Anonymous {
			if value.Kind() == reflect.Struct && value.CanAddr() {
				if err = valuesToStruct(values, value.Addr(), tag); err != nil {
					return
				}
			}
			continue
		}
		if !value.CanSet() {
			continue
		}
		fk := structField.Tag.Get(tag)
		if fk == "" {
			continue
		}
		if vals, ok := values[fk]; ok {
			if value.Kind() == reflect.Slice {
				err = setRefSlice(value, vals)
			} else if len(vals) > 0 && vals[0] != "" {
				err = setRefField(value, vals[0])
			}
			if err != nil {
				return
			}
		}
	}
	return
}
func shouldDeref(k reflect.Kind) bool {
	switch k {
	case reflect.String, reflect.Bool, reflect.Float32, reflect.Float64,
		reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
		reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		return true
	default:
		return false
	}
}
func setRefSlice(v reflect.Value, vals []string) error {
	l := len(vals)
	slice := reflect.MakeSlice(v.Type(), l, l)
	for i := 0; i < l; i++ {
		if err := setRefField(slice.Index(i), vals[i]); err != nil {
			return err
		}
	}
	v.Set(slice)
	return nil
}
func setRefField(v reflect.Value, str string) error {
	if ok, err := tryUnmarshalValue(v, str); ok {
		return err
	}
	if v.Kind() == reflect.Ptr && shouldDeref(v.Type().Elem().Kind()) {
		v.Set(reflect.New(v.Type().Elem()))
		v = v.Elem()
	}
	switch v.Kind() {
	case reflect.String:
		v.SetString(str)
		return nil
	case reflect.Bool:
		return setRefBool(v, str)
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return setRefInt(v, str, v.Type().Bits())
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		return setRefUint(v, str, v.Type().Bits())
	case reflect.Float32, reflect.Float64:
		return setRefFloat(v, str, v.Type().Bits())
	default:
		return fmt.Errorf("unknown field type: %v", v.Type())
	}
}
func setRefBool(v reflect.Value, str string) error {
	val, err := strconv.ParseBool(str)
	if err == nil {
		v.SetBool(val)
	}
	return err
}
func setRefInt(v reflect.Value, str string, size int) error {
	val, err := strconv.ParseInt(str, 10, size)
	if err == nil {
		v.SetInt(val)
	}
	return err
}
func setRefUint(v reflect.Value, str string, size int) error {
	val, err := strconv.ParseUint(str, 10, size)
	if err == nil {
		v.SetUint(val)
	}
	return err
}
func setRefFloat(v reflect.Value, str string, size int) error {
	val, err := strconv.ParseFloat(str, size)
	if err == nil {
		v.SetFloat(val)
	}
	return err
}
func tryUnmarshalValue(v reflect.Value, str string) (bool, error) {
	if v.Kind() != reflect.Ptr && v.CanAddr() && v.Type().Name() != "" {
		v = v.Addr()
	}
	if v.Type().NumMethod() > 0 {
		if v.IsNil() {
			v.Set(reflect.New(v.Type().Elem()))
		}
		if u, ok := v.Interface().(encoding.TextUnmarshaler); ok {
			return true, u.UnmarshalText([]byte(str))
		}
	}
	return false, nil
}
func pruneStack(stack []byte, skip int) string {
	lines := strings.Split(string(stack), "\n")[1:]
	newLines := make([]string, 0, len(lines)/2)
	num := 0
	for idx, line := range lines {
		if idx%2 == 0 {
			continue
		}
		skip--
		if skip >= 0 {
			continue
		}
		num++
		loc := strings.Split(line, " ")[0]
		loc = strings.Replace(loc, "\t", "\\t", -1)
		newLines = append(newLines, loc)
		if num == 10 {
			break
		}
	}
	return strings.Join(newLines, "\\n")
}
type atomicBool int32
func (b *atomicBool) isTrue() bool {
	return atomic.LoadInt32((*int32)(b)) == 1
}
func (b *atomicBool) swapTrue() bool {
	return atomic.SwapInt32((*int32)(b), 1) == 0
}
func (b *atomicBool) setTrue() {
	atomic.StoreInt32((*int32)(b), 1)
}
func IsStatusCode(status int) bool {
	switch status {
	case 100, 101, 102, 103,
		200, 201, 202, 203, 204, 205, 206, 207, 208, 226,
		300, 301, 302, 303, 304, 305, 306, 307, 308,
		400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418,
		421, 422, 423, 424, 426, 428, 429, 431, 440, 444, 449, 450, 451, 494, 495, 496, 497, 498, 499,
		500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 520, 521, 522, 523, 524, 525, 526, 527:
		return true
	default:
		return false
	}
}
func isRedirectStatus(status int) bool {
	switch status {
	case 300, 301, 302, 303, 305, 307, 308:
		return true
	default:
		return false
	}
}
func isEmptyStatus(status int) bool {
	switch status {
	case 100, 101, 102, 103, 204, 205, 304:
		return true
	default:
		return false
	}
}
func ContentDisposition(fileName, dispositionType string) (header string) {
	if dispositionType == "" {
		dispositionType = "attachment"
	}
	if fileName == "" {
		return dispositionType
	}
	header = fmt.Sprintf(`%s; filename="%s"`, dispositionType, url.QueryEscape(fileName))
	fallbackName := url.PathEscape(fileName)
	if len(fallbackName) != len(fileName) {
		header = fmt.Sprintf(`%s; filename*=UTF-8''%s`, header, fallbackName)
	}
	return
}
type LoggerFilterWriter struct {
	phrases [][]byte
	out     io.Writer
}
var loggerFilterWriter = &LoggerFilterWriter{
	phrases: [][]byte{[]byte("http: TLS handshake error"), []byte("EOF")},
	out:     os.Stderr,
}
func DefaultFilterWriter() *LoggerFilterWriter {
	return loggerFilterWriter
}
func (s *LoggerFilterWriter) SetOutput(out io.Writer) {
	s.out = out
}
func (s *LoggerFilterWriter) Add(err string) {
	if s.out == nil {
		panic(Err.WithMsg("output io.Writer should be set with SetOutput method"))
	}
	s.phrases = append(s.phrases, []byte(err))
}
func (s *LoggerFilterWriter) Write(p []byte) (n int, err error) {
	for _, phrase := range s.phrases {
		if bytes.Contains(p, phrase) {
			return len(p), nil
		}
	}
	return s.out.Write(p)
}