func (ctx *Context) SetSecureCookie(name, value string, others ...interface{}) {
	ctx.SetSuperSecureCookie(defaultCookieSecret, name, value, others...)
}
SetSecureCookie sets given cookie value to response header with default secret string.
package seago
import (
	"crypto/hmac"
	"crypto/sha1"
	"encoding/base64"
	"fmt"
	"io"
	"io/ioutil"
	"mime/multipart"
	"net/http"
	"path"
	"path/filepath"
	"reflect"
	"strconv"
	"strings"
	"time"
	"github.com/seago/seago/inject"
)
type Locale interface {
	Language() string
	Tr(string, ...interface{}) string
}
type RequestBody struct {
	reader io.ReadCloser
}
func (rb *RequestBody) Bytes() ([]byte, error) {
	return ioutil.ReadAll(rb.reader)
}
func (rb *RequestBody) String() (string, error) {
	data, err := rb.Bytes()
	return string(data), err
}
func (rb *RequestBody) ReadCloser() io.ReadCloser {
	return rb.reader
}
type Request struct {
	*http.Request
}
func (r *Request) Body() *RequestBody {
	return &RequestBody{r.Request.Body}
}
type Context struct {
	inject.Injector
	handlers []Handler
	action   Handler
	index    int
	*Router
	Request  Request
	Response ResponseWriter
	params   Params
	File   *multipart.File
	Render  
	Locale
	Data    map[string]interface{}
	statics map[string]*http.Dir  
}
func (c *Context) handler() Handler {
	if c.index < len(c.handlers) {
		return c.handlers[c.index]
	}
	if c.index == len(c.handlers) {
		return c.action
	}
	panic("invalid index for context handler")
}
func (c *Context) Next() {
	c.index += 1
	c.run()
}
func (c *Context) Written() bool {
	return c.Response.Written()
}
func (c *Context) run() {
	for c.index <= len(c.handlers) {
		vals, err := c.Invoke(c.handler())
		if err != nil {
			panic(err)
		}
		c.index += 1
		if len(vals) > 0 {
			ev := c.GetVal(reflect.TypeOf(ReturnHandler(nil)))
			handleReturn := ev.Interface().(ReturnHandler)
			handleReturn(c, vals)
		}
		if c.Written() {
			return
		}
	}
}
func (ctx *Context) RemoteAddr() string {
	addr := ctx.Request.Header.Get("X-Real-IP")
	if len(addr) == 0 {
		addr = ctx.Request.Header.Get("X-Forwarded-For")
		if addr == "" {
			addr = ctx.Request.RemoteAddr
			if i := strings.LastIndex(addr, ":"); i > -1 {
				addr = addr[:i]
			}
		}
	}
	return addr
}
func (ctx *Context) renderHTML(status int, setName, tplName string, data ...interface{}) {
	if ctx.Render == nil {
		panic("renderer middleware hasn't been registered")
	}
	if len(data) == 0 {
		ctx.Render.HTMLSet(status, setName, tplName, ctx.Data)
	} else {
		ctx.Render.HTMLSet(status, setName, tplName, data[0])
		if len(data) > 1 {
			ctx.Render.HTMLSet(status, setName, tplName, data[0], data[1].(HTMLOptions))
		}
	}
}
func (ctx *Context) HTML(status int, name string, data ...interface{}) {
	ctx.renderHTML(status, _DEFAULT_TPL_SET_NAME, name, data...)
}
func (ctx *Context) HTMLSet(status int, setName, tplName string, data ...interface{}) {
	ctx.renderHTML(status, setName, tplName, data...)
}
func (ctx *Context) Redirect(location string, status ...int) {
	code := http.StatusFound
	if len(status) == 1 {
		code = status[0]
	}
	http.Redirect(ctx.Response, ctx.Request.Request, location, code)
}
func (ctx *Context) GetParam(name string) Value {
	return Value(ctx.params[name])
}
func (ctx *Context) SetParam(name, value string) {
	ctx.params[name] = value
}
func (ctx *Context) HasParam(name string) (Value, bool) {
	value, ok := ctx.params[name]
	return Value(value), ok
}
func (ctx *Context) GetFile(name string) (multipart.File, *multipart.FileHeader, error) {
	return ctx.Request.FormFile(name)
}
func (ctx *Context) GetFiles(name string) ([]*multipart.FileHeader, bool) {
	mf := ctx.Request.MultipartForm
	if mf == nil {
		return nil, false
	}
	if len(mf.File[name]) == 0 {
		return nil, false
	}
	return mf.File[name], true
}
func (ctx *Context) SetCookie(name string, value string, others ...interface{}) {
	cookie := http.Cookie{}
	cookie.Name = name
	cookie.Value = value
	if len(others) > 0 {
		switch v := others[0].(type) {
		case int:
			cookie.MaxAge = v
		case int64:
			cookie.MaxAge = int(v)
		case int32:
			cookie.MaxAge = int(v)
		}
	}
	if len(others) > 1 {
		if v, ok := others[1].(string); ok && len(v) > 0 {
			cookie.Path = v
		}
	} else {
		cookie.Path = "/"
	}
	if len(others) > 2 {
		if v, ok := others[2].(string); ok && len(v) > 0 {
			cookie.Domain = v
		}
	}
	if len(others) > 3 {
		switch v := others[3].(type) {
		case bool:
			cookie.Secure = v
		default:
			if others[3] != nil {
				cookie.Secure = true
			}
		}
	}
	if len(others) > 4 {
		if v, ok := others[4].(bool); ok && v {
			cookie.HttpOnly = true
		}
	}
	ctx.Response.Header().Add("Set-Cookie", cookie.String())
}
func (ctx *Context) GetCookie(name string) string {
	cookie, err := ctx.Request.Cookie(name)
	if err != nil {
		return ""
	}
	return cookie.Value
}
var defaultCookieSecret string
func (s *Seago) SetDefaultCookieSecret(secret string) {
	defaultCookieSecret = secret
}