123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- package tango
- import (
- "net/http"
- "os"
- )
- const (
- Dev = iota
- Prod
- )
- var (
- Env = Dev
- modes = []string{
- "Dev",
- "Product",
- }
- )
- func Version() string {
- return "0.2.8.0326"
- }
- type Tango struct {
- Router
- Mode int
- handlers []Handler
- logger Logger
- ErrHandler Handler
- }
- var (
- ClassicHandlers = []Handler{
- Logging(),
- Recovery(true),
- Compresses([]string{".js", ".css", ".html", ".htm"}),
- Static(StaticOptions{Prefix: "public"}),
- Return(),
- Responses(),
- Requests(),
- Param(),
- Contexts(),
- }
- )
- func (t *Tango) Logger() Logger {
- return t.logger
- }
- func (t *Tango) Get(url string, c interface{}) {
- t.Route([]string{"GET", "HEAD"}, url, c)
- }
- func (t *Tango) Post(url string, c interface{}) {
- t.Route([]string{"POST"}, url, c)
- }
- func (t *Tango) Head(url string, c interface{}) {
- t.Route([]string{"HEAD"}, url, c)
- }
- func (t *Tango) Options(url string, c interface{}) {
- t.Route([]string{"OPTIONS"}, url, c)
- }
- func (t *Tango) Trace(url string, c interface{}) {
- t.Route([]string{"TRACE"}, url, c)
- }
- func (t *Tango) Patch(url string, c interface{}) {
- t.Route([]string{"PATCH"}, url, c)
- }
- func (t *Tango) Delete(url string, c interface{}) {
- t.Route([]string{"DELETE"}, url, c)
- }
- func (t *Tango) Put(url string, c interface{}) {
- t.Route([]string{"PUT"}, url, c)
- }
- func (t *Tango) Any(url string, c interface{}) {
- t.Route(SupportMethods, url, c)
- }
- func (t *Tango) Use(handlers ...Handler) {
- t.handlers = append(t.handlers, handlers...)
- }
- func (t *Tango) Run(addrs ...string) {
- var addr string
- if len(addrs) == 0 {
- addr = ":8000"
- } else {
- addr = addrs[0]
- }
- t.logger.Info("listening on", addr, modes[t.Mode])
- err := http.ListenAndServe(addr, t)
- if err != nil {
- t.logger.Error(err)
- }
- }
- func (t *Tango) RunTLS(certFile, keyFile string, addrs ...string) {
- var addr string
- if len(addrs) == 0 {
- addr = ":8000"
- } else {
- addr = addrs[0]
- }
- t.logger.Info("listening on https", addr, modes[t.Mode])
- err := http.ListenAndServeTLS(addr, certFile, keyFile, t)
- if err != nil {
- t.logger.Error(err)
- }
- }
- type HandlerFunc func(ctx *Context)
- func (h HandlerFunc) Handle(ctx *Context) {
- h(ctx)
- }
- func WrapBefore(handler http.Handler) HandlerFunc {
- return func(ctx *Context) {
- handler.ServeHTTP(ctx.ResponseWriter, ctx.Req())
- ctx.Next()
- }
- }
- func WrapAfter(handler http.Handler) HandlerFunc {
- return func(ctx *Context) {
- ctx.Next()
- handler.ServeHTTP(ctx.ResponseWriter, ctx.Req())
- }
- }
- func (t *Tango) UseHandler(handler http.Handler) {
- t.Use(WrapBefore(handler))
- }
- func (t *Tango) ServeHTTP(w http.ResponseWriter, req *http.Request) {
- ctx := NewContext(
- t,
- req,
- NewResponseWriter(w),
- t.logger,
- )
- ctx.Invoke()
- // if there is no logging or error handle, so the last written check.
- if !ctx.Written() {
- p := req.URL.Path
- if len(req.URL.RawQuery) > 0 {
- p = p + "?" + req.URL.RawQuery
- }
- if ctx.Route() != nil {
- if ctx.Result == nil {
- ctx.Write([]byte(""))
- t.logger.Info(req.Method, ctx.Status(), p)
- return
- }
- panic("result should be handler before")
- }
- if ctx.Result == nil {
- ctx.Result = NotFound()
- }
- ctx.HandleError()
- t.logger.Error(req.Method, ctx.Status(), p)
- }
- }
- func NewWithLog(logger Logger, handlers ...Handler) *Tango {
- tango := &Tango{
- Router: NewRouter(),
- Mode: Env,
- logger: logger,
- handlers: make([]Handler, 0),
- ErrHandler: Errors(),
- }
- tango.Use(handlers...)
- return tango
- }
- func New(handlers ...Handler) *Tango {
- return NewWithLog(NewLogger(os.Stdout), handlers...)
- }
- func Classic(l ...Logger) *Tango {
- var logger Logger
- if len(l) == 0 {
- logger = NewLogger(os.Stdout)
- } else {
- logger = l[0]
- }
- return NewWithLog(
- logger,
- ClassicHandlers...,
- )
- }
|