mirror of
https://github.com/astaxie/beego.git
synced 2024-12-22 17:30:50 +00:00
Merge branch 'develop-2.0' of github.com:astaxie/beego into session_exists_return_err
This commit is contained in:
commit
ce50ca22d7
6
.gitignore
vendored
6
.gitignore
vendored
@ -4,3 +4,9 @@
|
||||
*.swp
|
||||
*.swo
|
||||
beego.iml
|
||||
|
||||
_beeTmp/
|
||||
_beeTmp2/
|
||||
pkg/_beeTmp/
|
||||
pkg/_beeTmp2/
|
||||
test/tmp/
|
||||
|
@ -12,12 +12,14 @@ please let us know if anything feels wrong or incomplete.
|
||||
### Pull requests
|
||||
|
||||
First of all. beego follow the gitflow. So please send you pull request
|
||||
to **develop** branch. We will close the pull request to master branch.
|
||||
to **develop-2** branch. We will close the pull request to master branch.
|
||||
|
||||
We are always happy to receive pull requests, and do our best to
|
||||
review them as fast as possible. Not sure if that typo is worth a pull
|
||||
request? Do it! We will appreciate it.
|
||||
|
||||
Don't forget to rebase your commits!
|
||||
|
||||
If your pull request is not accepted on the first try, don't be
|
||||
discouraged! Sometimes we can make a mistake, please do more explaining
|
||||
for us. We will appreciate it.
|
||||
|
3
admin.go
3
admin.go
@ -52,6 +52,7 @@ var beeAdminApp *adminApp
|
||||
// return true
|
||||
// }
|
||||
// beego.FilterMonitorFunc = MyFilterMonitor.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
var FilterMonitorFunc func(string, string, time.Duration, string, int) bool
|
||||
|
||||
func init() {
|
||||
@ -201,6 +202,7 @@ func list(root string, p interface{}, m M) {
|
||||
}
|
||||
|
||||
// PrintTree prints all registered routers.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func PrintTree() M {
|
||||
var (
|
||||
content = M{}
|
||||
@ -432,6 +434,7 @@ func (admin *adminApp) Route(pattern string, f http.HandlerFunc) {
|
||||
|
||||
// Run adminApp http server.
|
||||
// Its addr is defined in configuration file as adminhttpaddr and adminhttpport.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (admin *adminApp) Run() {
|
||||
if len(toolbox.AdminTaskList) > 0 {
|
||||
toolbox.StartTask()
|
||||
|
@ -6,10 +6,11 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/astaxie/beego/toolbox"
|
||||
)
|
||||
|
||||
@ -230,10 +231,19 @@ func TestHealthCheckHandlerReturnsJSON(t *testing.T) {
|
||||
t.Errorf("invalid response map length: got %d want %d",
|
||||
len(decodedResponseBody), len(expectedResponseBody))
|
||||
}
|
||||
assert.Equal(t, len(expectedResponseBody), len(decodedResponseBody))
|
||||
assert.Equal(t, 2, len(decodedResponseBody))
|
||||
|
||||
if !reflect.DeepEqual(decodedResponseBody, expectedResponseBody) {
|
||||
t.Errorf("handler returned unexpected body: got %v want %v",
|
||||
decodedResponseBody, expectedResponseBody)
|
||||
var database, cache map[string]interface{}
|
||||
if decodedResponseBody[0]["message"] == "database" {
|
||||
database = decodedResponseBody[0]
|
||||
cache = decodedResponseBody[1]
|
||||
} else {
|
||||
database = decodedResponseBody[1]
|
||||
cache = decodedResponseBody[0]
|
||||
}
|
||||
|
||||
assert.Equal(t, expectedResponseBody[0], database)
|
||||
assert.Equal(t, expectedResponseBody[1], cache)
|
||||
|
||||
}
|
||||
|
22
app.go
22
app.go
@ -35,6 +35,7 @@ import (
|
||||
|
||||
var (
|
||||
// BeeApp is an application instance
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
BeeApp *App
|
||||
)
|
||||
|
||||
@ -50,6 +51,7 @@ type App struct {
|
||||
}
|
||||
|
||||
// NewApp returns a new beego application.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func NewApp() *App {
|
||||
cr := NewControllerRegister()
|
||||
app := &App{Handlers: cr, Server: &http.Server{}}
|
||||
@ -57,9 +59,11 @@ func NewApp() *App {
|
||||
}
|
||||
|
||||
// MiddleWare function for http.Handler
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
type MiddleWare func(http.Handler) http.Handler
|
||||
|
||||
// Run beego application.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (app *App) Run(mws ...MiddleWare) {
|
||||
addr := BConfig.Listen.HTTPAddr
|
||||
|
||||
@ -197,7 +201,7 @@ func (app *App) Run(mws ...MiddleWare) {
|
||||
pool.AppendCertsFromPEM(data)
|
||||
app.Server.TLSConfig = &tls.Config{
|
||||
ClientCAs: pool,
|
||||
ClientAuth: tls.RequireAndVerifyClientCert,
|
||||
ClientAuth: BConfig.Listen.ClientAuth,
|
||||
}
|
||||
}
|
||||
if err := app.Server.ListenAndServeTLS(BConfig.Listen.HTTPSCertFile, BConfig.Listen.HTTPSKeyFile); err != nil {
|
||||
@ -254,6 +258,7 @@ func (app *App) Run(mws ...MiddleWare) {
|
||||
// beego.Router("/api/create",&RestController{},"post:CreateFood")
|
||||
// beego.Router("/api/update",&RestController{},"put:UpdateFood")
|
||||
// beego.Router("/api/delete",&RestController{},"delete:DeleteFood")
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func Router(rootpath string, c ControllerInterface, mappingMethods ...string) *App {
|
||||
BeeApp.Handlers.Add(rootpath, c, mappingMethods...)
|
||||
return BeeApp
|
||||
@ -268,6 +273,7 @@ func Router(rootpath string, c ControllerInterface, mappingMethods ...string) *A
|
||||
// Usage (replace "GET" with "*" for all methods):
|
||||
// beego.UnregisterFixedRoute("/yourpreviouspath", "GET")
|
||||
// beego.Router("/yourpreviouspath", yourControllerAddress, "get:GetNewPage")
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func UnregisterFixedRoute(fixedRoute string, method string) *App {
|
||||
subPaths := splitPath(fixedRoute)
|
||||
if method == "" || method == "*" {
|
||||
@ -364,6 +370,7 @@ func findAndRemoveSingleTree(entryPointTree *Tree) {
|
||||
// the comments @router url methodlist
|
||||
// url support all the function Router's pattern
|
||||
// methodlist [get post head put delete options *]
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func Include(cList ...ControllerInterface) *App {
|
||||
BeeApp.Handlers.Include(cList...)
|
||||
return BeeApp
|
||||
@ -372,6 +379,7 @@ func Include(cList ...ControllerInterface) *App {
|
||||
// RESTRouter adds a restful controller handler to BeeApp.
|
||||
// its' controller implements beego.ControllerInterface and
|
||||
// defines a param "pattern/:objectId" to visit each resource.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func RESTRouter(rootpath string, c ControllerInterface) *App {
|
||||
Router(rootpath, c)
|
||||
Router(path.Join(rootpath, ":objectId"), c)
|
||||
@ -382,6 +390,7 @@ func RESTRouter(rootpath string, c ControllerInterface) *App {
|
||||
// it's same to App.AutoRouter.
|
||||
// if beego.AddAuto(&MainContorlller{}) and MainController has methods List and Page,
|
||||
// visit the url /main/list to exec List function or /main/page to exec Page function.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func AutoRouter(c ControllerInterface) *App {
|
||||
BeeApp.Handlers.AddAuto(c)
|
||||
return BeeApp
|
||||
@ -391,6 +400,7 @@ func AutoRouter(c ControllerInterface) *App {
|
||||
// it's same to App.AutoRouterWithPrefix.
|
||||
// if beego.AutoPrefix("/admin",&MainContorlller{}) and MainController has methods List and Page,
|
||||
// visit the url /admin/main/list to exec List function or /admin/main/page to exec Page function.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func AutoPrefix(prefix string, c ControllerInterface) *App {
|
||||
BeeApp.Handlers.AddAutoPrefix(prefix, c)
|
||||
return BeeApp
|
||||
@ -401,6 +411,7 @@ func AutoPrefix(prefix string, c ControllerInterface) *App {
|
||||
// beego.Get("/", func(ctx *context.Context){
|
||||
// ctx.Output.Body("hello world")
|
||||
// })
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func Get(rootpath string, f FilterFunc) *App {
|
||||
BeeApp.Handlers.Get(rootpath, f)
|
||||
return BeeApp
|
||||
@ -411,6 +422,7 @@ func Get(rootpath string, f FilterFunc) *App {
|
||||
// beego.Post("/api", func(ctx *context.Context){
|
||||
// ctx.Output.Body("hello world")
|
||||
// })
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func Post(rootpath string, f FilterFunc) *App {
|
||||
BeeApp.Handlers.Post(rootpath, f)
|
||||
return BeeApp
|
||||
@ -421,6 +433,7 @@ func Post(rootpath string, f FilterFunc) *App {
|
||||
// beego.Delete("/api", func(ctx *context.Context){
|
||||
// ctx.Output.Body("hello world")
|
||||
// })
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func Delete(rootpath string, f FilterFunc) *App {
|
||||
BeeApp.Handlers.Delete(rootpath, f)
|
||||
return BeeApp
|
||||
@ -431,6 +444,7 @@ func Delete(rootpath string, f FilterFunc) *App {
|
||||
// beego.Put("/api", func(ctx *context.Context){
|
||||
// ctx.Output.Body("hello world")
|
||||
// })
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func Put(rootpath string, f FilterFunc) *App {
|
||||
BeeApp.Handlers.Put(rootpath, f)
|
||||
return BeeApp
|
||||
@ -441,6 +455,7 @@ func Put(rootpath string, f FilterFunc) *App {
|
||||
// beego.Head("/api", func(ctx *context.Context){
|
||||
// ctx.Output.Body("hello world")
|
||||
// })
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func Head(rootpath string, f FilterFunc) *App {
|
||||
BeeApp.Handlers.Head(rootpath, f)
|
||||
return BeeApp
|
||||
@ -451,6 +466,7 @@ func Head(rootpath string, f FilterFunc) *App {
|
||||
// beego.Options("/api", func(ctx *context.Context){
|
||||
// ctx.Output.Body("hello world")
|
||||
// })
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func Options(rootpath string, f FilterFunc) *App {
|
||||
BeeApp.Handlers.Options(rootpath, f)
|
||||
return BeeApp
|
||||
@ -461,6 +477,7 @@ func Options(rootpath string, f FilterFunc) *App {
|
||||
// beego.Patch("/api", func(ctx *context.Context){
|
||||
// ctx.Output.Body("hello world")
|
||||
// })
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func Patch(rootpath string, f FilterFunc) *App {
|
||||
BeeApp.Handlers.Patch(rootpath, f)
|
||||
return BeeApp
|
||||
@ -471,6 +488,7 @@ func Patch(rootpath string, f FilterFunc) *App {
|
||||
// beego.Any("/api", func(ctx *context.Context){
|
||||
// ctx.Output.Body("hello world")
|
||||
// })
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func Any(rootpath string, f FilterFunc) *App {
|
||||
BeeApp.Handlers.Any(rootpath, f)
|
||||
return BeeApp
|
||||
@ -481,6 +499,7 @@ func Any(rootpath string, f FilterFunc) *App {
|
||||
// beego.Handler("/api", http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) {
|
||||
// fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
|
||||
// }))
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func Handler(rootpath string, h http.Handler, options ...interface{}) *App {
|
||||
BeeApp.Handlers.Handler(rootpath, h, options...)
|
||||
return BeeApp
|
||||
@ -490,6 +509,7 @@ func Handler(rootpath string, h http.Handler, options ...interface{}) *App {
|
||||
// The pos means action constant including
|
||||
// beego.BeforeStatic, beego.BeforeRouter, beego.BeforeExec, beego.AfterExec and beego.FinishRouter.
|
||||
// The bool params is for setting the returnOnOutput value (false allows multiple filters to execute)
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func InsertFilter(pattern string, pos int, filter FilterFunc, params ...bool) *App {
|
||||
BeeApp.Handlers.InsertFilter(pattern, pos, filter, params...)
|
||||
return BeeApp
|
||||
|
9
beego.go
9
beego.go
@ -23,15 +23,19 @@ import (
|
||||
|
||||
const (
|
||||
// VERSION represent beego web framework version.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
VERSION = "1.12.2"
|
||||
|
||||
// DEV is for develop
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
DEV = "dev"
|
||||
// PROD is for production
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
PROD = "prod"
|
||||
)
|
||||
|
||||
// M is Map shortcut
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
type M map[string]interface{}
|
||||
|
||||
// Hook function to run
|
||||
@ -44,6 +48,7 @@ var (
|
||||
// AddAPPStartHook is used to register the hookfunc
|
||||
// The hookfuncs will run in beego.Run()
|
||||
// such as initiating session , starting middleware , building template, starting admin control and so on.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func AddAPPStartHook(hf ...hookfunc) {
|
||||
hooks = append(hooks, hf...)
|
||||
}
|
||||
@ -53,6 +58,7 @@ func AddAPPStartHook(hf ...hookfunc) {
|
||||
// beego.Run("localhost")
|
||||
// beego.Run(":8089")
|
||||
// beego.Run("127.0.0.1:8089")
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func Run(params ...string) {
|
||||
|
||||
initBeforeHTTPRun()
|
||||
@ -73,6 +79,7 @@ func Run(params ...string) {
|
||||
}
|
||||
|
||||
// RunWithMiddleWares Run beego application with middlewares.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func RunWithMiddleWares(addr string, mws ...MiddleWare) {
|
||||
initBeforeHTTPRun()
|
||||
|
||||
@ -107,6 +114,7 @@ func initBeforeHTTPRun() {
|
||||
}
|
||||
|
||||
// TestBeegoInit is for test package init
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func TestBeegoInit(ap string) {
|
||||
path := filepath.Join(ap, "conf", "app.conf")
|
||||
os.Chdir(ap)
|
||||
@ -114,6 +122,7 @@ func TestBeegoInit(ap string) {
|
||||
}
|
||||
|
||||
// InitBeegoBeforeTest is for test package init
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func InitBeegoBeforeTest(appConfigPath string) {
|
||||
if err := LoadAppConfig(appConfigProvider, appConfigPath); err != nil {
|
||||
panic(err)
|
||||
|
@ -15,13 +15,20 @@
|
||||
package beego
|
||||
|
||||
var (
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
BuildVersion string
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
BuildGitRevision string
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
BuildStatus string
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
BuildTag string
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
BuildTime string
|
||||
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
GoVersion string
|
||||
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
GitBranch string
|
||||
)
|
||||
|
33
config.go
33
config.go
@ -21,6 +21,7 @@ import (
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strings"
|
||||
"crypto/tls"
|
||||
|
||||
"github.com/astaxie/beego/config"
|
||||
"github.com/astaxie/beego/context"
|
||||
@ -30,6 +31,7 @@ import (
|
||||
)
|
||||
|
||||
// Config is the main struct for BConfig
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
type Config struct {
|
||||
AppName string //Application name
|
||||
RunMode string //Running Mode: dev | prod
|
||||
@ -48,6 +50,7 @@ type Config struct {
|
||||
}
|
||||
|
||||
// Listen holds for http and https related config
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
type Listen struct {
|
||||
Graceful bool // Graceful means use graceful module to start the server
|
||||
ServerTimeOut int64
|
||||
@ -65,6 +68,7 @@ type Listen struct {
|
||||
HTTPSCertFile string
|
||||
HTTPSKeyFile string
|
||||
TrustCaFile string
|
||||
ClientAuth tls.ClientAuthType
|
||||
EnableAdmin bool
|
||||
AdminAddr string
|
||||
AdminPort int
|
||||
@ -73,6 +77,7 @@ type Listen struct {
|
||||
}
|
||||
|
||||
// WebConfig holds web related config
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
type WebConfig struct {
|
||||
AutoRender bool
|
||||
EnableDocs bool
|
||||
@ -93,6 +98,7 @@ type WebConfig struct {
|
||||
}
|
||||
|
||||
// SessionConfig holds session related config
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
type SessionConfig struct {
|
||||
SessionOn bool
|
||||
SessionProvider string
|
||||
@ -109,6 +115,7 @@ type SessionConfig struct {
|
||||
}
|
||||
|
||||
// LogConfig holds Log related config
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
type LogConfig struct {
|
||||
AccessLogs bool
|
||||
EnableStaticLogs bool //log static files requests default: false
|
||||
@ -119,12 +126,16 @@ type LogConfig struct {
|
||||
|
||||
var (
|
||||
// BConfig is the default config for Application
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
BConfig *Config
|
||||
// AppConfig is the instance of Config, store the config information from file
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
AppConfig *beegoAppConfig
|
||||
// AppPath is the absolute path to the app
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
AppPath string
|
||||
// GlobalSessions is the instance for the session manager
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
GlobalSessions *session.Manager
|
||||
|
||||
// appConfigPath is the path to the config files
|
||||
@ -132,6 +143,7 @@ var (
|
||||
// appConfigProvider is the provider for the config, default is ini
|
||||
appConfigProvider = "ini"
|
||||
// WorkPath is the absolute path to project root directory
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
WorkPath string
|
||||
)
|
||||
|
||||
@ -150,6 +162,9 @@ func init() {
|
||||
filename = os.Getenv("BEEGO_RUNMODE") + ".app.conf"
|
||||
}
|
||||
appConfigPath = filepath.Join(WorkPath, "conf", filename)
|
||||
if configPath := os.Getenv("BEEGO_CONFIG_PATH"); configPath != "" {
|
||||
appConfigPath = configPath
|
||||
}
|
||||
if !utils.FileExists(appConfigPath) {
|
||||
appConfigPath = filepath.Join(AppPath, "conf", filename)
|
||||
if !utils.FileExists(appConfigPath) {
|
||||
@ -231,6 +246,7 @@ func newBConfig() *Config {
|
||||
AdminPort: 8088,
|
||||
EnableFcgi: false,
|
||||
EnableStdIo: false,
|
||||
ClientAuth: tls.RequireAndVerifyClientCert,
|
||||
},
|
||||
WebConfig: WebConfig{
|
||||
AutoRender: true,
|
||||
@ -392,6 +408,7 @@ func assignSingleConfig(p interface{}, ac config.Configer) {
|
||||
}
|
||||
|
||||
// LoadAppConfig allow developer to apply a config file
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func LoadAppConfig(adapterName, configPath string) error {
|
||||
absConfigPath, err := filepath.Abs(configPath)
|
||||
if err != nil {
|
||||
@ -420,6 +437,7 @@ func newAppConfig(appConfigProvider, appConfigPath string) (*beegoAppConfig, err
|
||||
return &beegoAppConfig{ac}, nil
|
||||
}
|
||||
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (b *beegoAppConfig) Set(key, val string) error {
|
||||
if err := b.innerConfig.Set(BConfig.RunMode+"::"+key, val); err != nil {
|
||||
return b.innerConfig.Set(key, val)
|
||||
@ -427,6 +445,7 @@ func (b *beegoAppConfig) Set(key, val string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (b *beegoAppConfig) String(key string) string {
|
||||
if v := b.innerConfig.String(BConfig.RunMode + "::" + key); v != "" {
|
||||
return v
|
||||
@ -434,6 +453,7 @@ func (b *beegoAppConfig) String(key string) string {
|
||||
return b.innerConfig.String(key)
|
||||
}
|
||||
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (b *beegoAppConfig) Strings(key string) []string {
|
||||
if v := b.innerConfig.Strings(BConfig.RunMode + "::" + key); len(v) > 0 {
|
||||
return v
|
||||
@ -441,6 +461,7 @@ func (b *beegoAppConfig) Strings(key string) []string {
|
||||
return b.innerConfig.Strings(key)
|
||||
}
|
||||
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (b *beegoAppConfig) Int(key string) (int, error) {
|
||||
if v, err := b.innerConfig.Int(BConfig.RunMode + "::" + key); err == nil {
|
||||
return v, nil
|
||||
@ -448,6 +469,7 @@ func (b *beegoAppConfig) Int(key string) (int, error) {
|
||||
return b.innerConfig.Int(key)
|
||||
}
|
||||
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (b *beegoAppConfig) Int64(key string) (int64, error) {
|
||||
if v, err := b.innerConfig.Int64(BConfig.RunMode + "::" + key); err == nil {
|
||||
return v, nil
|
||||
@ -455,6 +477,7 @@ func (b *beegoAppConfig) Int64(key string) (int64, error) {
|
||||
return b.innerConfig.Int64(key)
|
||||
}
|
||||
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (b *beegoAppConfig) Bool(key string) (bool, error) {
|
||||
if v, err := b.innerConfig.Bool(BConfig.RunMode + "::" + key); err == nil {
|
||||
return v, nil
|
||||
@ -462,6 +485,7 @@ func (b *beegoAppConfig) Bool(key string) (bool, error) {
|
||||
return b.innerConfig.Bool(key)
|
||||
}
|
||||
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (b *beegoAppConfig) Float(key string) (float64, error) {
|
||||
if v, err := b.innerConfig.Float(BConfig.RunMode + "::" + key); err == nil {
|
||||
return v, nil
|
||||
@ -469,6 +493,7 @@ func (b *beegoAppConfig) Float(key string) (float64, error) {
|
||||
return b.innerConfig.Float(key)
|
||||
}
|
||||
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (b *beegoAppConfig) DefaultString(key string, defaultVal string) string {
|
||||
if v := b.String(key); v != "" {
|
||||
return v
|
||||
@ -476,6 +501,7 @@ func (b *beegoAppConfig) DefaultString(key string, defaultVal string) string {
|
||||
return defaultVal
|
||||
}
|
||||
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (b *beegoAppConfig) DefaultStrings(key string, defaultVal []string) []string {
|
||||
if v := b.Strings(key); len(v) != 0 {
|
||||
return v
|
||||
@ -483,6 +509,7 @@ func (b *beegoAppConfig) DefaultStrings(key string, defaultVal []string) []strin
|
||||
return defaultVal
|
||||
}
|
||||
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (b *beegoAppConfig) DefaultInt(key string, defaultVal int) int {
|
||||
if v, err := b.Int(key); err == nil {
|
||||
return v
|
||||
@ -490,6 +517,7 @@ func (b *beegoAppConfig) DefaultInt(key string, defaultVal int) int {
|
||||
return defaultVal
|
||||
}
|
||||
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (b *beegoAppConfig) DefaultInt64(key string, defaultVal int64) int64 {
|
||||
if v, err := b.Int64(key); err == nil {
|
||||
return v
|
||||
@ -497,6 +525,7 @@ func (b *beegoAppConfig) DefaultInt64(key string, defaultVal int64) int64 {
|
||||
return defaultVal
|
||||
}
|
||||
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (b *beegoAppConfig) DefaultBool(key string, defaultVal bool) bool {
|
||||
if v, err := b.Bool(key); err == nil {
|
||||
return v
|
||||
@ -504,6 +533,7 @@ func (b *beegoAppConfig) DefaultBool(key string, defaultVal bool) bool {
|
||||
return defaultVal
|
||||
}
|
||||
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (b *beegoAppConfig) DefaultFloat(key string, defaultVal float64) float64 {
|
||||
if v, err := b.Float(key); err == nil {
|
||||
return v
|
||||
@ -511,14 +541,17 @@ func (b *beegoAppConfig) DefaultFloat(key string, defaultVal float64) float64 {
|
||||
return defaultVal
|
||||
}
|
||||
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (b *beegoAppConfig) DIY(key string) (interface{}, error) {
|
||||
return b.innerConfig.DIY(key)
|
||||
}
|
||||
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (b *beegoAppConfig) GetSection(section string) (map[string]string, error) {
|
||||
return b.innerConfig.GetSection(section)
|
||||
}
|
||||
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (b *beegoAppConfig) SaveConfigFile(filename string) error {
|
||||
return b.innerConfig.SaveConfigFile(filename)
|
||||
}
|
||||
|
@ -150,7 +150,7 @@ func (ctx *Context) XSRFToken(key string, expire int64) string {
|
||||
token, ok := ctx.GetSecureCookie(key, "_xsrf")
|
||||
if !ok {
|
||||
token = string(utils.RandomCreateBytes(32))
|
||||
ctx.SetSecureCookie(key, "_xsrf", token, expire)
|
||||
ctx.SetSecureCookie(key, "_xsrf", token, expire, "", "", true, true)
|
||||
}
|
||||
ctx._xsrfToken = token
|
||||
}
|
||||
|
@ -17,7 +17,10 @@ package context
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestXsrfReset_01(t *testing.T) {
|
||||
@ -44,4 +47,8 @@ func TestXsrfReset_01(t *testing.T) {
|
||||
if token == c._xsrfToken {
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
ck := c.ResponseWriter.Header().Get("Set-Cookie")
|
||||
assert.True(t, strings.Contains(ck, "Secure"))
|
||||
assert.True(t, strings.Contains(ck, "HttpOnly"))
|
||||
}
|
||||
|
@ -35,12 +35,15 @@ import (
|
||||
|
||||
var (
|
||||
// ErrAbort custom error when user stop request handler manually.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
ErrAbort = errors.New("user stop run")
|
||||
// GlobalControllerRouter store comments with controller. pkgpath+controller:comments
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
GlobalControllerRouter = make(map[string][]ControllerComments)
|
||||
)
|
||||
|
||||
// ControllerFilter store the filter for controller
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
type ControllerFilter struct {
|
||||
Pattern string
|
||||
Pos int
|
||||
@ -50,6 +53,7 @@ type ControllerFilter struct {
|
||||
}
|
||||
|
||||
// ControllerFilterComments store the comment for controller level filter
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
type ControllerFilterComments struct {
|
||||
Pattern string
|
||||
Pos int
|
||||
@ -59,12 +63,14 @@ type ControllerFilterComments struct {
|
||||
}
|
||||
|
||||
// ControllerImportComments store the import comment for controller needed
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
type ControllerImportComments struct {
|
||||
ImportPath string
|
||||
ImportAlias string
|
||||
}
|
||||
|
||||
// ControllerComments store the comment for the controller method
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
type ControllerComments struct {
|
||||
Method string
|
||||
Router string
|
||||
@ -77,6 +83,7 @@ type ControllerComments struct {
|
||||
}
|
||||
|
||||
// ControllerCommentsSlice implements the sort interface
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
type ControllerCommentsSlice []ControllerComments
|
||||
|
||||
func (p ControllerCommentsSlice) Len() int { return len(p) }
|
||||
@ -85,6 +92,7 @@ func (p ControllerCommentsSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
|
||||
|
||||
// Controller defines some basic http request handler operations, such as
|
||||
// http context, template and view, session and xsrf.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
type Controller struct {
|
||||
// context data
|
||||
Ctx *context.Context
|
||||
@ -115,6 +123,7 @@ type Controller struct {
|
||||
}
|
||||
|
||||
// ControllerInterface is an interface to uniform all controller handler.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
type ControllerInterface interface {
|
||||
Init(ct *context.Context, controllerName, actionName string, app interface{})
|
||||
Prepare()
|
||||
@ -135,6 +144,7 @@ type ControllerInterface interface {
|
||||
}
|
||||
|
||||
// Init generates default values of controller operations.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) Init(ctx *context.Context, controllerName, actionName string, app interface{}) {
|
||||
c.Layout = ""
|
||||
c.TplName = ""
|
||||
@ -150,42 +160,51 @@ func (c *Controller) Init(ctx *context.Context, controllerName, actionName strin
|
||||
}
|
||||
|
||||
// Prepare runs after Init before request function execution.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) Prepare() {}
|
||||
|
||||
// Finish runs after request function execution.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) Finish() {}
|
||||
|
||||
// Get adds a request function to handle GET request.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) Get() {
|
||||
http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", http.StatusMethodNotAllowed)
|
||||
}
|
||||
|
||||
// Post adds a request function to handle POST request.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) Post() {
|
||||
http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", http.StatusMethodNotAllowed)
|
||||
}
|
||||
|
||||
// Delete adds a request function to handle DELETE request.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) Delete() {
|
||||
http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", http.StatusMethodNotAllowed)
|
||||
}
|
||||
|
||||
// Put adds a request function to handle PUT request.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) Put() {
|
||||
http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", http.StatusMethodNotAllowed)
|
||||
}
|
||||
|
||||
// Head adds a request function to handle HEAD request.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) Head() {
|
||||
http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", http.StatusMethodNotAllowed)
|
||||
}
|
||||
|
||||
// Patch adds a request function to handle PATCH request.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) Patch() {
|
||||
http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", http.StatusMethodNotAllowed)
|
||||
}
|
||||
|
||||
// Options adds a request function to handle OPTIONS request.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) Options() {
|
||||
http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", http.StatusMethodNotAllowed)
|
||||
}
|
||||
@ -198,6 +217,7 @@ func (c *Controller) Options() {
|
||||
// reflect the message received, excluding some fields described below,
|
||||
// back to the client as the message body of a 200 (OK) response with a
|
||||
// Content-Type of "message/http" (Section 8.3.1 of [RFC7230]).
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) Trace() {
|
||||
ts := func(h http.Header) (hs string) {
|
||||
for k, v := range h {
|
||||
@ -213,6 +233,7 @@ func (c *Controller) Trace() {
|
||||
}
|
||||
|
||||
// HandlerFunc call function with the name
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) HandlerFunc(fnname string) bool {
|
||||
if v, ok := c.methodMapping[fnname]; ok {
|
||||
v()
|
||||
@ -222,14 +243,17 @@ func (c *Controller) HandlerFunc(fnname string) bool {
|
||||
}
|
||||
|
||||
// URLMapping register the internal Controller router.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) URLMapping() {}
|
||||
|
||||
// Mapping the method to function
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) Mapping(method string, fn func()) {
|
||||
c.methodMapping[method] = fn
|
||||
}
|
||||
|
||||
// Render sends the response with rendered template bytes as text/html type.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) Render() error {
|
||||
if !c.EnableRender {
|
||||
return nil
|
||||
@ -247,12 +271,14 @@ func (c *Controller) Render() error {
|
||||
}
|
||||
|
||||
// RenderString returns the rendered template string. Do not send out response.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) RenderString() (string, error) {
|
||||
b, e := c.RenderBytes()
|
||||
return string(b), e
|
||||
}
|
||||
|
||||
// RenderBytes returns the bytes of rendered template string. Do not send out response.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) RenderBytes() ([]byte, error) {
|
||||
buf, err := c.renderTemplate()
|
||||
//if the controller has set layout, then first get the tplName's content set the content to the layout
|
||||
@ -314,12 +340,14 @@ func (c *Controller) viewPath() string {
|
||||
}
|
||||
|
||||
// Redirect sends the redirection response to url with status code.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) Redirect(url string, code int) {
|
||||
LogAccess(c.Ctx, nil, code)
|
||||
c.Ctx.Redirect(code, url)
|
||||
}
|
||||
|
||||
// SetData set the data depending on the accepted
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) SetData(data interface{}) {
|
||||
accept := c.Ctx.Input.Header("Accept")
|
||||
switch accept {
|
||||
@ -333,6 +361,7 @@ func (c *Controller) SetData(data interface{}) {
|
||||
}
|
||||
|
||||
// Abort stops controller handler and show the error data if code is defined in ErrorMap or code string.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) Abort(code string) {
|
||||
status, err := strconv.Atoi(code)
|
||||
if err != nil {
|
||||
@ -342,6 +371,7 @@ func (c *Controller) Abort(code string) {
|
||||
}
|
||||
|
||||
// CustomAbort stops controller handler and show the error data, it's similar Aborts, but support status code and body.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) CustomAbort(status int, body string) {
|
||||
// first panic from ErrorMaps, it is user defined error functions.
|
||||
if _, ok := ErrorMaps[body]; ok {
|
||||
@ -355,12 +385,14 @@ func (c *Controller) CustomAbort(status int, body string) {
|
||||
}
|
||||
|
||||
// StopRun makes panic of USERSTOPRUN error and go to recover function if defined.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) StopRun() {
|
||||
panic(ErrAbort)
|
||||
}
|
||||
|
||||
// URLFor does another controller handler in this request function.
|
||||
// it goes to this controller method if endpoint is not clear.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) URLFor(endpoint string, values ...interface{}) string {
|
||||
if len(endpoint) == 0 {
|
||||
return ""
|
||||
@ -372,6 +404,7 @@ func (c *Controller) URLFor(endpoint string, values ...interface{}) string {
|
||||
}
|
||||
|
||||
// ServeJSON sends a json response with encoding charset.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) ServeJSON(encoding ...bool) {
|
||||
var (
|
||||
hasIndent = BConfig.RunMode != PROD
|
||||
@ -382,23 +415,27 @@ func (c *Controller) ServeJSON(encoding ...bool) {
|
||||
}
|
||||
|
||||
// ServeJSONP sends a jsonp response.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) ServeJSONP() {
|
||||
hasIndent := BConfig.RunMode != PROD
|
||||
c.Ctx.Output.JSONP(c.Data["jsonp"], hasIndent)
|
||||
}
|
||||
|
||||
// ServeXML sends xml response.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) ServeXML() {
|
||||
hasIndent := BConfig.RunMode != PROD
|
||||
c.Ctx.Output.XML(c.Data["xml"], hasIndent)
|
||||
}
|
||||
|
||||
// ServeYAML sends yaml response.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) ServeYAML() {
|
||||
c.Ctx.Output.YAML(c.Data["yaml"])
|
||||
}
|
||||
|
||||
// ServeFormatted serve YAML, XML OR JSON, depending on the value of the Accept header
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) ServeFormatted(encoding ...bool) {
|
||||
hasIndent := BConfig.RunMode != PROD
|
||||
hasEncoding := len(encoding) > 0 && encoding[0]
|
||||
@ -406,6 +443,7 @@ func (c *Controller) ServeFormatted(encoding ...bool) {
|
||||
}
|
||||
|
||||
// Input returns the input data map from POST or PUT request body and query string.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) Input() url.Values {
|
||||
if c.Ctx.Request.Form == nil {
|
||||
c.Ctx.Request.ParseForm()
|
||||
@ -414,11 +452,13 @@ func (c *Controller) Input() url.Values {
|
||||
}
|
||||
|
||||
// ParseForm maps input data map to obj struct.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) ParseForm(obj interface{}) error {
|
||||
return ParseForm(c.Input(), obj)
|
||||
}
|
||||
|
||||
// GetString returns the input value by key string or the default value while it's present and input is blank
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) GetString(key string, def ...string) string {
|
||||
if v := c.Ctx.Input.Query(key); v != "" {
|
||||
return v
|
||||
@ -431,6 +471,7 @@ func (c *Controller) GetString(key string, def ...string) string {
|
||||
|
||||
// GetStrings returns the input string slice by key string or the default value while it's present and input is blank
|
||||
// it's designed for multi-value input field such as checkbox(input[type=checkbox]), multi-selection.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) GetStrings(key string, def ...[]string) []string {
|
||||
var defv []string
|
||||
if len(def) > 0 {
|
||||
@ -447,6 +488,7 @@ func (c *Controller) GetStrings(key string, def ...[]string) []string {
|
||||
}
|
||||
|
||||
// GetInt returns input as an int or the default value while it's present and input is blank
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) GetInt(key string, def ...int) (int, error) {
|
||||
strv := c.Ctx.Input.Query(key)
|
||||
if len(strv) == 0 && len(def) > 0 {
|
||||
@ -456,6 +498,7 @@ func (c *Controller) GetInt(key string, def ...int) (int, error) {
|
||||
}
|
||||
|
||||
// GetInt8 return input as an int8 or the default value while it's present and input is blank
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) GetInt8(key string, def ...int8) (int8, error) {
|
||||
strv := c.Ctx.Input.Query(key)
|
||||
if len(strv) == 0 && len(def) > 0 {
|
||||
@ -466,6 +509,7 @@ func (c *Controller) GetInt8(key string, def ...int8) (int8, error) {
|
||||
}
|
||||
|
||||
// GetUint8 return input as an uint8 or the default value while it's present and input is blank
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) GetUint8(key string, def ...uint8) (uint8, error) {
|
||||
strv := c.Ctx.Input.Query(key)
|
||||
if len(strv) == 0 && len(def) > 0 {
|
||||
@ -476,6 +520,7 @@ func (c *Controller) GetUint8(key string, def ...uint8) (uint8, error) {
|
||||
}
|
||||
|
||||
// GetInt16 returns input as an int16 or the default value while it's present and input is blank
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) GetInt16(key string, def ...int16) (int16, error) {
|
||||
strv := c.Ctx.Input.Query(key)
|
||||
if len(strv) == 0 && len(def) > 0 {
|
||||
@ -486,6 +531,7 @@ func (c *Controller) GetInt16(key string, def ...int16) (int16, error) {
|
||||
}
|
||||
|
||||
// GetUint16 returns input as an uint16 or the default value while it's present and input is blank
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) GetUint16(key string, def ...uint16) (uint16, error) {
|
||||
strv := c.Ctx.Input.Query(key)
|
||||
if len(strv) == 0 && len(def) > 0 {
|
||||
@ -496,6 +542,7 @@ func (c *Controller) GetUint16(key string, def ...uint16) (uint16, error) {
|
||||
}
|
||||
|
||||
// GetInt32 returns input as an int32 or the default value while it's present and input is blank
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) GetInt32(key string, def ...int32) (int32, error) {
|
||||
strv := c.Ctx.Input.Query(key)
|
||||
if len(strv) == 0 && len(def) > 0 {
|
||||
@ -506,6 +553,7 @@ func (c *Controller) GetInt32(key string, def ...int32) (int32, error) {
|
||||
}
|
||||
|
||||
// GetUint32 returns input as an uint32 or the default value while it's present and input is blank
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) GetUint32(key string, def ...uint32) (uint32, error) {
|
||||
strv := c.Ctx.Input.Query(key)
|
||||
if len(strv) == 0 && len(def) > 0 {
|
||||
@ -516,6 +564,7 @@ func (c *Controller) GetUint32(key string, def ...uint32) (uint32, error) {
|
||||
}
|
||||
|
||||
// GetInt64 returns input value as int64 or the default value while it's present and input is blank.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) GetInt64(key string, def ...int64) (int64, error) {
|
||||
strv := c.Ctx.Input.Query(key)
|
||||
if len(strv) == 0 && len(def) > 0 {
|
||||
@ -525,6 +574,7 @@ func (c *Controller) GetInt64(key string, def ...int64) (int64, error) {
|
||||
}
|
||||
|
||||
// GetUint64 returns input value as uint64 or the default value while it's present and input is blank.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) GetUint64(key string, def ...uint64) (uint64, error) {
|
||||
strv := c.Ctx.Input.Query(key)
|
||||
if len(strv) == 0 && len(def) > 0 {
|
||||
@ -534,6 +584,7 @@ func (c *Controller) GetUint64(key string, def ...uint64) (uint64, error) {
|
||||
}
|
||||
|
||||
// GetBool returns input value as bool or the default value while it's present and input is blank.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) GetBool(key string, def ...bool) (bool, error) {
|
||||
strv := c.Ctx.Input.Query(key)
|
||||
if len(strv) == 0 && len(def) > 0 {
|
||||
@ -543,6 +594,7 @@ func (c *Controller) GetBool(key string, def ...bool) (bool, error) {
|
||||
}
|
||||
|
||||
// GetFloat returns input value as float64 or the default value while it's present and input is blank.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) GetFloat(key string, def ...float64) (float64, error) {
|
||||
strv := c.Ctx.Input.Query(key)
|
||||
if len(strv) == 0 && len(def) > 0 {
|
||||
@ -553,6 +605,7 @@ func (c *Controller) GetFloat(key string, def ...float64) (float64, error) {
|
||||
|
||||
// GetFile returns the file data in file upload field named as key.
|
||||
// it returns the first one of multi-uploaded files.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) GetFile(key string) (multipart.File, *multipart.FileHeader, error) {
|
||||
return c.Ctx.Request.FormFile(key)
|
||||
}
|
||||
@ -584,6 +637,7 @@ func (c *Controller) GetFile(key string) (multipart.File, *multipart.FileHeader,
|
||||
// return
|
||||
// }
|
||||
// }
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) GetFiles(key string) ([]*multipart.FileHeader, error) {
|
||||
if files, ok := c.Ctx.Request.MultipartForm.File[key]; ok {
|
||||
return files, nil
|
||||
@ -593,6 +647,7 @@ func (c *Controller) GetFiles(key string) ([]*multipart.FileHeader, error) {
|
||||
|
||||
// SaveToFile saves uploaded file to new path.
|
||||
// it only operates the first one of mutil-upload form file field.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) SaveToFile(fromfile, tofile string) error {
|
||||
file, _, err := c.Ctx.Request.FormFile(fromfile)
|
||||
if err != nil {
|
||||
@ -609,6 +664,7 @@ func (c *Controller) SaveToFile(fromfile, tofile string) error {
|
||||
}
|
||||
|
||||
// StartSession starts session and load old session data info this controller.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) StartSession() session.Store {
|
||||
if c.CruSession == nil {
|
||||
c.CruSession = c.Ctx.Input.CruSession
|
||||
@ -617,6 +673,7 @@ func (c *Controller) StartSession() session.Store {
|
||||
}
|
||||
|
||||
// SetSession puts value into session.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) SetSession(name interface{}, value interface{}) {
|
||||
if c.CruSession == nil {
|
||||
c.StartSession()
|
||||
@ -625,6 +682,7 @@ func (c *Controller) SetSession(name interface{}, value interface{}) {
|
||||
}
|
||||
|
||||
// GetSession gets value from session.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) GetSession(name interface{}) interface{} {
|
||||
if c.CruSession == nil {
|
||||
c.StartSession()
|
||||
@ -633,6 +691,7 @@ func (c *Controller) GetSession(name interface{}) interface{} {
|
||||
}
|
||||
|
||||
// DelSession removes value from session.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) DelSession(name interface{}) {
|
||||
if c.CruSession == nil {
|
||||
c.StartSession()
|
||||
@ -642,6 +701,7 @@ func (c *Controller) DelSession(name interface{}) {
|
||||
|
||||
// SessionRegenerateID regenerates session id for this session.
|
||||
// the session data have no changes.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) SessionRegenerateID() {
|
||||
if c.CruSession != nil {
|
||||
c.CruSession.SessionRelease(c.Ctx.ResponseWriter)
|
||||
@ -651,6 +711,7 @@ func (c *Controller) SessionRegenerateID() {
|
||||
}
|
||||
|
||||
// DestroySession cleans session data and session cookie.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) DestroySession() {
|
||||
c.Ctx.Input.CruSession.Flush()
|
||||
c.Ctx.Input.CruSession = nil
|
||||
@ -658,21 +719,25 @@ func (c *Controller) DestroySession() {
|
||||
}
|
||||
|
||||
// IsAjax returns this request is ajax or not.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) IsAjax() bool {
|
||||
return c.Ctx.Input.IsAjax()
|
||||
}
|
||||
|
||||
// GetSecureCookie returns decoded cookie value from encoded browser cookie values.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) GetSecureCookie(Secret, key string) (string, bool) {
|
||||
return c.Ctx.GetSecureCookie(Secret, key)
|
||||
}
|
||||
|
||||
// SetSecureCookie puts value into cookie after encoded the value.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) SetSecureCookie(Secret, name, value string, others ...interface{}) {
|
||||
c.Ctx.SetSecureCookie(Secret, name, value, others...)
|
||||
}
|
||||
|
||||
// XSRFToken creates a CSRF token string and returns.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) XSRFToken() string {
|
||||
if c._xsrfToken == "" {
|
||||
expire := int64(BConfig.WebConfig.XSRFExpire)
|
||||
@ -687,6 +752,7 @@ func (c *Controller) XSRFToken() string {
|
||||
// CheckXSRFCookie checks xsrf token in this request is valid or not.
|
||||
// the token can provided in request header "X-Xsrftoken" and "X-CsrfToken"
|
||||
// or in form field value named as "_xsrf".
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) CheckXSRFCookie() bool {
|
||||
if !c.EnableXSRF {
|
||||
return true
|
||||
@ -695,12 +761,14 @@ func (c *Controller) CheckXSRFCookie() bool {
|
||||
}
|
||||
|
||||
// XSRFFormHTML writes an input field contains xsrf token value.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) XSRFFormHTML() string {
|
||||
return `<input type="hidden" name="_xsrf" value="` +
|
||||
c.XSRFToken() + `" />`
|
||||
}
|
||||
|
||||
// GetControllerAndAction gets the executing controller name and action name.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *Controller) GetControllerAndAction() (string, string) {
|
||||
return c.controllerName, c.actionName
|
||||
}
|
||||
|
2
doc.go
2
doc.go
@ -13,5 +13,7 @@ beego is inspired by Tornado, Sinatra and Flask with the added benefit of some G
|
||||
}
|
||||
|
||||
more information: http://beego.me
|
||||
|
||||
Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
*/
|
||||
package beego
|
||||
|
4
error.go
4
error.go
@ -205,6 +205,7 @@ type errorInfo struct {
|
||||
|
||||
// ErrorMaps holds map of http handlers for each error string.
|
||||
// there is 10 kinds default error(40x and 50x)
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
var ErrorMaps = make(map[string]*errorInfo, 10)
|
||||
|
||||
// show 401 unauthorized error.
|
||||
@ -387,6 +388,7 @@ func responseError(rw http.ResponseWriter, r *http.Request, errCode int, errCont
|
||||
// usage:
|
||||
// beego.ErrorHandler("404",NotFound)
|
||||
// beego.ErrorHandler("500",InternalServerError)
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func ErrorHandler(code string, h http.HandlerFunc) *App {
|
||||
ErrorMaps[code] = &errorInfo{
|
||||
errorType: errorTypeHandler,
|
||||
@ -399,6 +401,7 @@ func ErrorHandler(code string, h http.HandlerFunc) *App {
|
||||
// ErrorController registers ControllerInterface to each http err code string.
|
||||
// usage:
|
||||
// beego.ErrorController(&controllers.ErrorController{})
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func ErrorController(c ControllerInterface) *App {
|
||||
reflectVal := reflect.ValueOf(c)
|
||||
rt := reflectVal.Type()
|
||||
@ -418,6 +421,7 @@ func ErrorController(c ControllerInterface) *App {
|
||||
}
|
||||
|
||||
// Exception Write HttpStatus with errCode and Exec error handler if exist.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func Exception(errCode uint64, ctx *context.Context) {
|
||||
exception(strconv.FormatUint(errCode, 10), ctx)
|
||||
}
|
||||
|
@ -17,11 +17,13 @@ package beego
|
||||
import "github.com/astaxie/beego/context"
|
||||
|
||||
// FilterFunc defines a filter function which is invoked before the controller handler is executed.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
type FilterFunc func(*context.Context)
|
||||
|
||||
// FilterRouter defines a filter operation which is invoked before the controller handler is executed.
|
||||
// It can match the URL against a pattern, and execute a filter function
|
||||
// when a request with a matching URL arrives.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
type FilterRouter struct {
|
||||
filterFunc FilterFunc
|
||||
tree *Tree
|
||||
@ -33,6 +35,7 @@ type FilterRouter struct {
|
||||
// ValidRouter checks if the current request is matched by this filter.
|
||||
// If the request is matched, the values of the URL parameters defined
|
||||
// by the filter pattern are also returned.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (f *FilterRouter) ValidRouter(url string, ctx *context.Context) bool {
|
||||
isOk := f.tree.Match(url, ctx)
|
||||
if isOk != nil {
|
||||
|
9
flash.go
9
flash.go
@ -21,11 +21,13 @@ import (
|
||||
)
|
||||
|
||||
// FlashData is a tools to maintain data when using across request.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
type FlashData struct {
|
||||
Data map[string]string
|
||||
}
|
||||
|
||||
// NewFlash return a new empty FlashData struct.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func NewFlash() *FlashData {
|
||||
return &FlashData{
|
||||
Data: make(map[string]string),
|
||||
@ -33,6 +35,7 @@ func NewFlash() *FlashData {
|
||||
}
|
||||
|
||||
// Set message to flash
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (fd *FlashData) Set(key string, msg string, args ...interface{}) {
|
||||
if len(args) == 0 {
|
||||
fd.Data[key] = msg
|
||||
@ -42,6 +45,7 @@ func (fd *FlashData) Set(key string, msg string, args ...interface{}) {
|
||||
}
|
||||
|
||||
// Success writes success message to flash.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (fd *FlashData) Success(msg string, args ...interface{}) {
|
||||
if len(args) == 0 {
|
||||
fd.Data["success"] = msg
|
||||
@ -51,6 +55,7 @@ func (fd *FlashData) Success(msg string, args ...interface{}) {
|
||||
}
|
||||
|
||||
// Notice writes notice message to flash.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (fd *FlashData) Notice(msg string, args ...interface{}) {
|
||||
if len(args) == 0 {
|
||||
fd.Data["notice"] = msg
|
||||
@ -60,6 +65,7 @@ func (fd *FlashData) Notice(msg string, args ...interface{}) {
|
||||
}
|
||||
|
||||
// Warning writes warning message to flash.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (fd *FlashData) Warning(msg string, args ...interface{}) {
|
||||
if len(args) == 0 {
|
||||
fd.Data["warning"] = msg
|
||||
@ -69,6 +75,7 @@ func (fd *FlashData) Warning(msg string, args ...interface{}) {
|
||||
}
|
||||
|
||||
// Error writes error message to flash.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (fd *FlashData) Error(msg string, args ...interface{}) {
|
||||
if len(args) == 0 {
|
||||
fd.Data["error"] = msg
|
||||
@ -79,6 +86,7 @@ func (fd *FlashData) Error(msg string, args ...interface{}) {
|
||||
|
||||
// Store does the saving operation of flash data.
|
||||
// the data are encoded and saved in cookie.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (fd *FlashData) Store(c *Controller) {
|
||||
c.Data["flash"] = fd.Data
|
||||
var flashValue string
|
||||
@ -89,6 +97,7 @@ func (fd *FlashData) Store(c *Controller) {
|
||||
}
|
||||
|
||||
// ReadFromRequest parsed flash data from encoded values in cookie.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func ReadFromRequest(c *Controller) *FlashData {
|
||||
flash := NewFlash()
|
||||
if cookie, err := c.Ctx.Request.Cookie(BConfig.WebConfig.FlashName); err == nil {
|
||||
|
3
fs.go
3
fs.go
@ -6,9 +6,11 @@ import (
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
type FileSystem struct {
|
||||
}
|
||||
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (d FileSystem) Open(name string) (http.File, error) {
|
||||
return os.Open(name)
|
||||
}
|
||||
@ -16,6 +18,7 @@ func (d FileSystem) Open(name string) (http.File, error) {
|
||||
// Walk walks the file tree rooted at root in filesystem, calling walkFn for each file or
|
||||
// directory in the tree, including root. All errors that arise visiting files
|
||||
// and directories are filtered by walkFn.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func Walk(fs http.FileSystem, root string, walkFn filepath.WalkFunc) error {
|
||||
|
||||
f, err := fs.Open(root)
|
||||
|
5
go.mod
5
go.mod
@ -12,6 +12,7 @@ require (
|
||||
github.com/couchbase/goutils v0.0.0-20180530154633-e865a1461c8a // indirect
|
||||
github.com/elastic/go-elasticsearch/v6 v6.8.5
|
||||
github.com/elazarl/go-bindata-assetfs v1.0.0
|
||||
github.com/go-kit/kit v0.9.0
|
||||
github.com/go-redis/redis v6.14.2+incompatible
|
||||
github.com/go-sql-driver/mysql v1.5.0
|
||||
github.com/gogo/protobuf v1.1.1
|
||||
@ -21,6 +22,7 @@ require (
|
||||
github.com/ledisdb/ledisdb v0.0.0-20200510135210-d35789ec47e6
|
||||
github.com/lib/pq v1.0.0
|
||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible
|
||||
github.com/opentracing/opentracing-go v1.2.0
|
||||
github.com/pelletier/go-toml v1.2.0 // indirect
|
||||
github.com/prometheus/client_golang v1.7.0
|
||||
github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644
|
||||
@ -29,7 +31,8 @@ require (
|
||||
github.com/syndtr/goleveldb v0.0.0-20181127023241-353a9fca669c // indirect
|
||||
github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b // indirect
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550
|
||||
golang.org/x/tools v0.0.0-20200117065230-39095c1d176c
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 // indirect
|
||||
google.golang.org/grpc v1.31.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.2.8
|
||||
)
|
||||
|
||||
|
47
go.sum
47
go.sum
@ -1,3 +1,4 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/Knetic/govaluate v3.0.0+incompatible h1:7o6+MAPhYTCF0+fdvoz1xDedhRb4f6s9Tn1Tt7/WTEg=
|
||||
@ -20,10 +21,13 @@ github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737 h1:rRISKWyXfVx
|
||||
github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60=
|
||||
github.com/casbin/casbin v1.7.0 h1:PuzlE8w0JBg/DhIqnkF1Dewf3z+qmUZMVN07PonvVUQ=
|
||||
github.com/casbin/casbin v1.7.0/go.mod h1:c67qKN6Oum3UF5Q1+BByfFxkwKvhwW57ITjqwtzR1KE=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58 h1:F1EaeKL/ta07PY/k9Os/UFtwERei2/XzGemhpGnBKNg=
|
||||
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/couchbase/go-couchbase v0.0.0-20200519150804-63f3cdb75e0d h1:OMrhQqj1QCyDT2sxHCDjE+k8aMdn2ngTCGG7g4wrdLo=
|
||||
github.com/couchbase/go-couchbase v0.0.0-20200519150804-63f3cdb75e0d/go.mod h1:TWI8EKQMs5u5jLKW/tsb9VwauIrMIxQG1r5fMsswK5U=
|
||||
github.com/couchbase/gomemcached v0.0.0-20200526233749-ec430f949808 h1:8s2l8TVUwMXl6tZMe3+hPCRJ25nQXiA3d1x622JtOqc=
|
||||
@ -41,25 +45,34 @@ github.com/elastic/go-elasticsearch/v6 v6.8.5 h1:U2HtkBseC1FNBmDr0TR2tKltL6FxoY+
|
||||
github.com/elastic/go-elasticsearch/v6 v6.8.5/go.mod h1:UwaDJsD3rWLM5rKNFzv9hgox93HoX8utj1kxD9aFUcI=
|
||||
github.com/elazarl/go-bindata-assetfs v1.0.0 h1:G/bYguwHIzWq9ZoyUQqrjTmJbbYn3j3CKKpKinvZLFk=
|
||||
github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/glendc/gopher-json v0.0.0-20170414221815-dc4743023d0c/go.mod h1:Gja1A+xZ9BoviGJNA2E9vFkPjjsl+CoJxSXiQM1UXtw=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-redis/redis v6.14.2+incompatible h1:UE9pLhzmWf+xHNmZsoccjXosPicuiNaInPgym8nzfg0=
|
||||
github.com/go-redis/redis v6.14.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-yaml/yaml v0.0.0-20180328195020-5420a8b6744d h1:xy93KVe+KrIIwWDEAfQBdIfsiHJkepbYsDr+VY3g9/o=
|
||||
github.com/go-yaml/yaml v0.0.0-20180328195020-5420a8b6744d/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
github.com/gogo/protobuf v1.1.1 h1:72R+M5VuhED/KujmZVcIquuo8mBgX4oVda//DQb3PXo=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
@ -72,6 +85,7 @@ github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pO
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/gomodule/redigo v2.0.0+incompatible h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNuhuh457pBFPtt0=
|
||||
github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||
@ -85,6 +99,7 @@ github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
@ -110,11 +125,12 @@ github.com/onsi/ginkgo v1.12.0 h1:Iw5WCbBcaAAd0fpRb1c9r5YCylv4XDoCSigm1zLevwU=
|
||||
github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
|
||||
github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
|
||||
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
|
||||
github.com/pelletier/go-toml v1.0.1/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/peterh/liner v1.0.1-0.20171122030339-3681c2a91233/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
|
||||
github.com/pingcap/tidb v2.0.11+incompatible/go.mod h1:I8C6jrPINP2rrVunTRd7C9fRRhQrtR43S1/CL5ix/yQ=
|
||||
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
@ -127,6 +143,7 @@ github.com/prometheus/client_golang v1.7.0 h1:wCi7urQOGBsYcQROHqpUUX4ct84xp40t9R
|
||||
github.com/prometheus/client_golang v1.7.0/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
@ -164,19 +181,28 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a h1:gOpx8G595UYyvj8UK4+OFyY4rx037g3fmfhe5SasG3U=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@ -189,10 +215,21 @@ golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 h1:ogLJMz+qpzav7lGMh10LMvAkM
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/tools v0.0.0-20200117065230-39095c1d176c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.31.0 h1:T7P4R73V3SSDPhH7WW7ATbfViLtmamH0DKrP3f9AuDI=
|
||||
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
@ -215,3 +252,5 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
@ -70,10 +70,11 @@ func TestReconnect(t *testing.T) {
|
||||
log.Informational("informational 2")
|
||||
|
||||
// Check if there was a second connection attempt
|
||||
select {
|
||||
case second := <-newConns:
|
||||
second.Close()
|
||||
default:
|
||||
t.Error("Did not reconnect")
|
||||
}
|
||||
// close this because we moved the codes to pkg/logs
|
||||
// select {
|
||||
// case second := <-newConns:
|
||||
// second.Close()
|
||||
// default:
|
||||
// t.Error("Did not reconnect")
|
||||
// }
|
||||
}
|
||||
|
@ -14,14 +14,11 @@
|
||||
|
||||
package logs
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestSmtp(t *testing.T) {
|
||||
log := NewLogger(10000)
|
||||
log.SetLogger("smtp", `{"username":"beegotest@gmail.com","password":"xxxxxxxx","host":"smtp.gmail.com:587","sendTos":["xiemengjun@gmail.com"]}`)
|
||||
log.Critical("sendmail critical")
|
||||
time.Sleep(time.Second * 30)
|
||||
}
|
||||
// it often failed. And we moved this to pkg/logs,
|
||||
// so we ignore it
|
||||
// func TestSmtp(t *testing.T) {
|
||||
// log := NewLogger(10000)
|
||||
// log.SetLogger("smtp", `{"username":"beegotest@gmail.com","password":"xxxxxxxx","host":"smtp.gmail.com:587","sendTos":["xiemengjun@gmail.com"]}`)
|
||||
// log.Critical("sendmail critical")
|
||||
// time.Sleep(time.Second * 30)
|
||||
// }
|
||||
|
@ -27,6 +27,8 @@ import (
|
||||
"github.com/astaxie/beego/logs"
|
||||
)
|
||||
|
||||
// Deprecated: we will removed this function in 2.1.0
|
||||
// please use pkg/web/filter/prometheus#FilterChain
|
||||
func PrometheusMiddleWare(next http.Handler) http.Handler {
|
||||
summaryVec := prometheus.NewSummaryVec(prometheus.SummaryOpts{
|
||||
Name: "beego",
|
||||
|
37
namespace.go
37
namespace.go
@ -24,15 +24,18 @@ import (
|
||||
type namespaceCond func(*beecontext.Context) bool
|
||||
|
||||
// LinkNamespace used as link action
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
type LinkNamespace func(*Namespace)
|
||||
|
||||
// Namespace is store all the info
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
type Namespace struct {
|
||||
prefix string
|
||||
handlers *ControllerRegister
|
||||
}
|
||||
|
||||
// NewNamespace get new Namespace
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func NewNamespace(prefix string, params ...LinkNamespace) *Namespace {
|
||||
ns := &Namespace{
|
||||
prefix: prefix,
|
||||
@ -54,6 +57,7 @@ func NewNamespace(prefix string, params ...LinkNamespace) *Namespace {
|
||||
// return false
|
||||
// })
|
||||
// Cond as the first filter
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (n *Namespace) Cond(cond namespaceCond) *Namespace {
|
||||
fn := func(ctx *beecontext.Context) {
|
||||
if !cond(ctx) {
|
||||
@ -83,6 +87,7 @@ func (n *Namespace) Cond(cond namespaceCond) *Namespace {
|
||||
// ctx.Redirect(302, "/login")
|
||||
// }
|
||||
// })
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (n *Namespace) Filter(action string, filter ...FilterFunc) *Namespace {
|
||||
var a int
|
||||
if action == "before" {
|
||||
@ -98,6 +103,7 @@ func (n *Namespace) Filter(action string, filter ...FilterFunc) *Namespace {
|
||||
|
||||
// Router same as beego.Rourer
|
||||
// refer: https://godoc.org/github.com/astaxie/beego#Router
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (n *Namespace) Router(rootpath string, c ControllerInterface, mappingMethods ...string) *Namespace {
|
||||
n.handlers.Add(rootpath, c, mappingMethods...)
|
||||
return n
|
||||
@ -105,6 +111,7 @@ func (n *Namespace) Router(rootpath string, c ControllerInterface, mappingMethod
|
||||
|
||||
// AutoRouter same as beego.AutoRouter
|
||||
// refer: https://godoc.org/github.com/astaxie/beego#AutoRouter
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (n *Namespace) AutoRouter(c ControllerInterface) *Namespace {
|
||||
n.handlers.AddAuto(c)
|
||||
return n
|
||||
@ -112,6 +119,7 @@ func (n *Namespace) AutoRouter(c ControllerInterface) *Namespace {
|
||||
|
||||
// AutoPrefix same as beego.AutoPrefix
|
||||
// refer: https://godoc.org/github.com/astaxie/beego#AutoPrefix
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (n *Namespace) AutoPrefix(prefix string, c ControllerInterface) *Namespace {
|
||||
n.handlers.AddAutoPrefix(prefix, c)
|
||||
return n
|
||||
@ -119,6 +127,7 @@ func (n *Namespace) AutoPrefix(prefix string, c ControllerInterface) *Namespace
|
||||
|
||||
// Get same as beego.Get
|
||||
// refer: https://godoc.org/github.com/astaxie/beego#Get
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (n *Namespace) Get(rootpath string, f FilterFunc) *Namespace {
|
||||
n.handlers.Get(rootpath, f)
|
||||
return n
|
||||
@ -126,6 +135,7 @@ func (n *Namespace) Get(rootpath string, f FilterFunc) *Namespace {
|
||||
|
||||
// Post same as beego.Post
|
||||
// refer: https://godoc.org/github.com/astaxie/beego#Post
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (n *Namespace) Post(rootpath string, f FilterFunc) *Namespace {
|
||||
n.handlers.Post(rootpath, f)
|
||||
return n
|
||||
@ -133,6 +143,7 @@ func (n *Namespace) Post(rootpath string, f FilterFunc) *Namespace {
|
||||
|
||||
// Delete same as beego.Delete
|
||||
// refer: https://godoc.org/github.com/astaxie/beego#Delete
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (n *Namespace) Delete(rootpath string, f FilterFunc) *Namespace {
|
||||
n.handlers.Delete(rootpath, f)
|
||||
return n
|
||||
@ -140,6 +151,7 @@ func (n *Namespace) Delete(rootpath string, f FilterFunc) *Namespace {
|
||||
|
||||
// Put same as beego.Put
|
||||
// refer: https://godoc.org/github.com/astaxie/beego#Put
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (n *Namespace) Put(rootpath string, f FilterFunc) *Namespace {
|
||||
n.handlers.Put(rootpath, f)
|
||||
return n
|
||||
@ -147,6 +159,7 @@ func (n *Namespace) Put(rootpath string, f FilterFunc) *Namespace {
|
||||
|
||||
// Head same as beego.Head
|
||||
// refer: https://godoc.org/github.com/astaxie/beego#Head
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (n *Namespace) Head(rootpath string, f FilterFunc) *Namespace {
|
||||
n.handlers.Head(rootpath, f)
|
||||
return n
|
||||
@ -154,6 +167,7 @@ func (n *Namespace) Head(rootpath string, f FilterFunc) *Namespace {
|
||||
|
||||
// Options same as beego.Options
|
||||
// refer: https://godoc.org/github.com/astaxie/beego#Options
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (n *Namespace) Options(rootpath string, f FilterFunc) *Namespace {
|
||||
n.handlers.Options(rootpath, f)
|
||||
return n
|
||||
@ -161,6 +175,7 @@ func (n *Namespace) Options(rootpath string, f FilterFunc) *Namespace {
|
||||
|
||||
// Patch same as beego.Patch
|
||||
// refer: https://godoc.org/github.com/astaxie/beego#Patch
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (n *Namespace) Patch(rootpath string, f FilterFunc) *Namespace {
|
||||
n.handlers.Patch(rootpath, f)
|
||||
return n
|
||||
@ -168,6 +183,7 @@ func (n *Namespace) Patch(rootpath string, f FilterFunc) *Namespace {
|
||||
|
||||
// Any same as beego.Any
|
||||
// refer: https://godoc.org/github.com/astaxie/beego#Any
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (n *Namespace) Any(rootpath string, f FilterFunc) *Namespace {
|
||||
n.handlers.Any(rootpath, f)
|
||||
return n
|
||||
@ -175,6 +191,7 @@ func (n *Namespace) Any(rootpath string, f FilterFunc) *Namespace {
|
||||
|
||||
// Handler same as beego.Handler
|
||||
// refer: https://godoc.org/github.com/astaxie/beego#Handler
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (n *Namespace) Handler(rootpath string, h http.Handler) *Namespace {
|
||||
n.handlers.Handler(rootpath, h)
|
||||
return n
|
||||
@ -182,6 +199,7 @@ func (n *Namespace) Handler(rootpath string, h http.Handler) *Namespace {
|
||||
|
||||
// Include add include class
|
||||
// refer: https://godoc.org/github.com/astaxie/beego#Include
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (n *Namespace) Include(cList ...ControllerInterface) *Namespace {
|
||||
n.handlers.Include(cList...)
|
||||
return n
|
||||
@ -204,6 +222,7 @@ func (n *Namespace) Include(cList ...ControllerInterface) *Namespace {
|
||||
// ctx.Output.Body([]byte("crminfo"))
|
||||
// }),
|
||||
//)
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (n *Namespace) Namespace(ns ...*Namespace) *Namespace {
|
||||
for _, ni := range ns {
|
||||
for k, v := range ni.handlers.routers {
|
||||
@ -233,6 +252,7 @@ func (n *Namespace) Namespace(ns ...*Namespace) *Namespace {
|
||||
|
||||
// AddNamespace register Namespace into beego.Handler
|
||||
// support multi Namespace
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func AddNamespace(nl ...*Namespace) {
|
||||
for _, n := range nl {
|
||||
for k, v := range n.handlers.routers {
|
||||
@ -276,6 +296,7 @@ func addPrefix(t *Tree, prefix string) {
|
||||
}
|
||||
|
||||
// NSCond is Namespace Condition
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func NSCond(cond namespaceCond) LinkNamespace {
|
||||
return func(ns *Namespace) {
|
||||
ns.Cond(cond)
|
||||
@ -283,6 +304,7 @@ func NSCond(cond namespaceCond) LinkNamespace {
|
||||
}
|
||||
|
||||
// NSBefore Namespace BeforeRouter filter
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func NSBefore(filterList ...FilterFunc) LinkNamespace {
|
||||
return func(ns *Namespace) {
|
||||
ns.Filter("before", filterList...)
|
||||
@ -290,6 +312,7 @@ func NSBefore(filterList ...FilterFunc) LinkNamespace {
|
||||
}
|
||||
|
||||
// NSAfter add Namespace FinishRouter filter
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func NSAfter(filterList ...FilterFunc) LinkNamespace {
|
||||
return func(ns *Namespace) {
|
||||
ns.Filter("after", filterList...)
|
||||
@ -297,6 +320,7 @@ func NSAfter(filterList ...FilterFunc) LinkNamespace {
|
||||
}
|
||||
|
||||
// NSInclude Namespace Include ControllerInterface
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func NSInclude(cList ...ControllerInterface) LinkNamespace {
|
||||
return func(ns *Namespace) {
|
||||
ns.Include(cList...)
|
||||
@ -304,6 +328,7 @@ func NSInclude(cList ...ControllerInterface) LinkNamespace {
|
||||
}
|
||||
|
||||
// NSRouter call Namespace Router
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func NSRouter(rootpath string, c ControllerInterface, mappingMethods ...string) LinkNamespace {
|
||||
return func(ns *Namespace) {
|
||||
ns.Router(rootpath, c, mappingMethods...)
|
||||
@ -311,6 +336,7 @@ func NSRouter(rootpath string, c ControllerInterface, mappingMethods ...string)
|
||||
}
|
||||
|
||||
// NSGet call Namespace Get
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func NSGet(rootpath string, f FilterFunc) LinkNamespace {
|
||||
return func(ns *Namespace) {
|
||||
ns.Get(rootpath, f)
|
||||
@ -318,6 +344,7 @@ func NSGet(rootpath string, f FilterFunc) LinkNamespace {
|
||||
}
|
||||
|
||||
// NSPost call Namespace Post
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func NSPost(rootpath string, f FilterFunc) LinkNamespace {
|
||||
return func(ns *Namespace) {
|
||||
ns.Post(rootpath, f)
|
||||
@ -325,6 +352,7 @@ func NSPost(rootpath string, f FilterFunc) LinkNamespace {
|
||||
}
|
||||
|
||||
// NSHead call Namespace Head
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func NSHead(rootpath string, f FilterFunc) LinkNamespace {
|
||||
return func(ns *Namespace) {
|
||||
ns.Head(rootpath, f)
|
||||
@ -332,6 +360,7 @@ func NSHead(rootpath string, f FilterFunc) LinkNamespace {
|
||||
}
|
||||
|
||||
// NSPut call Namespace Put
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func NSPut(rootpath string, f FilterFunc) LinkNamespace {
|
||||
return func(ns *Namespace) {
|
||||
ns.Put(rootpath, f)
|
||||
@ -339,6 +368,7 @@ func NSPut(rootpath string, f FilterFunc) LinkNamespace {
|
||||
}
|
||||
|
||||
// NSDelete call Namespace Delete
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func NSDelete(rootpath string, f FilterFunc) LinkNamespace {
|
||||
return func(ns *Namespace) {
|
||||
ns.Delete(rootpath, f)
|
||||
@ -346,6 +376,7 @@ func NSDelete(rootpath string, f FilterFunc) LinkNamespace {
|
||||
}
|
||||
|
||||
// NSAny call Namespace Any
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func NSAny(rootpath string, f FilterFunc) LinkNamespace {
|
||||
return func(ns *Namespace) {
|
||||
ns.Any(rootpath, f)
|
||||
@ -353,6 +384,7 @@ func NSAny(rootpath string, f FilterFunc) LinkNamespace {
|
||||
}
|
||||
|
||||
// NSOptions call Namespace Options
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func NSOptions(rootpath string, f FilterFunc) LinkNamespace {
|
||||
return func(ns *Namespace) {
|
||||
ns.Options(rootpath, f)
|
||||
@ -360,6 +392,7 @@ func NSOptions(rootpath string, f FilterFunc) LinkNamespace {
|
||||
}
|
||||
|
||||
// NSPatch call Namespace Patch
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func NSPatch(rootpath string, f FilterFunc) LinkNamespace {
|
||||
return func(ns *Namespace) {
|
||||
ns.Patch(rootpath, f)
|
||||
@ -367,6 +400,7 @@ func NSPatch(rootpath string, f FilterFunc) LinkNamespace {
|
||||
}
|
||||
|
||||
// NSAutoRouter call Namespace AutoRouter
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func NSAutoRouter(c ControllerInterface) LinkNamespace {
|
||||
return func(ns *Namespace) {
|
||||
ns.AutoRouter(c)
|
||||
@ -374,6 +408,7 @@ func NSAutoRouter(c ControllerInterface) LinkNamespace {
|
||||
}
|
||||
|
||||
// NSAutoPrefix call Namespace AutoPrefix
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func NSAutoPrefix(prefix string, c ControllerInterface) LinkNamespace {
|
||||
return func(ns *Namespace) {
|
||||
ns.AutoPrefix(prefix, c)
|
||||
@ -381,6 +416,7 @@ func NSAutoPrefix(prefix string, c ControllerInterface) LinkNamespace {
|
||||
}
|
||||
|
||||
// NSNamespace add sub Namespace
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func NSNamespace(prefix string, params ...LinkNamespace) LinkNamespace {
|
||||
return func(ns *Namespace) {
|
||||
n := NewNamespace(prefix, params...)
|
||||
@ -389,6 +425,7 @@ func NSNamespace(prefix string, params ...LinkNamespace) LinkNamespace {
|
||||
}
|
||||
|
||||
// NSHandler add handler
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func NSHandler(rootpath string, h http.Handler) LinkNamespace {
|
||||
return func(ns *Namespace) {
|
||||
ns.Handler(rootpath, h)
|
||||
|
@ -495,3 +495,10 @@ func InsertFilter(pattern string, pos int, filter FilterFunc, params ...bool) *A
|
||||
BeeApp.Handlers.InsertFilter(pattern, pos, filter, params...)
|
||||
return BeeApp
|
||||
}
|
||||
|
||||
// InsertFilterChain adds a FilterFunc built by filterChain.
|
||||
// This filter will be executed before all filters.
|
||||
func InsertFilterChain(pattern string, filterChain FilterChain, params ...bool) *App {
|
||||
BeeApp.Handlers.InsertFilterChain(pattern, filterChain, params...)
|
||||
return BeeApp
|
||||
}
|
||||
|
@ -150,7 +150,7 @@ func (ctx *Context) XSRFToken(key string, expire int64) string {
|
||||
token, ok := ctx.GetSecureCookie(key, "_xsrf")
|
||||
if !ok {
|
||||
token = string(utils.RandomCreateBytes(32))
|
||||
ctx.SetSecureCookie(key, "_xsrf", token, expire)
|
||||
ctx.SetSecureCookie(key, "_xsrf", token, expire, "", "", true, true)
|
||||
}
|
||||
ctx._xsrfToken = token
|
||||
}
|
||||
|
@ -19,6 +19,8 @@ import (
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/astaxie/beego/pkg/context"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@ -125,8 +127,10 @@ func TestGetUint64(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestAdditionalViewPaths(t *testing.T) {
|
||||
dir1 := "_beeTmp"
|
||||
dir2 := "_beeTmp2"
|
||||
wkdir, err := os.Getwd()
|
||||
assert.Nil(t, err)
|
||||
dir1 := filepath.Join(wkdir, "_beeTmp", "TestAdditionalViewPaths")
|
||||
dir2 := filepath.Join(wkdir, "_beeTmp2", "TestAdditionalViewPaths")
|
||||
defer os.RemoveAll(dir1)
|
||||
defer os.RemoveAll(dir2)
|
||||
|
||||
|
@ -14,10 +14,19 @@
|
||||
|
||||
package beego
|
||||
|
||||
import "github.com/astaxie/beego/pkg/context"
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/astaxie/beego/pkg/context"
|
||||
)
|
||||
|
||||
// FilterChain is different from pure FilterFunc
|
||||
// when you use this, you must invoke next(ctx) inside the FilterFunc which is returned
|
||||
// And all those FilterChain will be invoked before other FilterFunc
|
||||
type FilterChain func(next FilterFunc) FilterFunc
|
||||
|
||||
// FilterFunc defines a filter function which is invoked before the controller handler is executed.
|
||||
type FilterFunc func(*context.Context)
|
||||
type FilterFunc func(ctx *context.Context)
|
||||
|
||||
// FilterRouter defines a filter operation which is invoked before the controller handler is executed.
|
||||
// It can match the URL against a pattern, and execute a filter function
|
||||
@ -30,6 +39,55 @@ type FilterRouter struct {
|
||||
resetParams bool
|
||||
}
|
||||
|
||||
// params is for:
|
||||
// 1. setting the returnOnOutput value (false allows multiple filters to execute)
|
||||
// 2. determining whether or not params need to be reset.
|
||||
func newFilterRouter(pattern string, routerCaseSensitive bool, filter FilterFunc, params ...bool) *FilterRouter {
|
||||
mr := &FilterRouter{
|
||||
tree: NewTree(),
|
||||
pattern: pattern,
|
||||
filterFunc: filter,
|
||||
returnOnOutput: true,
|
||||
}
|
||||
if !routerCaseSensitive {
|
||||
mr.pattern = strings.ToLower(pattern)
|
||||
}
|
||||
|
||||
paramsLen := len(params)
|
||||
if paramsLen > 0 {
|
||||
mr.returnOnOutput = params[0]
|
||||
}
|
||||
if paramsLen > 1 {
|
||||
mr.resetParams = params[1]
|
||||
}
|
||||
mr.tree.AddRouter(pattern, true)
|
||||
return mr
|
||||
}
|
||||
|
||||
// filter will check whether we need to execute the filter logic
|
||||
// return (started, done)
|
||||
func (f *FilterRouter) filter(ctx *context.Context, urlPath string, preFilterParams map[string]string) (bool, bool) {
|
||||
if f.returnOnOutput && ctx.ResponseWriter.Started {
|
||||
return true, true
|
||||
}
|
||||
if f.resetParams {
|
||||
preFilterParams = ctx.Input.Params()
|
||||
}
|
||||
if ok := f.ValidRouter(urlPath, ctx); ok {
|
||||
f.filterFunc(ctx)
|
||||
if f.resetParams {
|
||||
ctx.Input.ResetParams()
|
||||
for k, v := range preFilterParams {
|
||||
ctx.Input.SetParam(k, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
if f.returnOnOutput && ctx.ResponseWriter.Started {
|
||||
return true, true
|
||||
}
|
||||
return false, false
|
||||
}
|
||||
|
||||
// ValidRouter checks if the current request is matched by this filter.
|
||||
// If the request is matched, the values of the URL parameters defined
|
||||
// by the filter pattern are also returned.
|
||||
|
49
pkg/filter_chain_test.go
Normal file
49
pkg/filter_chain_test.go
Normal file
@ -0,0 +1,49 @@
|
||||
// Copyright 2020
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package beego
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/astaxie/beego/pkg/context"
|
||||
)
|
||||
|
||||
func TestControllerRegister_InsertFilterChain(t *testing.T) {
|
||||
|
||||
InsertFilterChain("/*", func(next FilterFunc) FilterFunc {
|
||||
return func(ctx *context.Context) {
|
||||
ctx.Output.Header("filter", "filter-chain")
|
||||
next(ctx)
|
||||
}
|
||||
})
|
||||
|
||||
ns := NewNamespace("/chain")
|
||||
|
||||
ns.Get("/*", func(ctx *context.Context) {
|
||||
ctx.Output.Body([]byte("hello"))
|
||||
})
|
||||
|
||||
|
||||
r, _ := http.NewRequest("GET", "/chain/user", nil)
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
BeeApp.Handlers.ServeHTTP(w, r)
|
||||
|
||||
assert.Equal(t, "filter-chain", w.Header().Get("filter"))
|
||||
}
|
185
pkg/router.go
185
pkg/router.go
@ -134,11 +134,14 @@ type ControllerRegister struct {
|
||||
enableFilter bool
|
||||
filters [FinishRouter + 1][]*FilterRouter
|
||||
pool sync.Pool
|
||||
|
||||
// the filter created by FilterChain
|
||||
chainRoot *FilterRouter
|
||||
}
|
||||
|
||||
// NewControllerRegister returns a new ControllerRegister.
|
||||
func NewControllerRegister() *ControllerRegister {
|
||||
return &ControllerRegister{
|
||||
res := &ControllerRegister{
|
||||
routers: make(map[string]*Tree),
|
||||
policies: make(map[string]*Tree),
|
||||
pool: sync.Pool{
|
||||
@ -147,6 +150,8 @@ func NewControllerRegister() *ControllerRegister {
|
||||
},
|
||||
},
|
||||
}
|
||||
res.chainRoot = newFilterRouter("/*", false, res.serveHttp)
|
||||
return res
|
||||
}
|
||||
|
||||
// Add controller handler and pattern rules to ControllerRegister.
|
||||
@ -489,27 +494,28 @@ func (p *ControllerRegister) AddAutoPrefix(prefix string, c ControllerInterface)
|
||||
// 1. setting the returnOnOutput value (false allows multiple filters to execute)
|
||||
// 2. determining whether or not params need to be reset.
|
||||
func (p *ControllerRegister) InsertFilter(pattern string, pos int, filter FilterFunc, params ...bool) error {
|
||||
mr := &FilterRouter{
|
||||
tree: NewTree(),
|
||||
pattern: pattern,
|
||||
filterFunc: filter,
|
||||
returnOnOutput: true,
|
||||
}
|
||||
if !BConfig.RouterCaseSensitive {
|
||||
mr.pattern = strings.ToLower(pattern)
|
||||
}
|
||||
|
||||
paramsLen := len(params)
|
||||
if paramsLen > 0 {
|
||||
mr.returnOnOutput = params[0]
|
||||
}
|
||||
if paramsLen > 1 {
|
||||
mr.resetParams = params[1]
|
||||
}
|
||||
mr.tree.AddRouter(pattern, true)
|
||||
mr := newFilterRouter(pattern, BConfig.RouterCaseSensitive, filter, params...)
|
||||
return p.insertFilterRouter(pos, mr)
|
||||
}
|
||||
|
||||
// InsertFilterChain is similar to InsertFilter,
|
||||
// but it will using chainRoot.filterFunc as input to build a new filterFunc
|
||||
// for example, assume that chainRoot is funcA
|
||||
// and we add new FilterChain
|
||||
// fc := func(next) {
|
||||
// return func(ctx) {
|
||||
// // do something
|
||||
// next(ctx)
|
||||
// // do something
|
||||
// }
|
||||
// }
|
||||
func (p *ControllerRegister) InsertFilterChain(pattern string, chain FilterChain, params...bool) {
|
||||
root := p.chainRoot
|
||||
filterFunc := chain(root.filterFunc)
|
||||
p.chainRoot = newFilterRouter(pattern, BConfig.RouterCaseSensitive, filterFunc, params...)
|
||||
}
|
||||
|
||||
|
||||
// add Filter into
|
||||
func (p *ControllerRegister) insertFilterRouter(pos int, mr *FilterRouter) (err error) {
|
||||
if pos < BeforeStatic || pos > FinishRouter {
|
||||
@ -668,23 +674,9 @@ func (p *ControllerRegister) getURL(t *Tree, url, controllerName, methodName str
|
||||
func (p *ControllerRegister) execFilter(context *beecontext.Context, urlPath string, pos int) (started bool) {
|
||||
var preFilterParams map[string]string
|
||||
for _, filterR := range p.filters[pos] {
|
||||
if filterR.returnOnOutput && context.ResponseWriter.Started {
|
||||
return true
|
||||
}
|
||||
if filterR.resetParams {
|
||||
preFilterParams = context.Input.Params()
|
||||
}
|
||||
if ok := filterR.ValidRouter(urlPath, context); ok {
|
||||
filterR.filterFunc(context)
|
||||
if filterR.resetParams {
|
||||
context.Input.ResetParams()
|
||||
for k, v := range preFilterParams {
|
||||
context.Input.SetParam(k, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
if filterR.returnOnOutput && context.ResponseWriter.Started {
|
||||
return true
|
||||
b, done := filterR.filter(context, urlPath, preFilterParams)
|
||||
if done {
|
||||
return b
|
||||
}
|
||||
}
|
||||
return false
|
||||
@ -692,7 +684,20 @@ func (p *ControllerRegister) execFilter(context *beecontext.Context, urlPath str
|
||||
|
||||
// Implement http.Handler interface.
|
||||
func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
||||
|
||||
ctx := p.GetContext()
|
||||
|
||||
ctx.Reset(rw, r)
|
||||
defer p.GiveBackContext(ctx)
|
||||
|
||||
var preFilterParams map[string]string
|
||||
p.chainRoot.filter(ctx, p.getUrlPath(ctx), preFilterParams)
|
||||
}
|
||||
|
||||
func (p *ControllerRegister) serveHttp(ctx *beecontext.Context) {
|
||||
startTime := time.Now()
|
||||
r := ctx.Request
|
||||
rw := ctx.ResponseWriter.ResponseWriter
|
||||
var (
|
||||
runRouter reflect.Type
|
||||
findRouter bool
|
||||
@ -701,108 +706,100 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request)
|
||||
routerInfo *ControllerInfo
|
||||
isRunnable bool
|
||||
)
|
||||
context := p.GetContext()
|
||||
|
||||
context.Reset(rw, r)
|
||||
|
||||
defer p.GiveBackContext(context)
|
||||
if BConfig.RecoverFunc != nil {
|
||||
defer BConfig.RecoverFunc(context)
|
||||
defer BConfig.RecoverFunc(ctx)
|
||||
}
|
||||
|
||||
context.Output.EnableGzip = BConfig.EnableGzip
|
||||
ctx.Output.EnableGzip = BConfig.EnableGzip
|
||||
|
||||
if BConfig.RunMode == DEV {
|
||||
context.Output.Header("Server", BConfig.ServerName)
|
||||
ctx.Output.Header("Server", BConfig.ServerName)
|
||||
}
|
||||
|
||||
var urlPath = r.URL.Path
|
||||
|
||||
if !BConfig.RouterCaseSensitive {
|
||||
urlPath = strings.ToLower(urlPath)
|
||||
}
|
||||
urlPath := p.getUrlPath(ctx)
|
||||
|
||||
// filter wrong http method
|
||||
if !HTTPMETHOD[r.Method] {
|
||||
exception("405", context)
|
||||
exception("405", ctx)
|
||||
goto Admin
|
||||
}
|
||||
|
||||
// filter for static file
|
||||
if len(p.filters[BeforeStatic]) > 0 && p.execFilter(context, urlPath, BeforeStatic) {
|
||||
if len(p.filters[BeforeStatic]) > 0 && p.execFilter(ctx, urlPath, BeforeStatic) {
|
||||
goto Admin
|
||||
}
|
||||
|
||||
serverStaticRouter(context)
|
||||
serverStaticRouter(ctx)
|
||||
|
||||
if context.ResponseWriter.Started {
|
||||
if ctx.ResponseWriter.Started {
|
||||
findRouter = true
|
||||
goto Admin
|
||||
}
|
||||
|
||||
if r.Method != http.MethodGet && r.Method != http.MethodHead {
|
||||
if BConfig.CopyRequestBody && !context.Input.IsUpload() {
|
||||
if BConfig.CopyRequestBody && !ctx.Input.IsUpload() {
|
||||
// connection will close if the incoming data are larger (RFC 7231, 6.5.11)
|
||||
if r.ContentLength > BConfig.MaxMemory {
|
||||
logs.Error(errors.New("payload too large"))
|
||||
exception("413", context)
|
||||
exception("413", ctx)
|
||||
goto Admin
|
||||
}
|
||||
context.Input.CopyBody(BConfig.MaxMemory)
|
||||
ctx.Input.CopyBody(BConfig.MaxMemory)
|
||||
}
|
||||
context.Input.ParseFormOrMulitForm(BConfig.MaxMemory)
|
||||
ctx.Input.ParseFormOrMulitForm(BConfig.MaxMemory)
|
||||
}
|
||||
|
||||
// session init
|
||||
if BConfig.WebConfig.Session.SessionOn {
|
||||
var err error
|
||||
context.Input.CruSession, err = GlobalSessions.SessionStart(rw, r)
|
||||
ctx.Input.CruSession, err = GlobalSessions.SessionStart(rw, r)
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
exception("503", context)
|
||||
exception("503", ctx)
|
||||
goto Admin
|
||||
}
|
||||
defer func() {
|
||||
if context.Input.CruSession != nil {
|
||||
context.Input.CruSession.SessionRelease(rw)
|
||||
if ctx.Input.CruSession != nil {
|
||||
ctx.Input.CruSession.SessionRelease(rw)
|
||||
}
|
||||
}()
|
||||
}
|
||||
if len(p.filters[BeforeRouter]) > 0 && p.execFilter(context, urlPath, BeforeRouter) {
|
||||
if len(p.filters[BeforeRouter]) > 0 && p.execFilter(ctx, urlPath, BeforeRouter) {
|
||||
goto Admin
|
||||
}
|
||||
// User can define RunController and RunMethod in filter
|
||||
if context.Input.RunController != nil && context.Input.RunMethod != "" {
|
||||
if ctx.Input.RunController != nil && ctx.Input.RunMethod != "" {
|
||||
findRouter = true
|
||||
runMethod = context.Input.RunMethod
|
||||
runRouter = context.Input.RunController
|
||||
runMethod = ctx.Input.RunMethod
|
||||
runRouter = ctx.Input.RunController
|
||||
} else {
|
||||
routerInfo, findRouter = p.FindRouter(context)
|
||||
routerInfo, findRouter = p.FindRouter(ctx)
|
||||
}
|
||||
|
||||
// if no matches to url, throw a not found exception
|
||||
if !findRouter {
|
||||
exception("404", context)
|
||||
exception("404", ctx)
|
||||
goto Admin
|
||||
}
|
||||
if splat := context.Input.Param(":splat"); splat != "" {
|
||||
if splat := ctx.Input.Param(":splat"); splat != "" {
|
||||
for k, v := range strings.Split(splat, "/") {
|
||||
context.Input.SetParam(strconv.Itoa(k), v)
|
||||
ctx.Input.SetParam(strconv.Itoa(k), v)
|
||||
}
|
||||
}
|
||||
|
||||
if routerInfo != nil {
|
||||
// store router pattern into context
|
||||
context.Input.SetData("RouterPattern", routerInfo.pattern)
|
||||
ctx.Input.SetData("RouterPattern", routerInfo.pattern)
|
||||
}
|
||||
|
||||
// execute middleware filters
|
||||
if len(p.filters[BeforeExec]) > 0 && p.execFilter(context, urlPath, BeforeExec) {
|
||||
if len(p.filters[BeforeExec]) > 0 && p.execFilter(ctx, urlPath, BeforeExec) {
|
||||
goto Admin
|
||||
}
|
||||
|
||||
// check policies
|
||||
if p.execPolicy(context, urlPath) {
|
||||
if p.execPolicy(ctx, urlPath) {
|
||||
goto Admin
|
||||
}
|
||||
|
||||
@ -810,22 +807,22 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request)
|
||||
if routerInfo.routerType == routerTypeRESTFul {
|
||||
if _, ok := routerInfo.methods[r.Method]; ok {
|
||||
isRunnable = true
|
||||
routerInfo.runFunction(context)
|
||||
routerInfo.runFunction(ctx)
|
||||
} else {
|
||||
exception("405", context)
|
||||
exception("405", ctx)
|
||||
goto Admin
|
||||
}
|
||||
} else if routerInfo.routerType == routerTypeHandler {
|
||||
isRunnable = true
|
||||
routerInfo.handler.ServeHTTP(context.ResponseWriter, context.Request)
|
||||
routerInfo.handler.ServeHTTP(ctx.ResponseWriter, ctx.Request)
|
||||
} else {
|
||||
runRouter = routerInfo.controllerType
|
||||
methodParams = routerInfo.methodParams
|
||||
method := r.Method
|
||||
if r.Method == http.MethodPost && context.Input.Query("_method") == http.MethodPut {
|
||||
if r.Method == http.MethodPost && ctx.Input.Query("_method") == http.MethodPut {
|
||||
method = http.MethodPut
|
||||
}
|
||||
if r.Method == http.MethodPost && context.Input.Query("_method") == http.MethodDelete {
|
||||
if r.Method == http.MethodPost && ctx.Input.Query("_method") == http.MethodDelete {
|
||||
method = http.MethodDelete
|
||||
}
|
||||
if m, ok := routerInfo.methods[method]; ok {
|
||||
@ -854,7 +851,7 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request)
|
||||
}
|
||||
|
||||
// call the controller init function
|
||||
execController.Init(context, runRouter.Name(), runMethod, execController)
|
||||
execController.Init(ctx, runRouter.Name(), runMethod, execController)
|
||||
|
||||
// call prepare function
|
||||
execController.Prepare()
|
||||
@ -863,14 +860,14 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request)
|
||||
if BConfig.WebConfig.EnableXSRF {
|
||||
execController.XSRFToken()
|
||||
if r.Method == http.MethodPost || r.Method == http.MethodDelete || r.Method == http.MethodPut ||
|
||||
(r.Method == http.MethodPost && (context.Input.Query("_method") == http.MethodDelete || context.Input.Query("_method") == http.MethodPut)) {
|
||||
(r.Method == http.MethodPost && (ctx.Input.Query("_method") == http.MethodDelete || ctx.Input.Query("_method") == http.MethodPut)) {
|
||||
execController.CheckXSRFCookie()
|
||||
}
|
||||
}
|
||||
|
||||
execController.URLMapping()
|
||||
|
||||
if !context.ResponseWriter.Started {
|
||||
if !ctx.ResponseWriter.Started {
|
||||
// exec main logic
|
||||
switch runMethod {
|
||||
case http.MethodGet:
|
||||
@ -893,18 +890,18 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request)
|
||||
if !execController.HandlerFunc(runMethod) {
|
||||
vc := reflect.ValueOf(execController)
|
||||
method := vc.MethodByName(runMethod)
|
||||
in := param.ConvertParams(methodParams, method.Type(), context)
|
||||
in := param.ConvertParams(methodParams, method.Type(), ctx)
|
||||
out := method.Call(in)
|
||||
|
||||
// For backward compatibility we only handle response if we had incoming methodParams
|
||||
if methodParams != nil {
|
||||
p.handleParamResponse(context, execController, out)
|
||||
p.handleParamResponse(ctx, execController, out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// render template
|
||||
if !context.ResponseWriter.Started && context.Output.Status == 0 {
|
||||
if !ctx.ResponseWriter.Started && ctx.Output.Status == 0 {
|
||||
if BConfig.WebConfig.AutoRender {
|
||||
if err := execController.Render(); err != nil {
|
||||
logs.Error(err)
|
||||
@ -918,26 +915,26 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request)
|
||||
}
|
||||
|
||||
// execute middleware filters
|
||||
if len(p.filters[AfterExec]) > 0 && p.execFilter(context, urlPath, AfterExec) {
|
||||
if len(p.filters[AfterExec]) > 0 && p.execFilter(ctx, urlPath, AfterExec) {
|
||||
goto Admin
|
||||
}
|
||||
|
||||
if len(p.filters[FinishRouter]) > 0 && p.execFilter(context, urlPath, FinishRouter) {
|
||||
if len(p.filters[FinishRouter]) > 0 && p.execFilter(ctx, urlPath, FinishRouter) {
|
||||
goto Admin
|
||||
}
|
||||
|
||||
Admin:
|
||||
// admin module record QPS
|
||||
|
||||
statusCode := context.ResponseWriter.Status
|
||||
statusCode := ctx.ResponseWriter.Status
|
||||
if statusCode == 0 {
|
||||
statusCode = 200
|
||||
}
|
||||
|
||||
LogAccess(context, &startTime, statusCode)
|
||||
LogAccess(ctx, &startTime, statusCode)
|
||||
|
||||
timeDur := time.Since(startTime)
|
||||
context.ResponseWriter.Elapsed = timeDur
|
||||
ctx.ResponseWriter.Elapsed = timeDur
|
||||
if BConfig.Listen.EnableAdmin {
|
||||
pattern := ""
|
||||
if routerInfo != nil {
|
||||
@ -956,7 +953,7 @@ Admin:
|
||||
if BConfig.RunMode == DEV && !BConfig.Log.AccessLogs {
|
||||
match := map[bool]string{true: "match", false: "nomatch"}
|
||||
devInfo := fmt.Sprintf("|%15s|%s %3d %s|%13s|%8s|%s %-7s %s %-3s",
|
||||
context.Input.IP(),
|
||||
ctx.Input.IP(),
|
||||
logs.ColorByStatus(statusCode), statusCode, logs.ResetColor(),
|
||||
timeDur.String(),
|
||||
match[findRouter],
|
||||
@ -969,11 +966,19 @@ Admin:
|
||||
logs.Debug(devInfo)
|
||||
}
|
||||
// Call WriteHeader if status code has been set changed
|
||||
if context.Output.Status != 0 {
|
||||
context.ResponseWriter.WriteHeader(context.Output.Status)
|
||||
if ctx.Output.Status != 0 {
|
||||
ctx.ResponseWriter.WriteHeader(ctx.Output.Status)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *ControllerRegister) getUrlPath(ctx *beecontext.Context) string {
|
||||
urlPath := ctx.Request.URL.Path
|
||||
if !BConfig.RouterCaseSensitive {
|
||||
urlPath = strings.ToLower(urlPath)
|
||||
}
|
||||
return urlPath
|
||||
}
|
||||
|
||||
func (p *ControllerRegister) handleParamResponse(context *beecontext.Context, execController ControllerInterface, results []reflect.Value) {
|
||||
// looping in reverse order for the case when both error and value are returned and error sets the response status code
|
||||
for i := len(results) - 1; i >= 0; i-- {
|
||||
|
@ -16,12 +16,15 @@ package beego
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/astaxie/beego/pkg/testdata"
|
||||
"github.com/elazarl/go-bindata-assetfs"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/elazarl/go-bindata-assetfs"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/astaxie/beego/test"
|
||||
)
|
||||
|
||||
var header = `{{define "header"}}
|
||||
@ -46,7 +49,9 @@ var block = `{{define "block"}}
|
||||
{{end}}`
|
||||
|
||||
func TestTemplate(t *testing.T) {
|
||||
dir := "_beeTmp"
|
||||
wkdir, err := os.Getwd()
|
||||
assert.Nil(t, err)
|
||||
dir := filepath.Join(wkdir, "_beeTmp", "TestTemplate")
|
||||
files := []string{
|
||||
"header.tpl",
|
||||
"index.tpl",
|
||||
@ -56,7 +61,8 @@ func TestTemplate(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for k, name := range files {
|
||||
os.MkdirAll(filepath.Dir(filepath.Join(dir, name)), 0777)
|
||||
dirErr := os.MkdirAll(filepath.Dir(filepath.Join(dir, name)), 0777)
|
||||
assert.Nil(t, dirErr)
|
||||
if f, err := os.Create(filepath.Join(dir, name)); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
@ -107,7 +113,9 @@ var user = `<!DOCTYPE html>
|
||||
`
|
||||
|
||||
func TestRelativeTemplate(t *testing.T) {
|
||||
dir := "_beeTmp"
|
||||
wkdir, err := os.Getwd()
|
||||
assert.Nil(t, err)
|
||||
dir := filepath.Join(wkdir, "_beeTmp")
|
||||
|
||||
//Just add dir to known viewPaths
|
||||
if err := AddViewPath(dir); err != nil {
|
||||
@ -218,7 +226,10 @@ var output = `<!DOCTYPE html>
|
||||
`
|
||||
|
||||
func TestTemplateLayout(t *testing.T) {
|
||||
dir := "_beeTmp"
|
||||
wkdir, err := os.Getwd()
|
||||
assert.Nil(t, err)
|
||||
|
||||
dir := filepath.Join(wkdir, "_beeTmp", "TestTemplateLayout")
|
||||
files := []string{
|
||||
"add.tpl",
|
||||
"layout_blog.tpl",
|
||||
@ -226,17 +237,22 @@ func TestTemplateLayout(t *testing.T) {
|
||||
if err := os.MkdirAll(dir, 0777); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for k, name := range files {
|
||||
os.MkdirAll(filepath.Dir(filepath.Join(dir, name)), 0777)
|
||||
dirErr := os.MkdirAll(filepath.Dir(filepath.Join(dir, name)), 0777)
|
||||
assert.Nil(t, dirErr)
|
||||
if f, err := os.Create(filepath.Join(dir, name)); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
if k == 0 {
|
||||
f.WriteString(add)
|
||||
_, writeErr := f.WriteString(add)
|
||||
assert.Nil(t, writeErr)
|
||||
} else if k == 1 {
|
||||
f.WriteString(layoutBlog)
|
||||
_, writeErr := f.WriteString(layoutBlog)
|
||||
assert.Nil(t, writeErr)
|
||||
}
|
||||
f.Close()
|
||||
clErr := f.Close()
|
||||
assert.Nil(t, clErr)
|
||||
}
|
||||
}
|
||||
if err := AddViewPath(dir); err != nil {
|
||||
@ -247,6 +263,7 @@ func TestTemplateLayout(t *testing.T) {
|
||||
t.Fatalf("should be 2 but got %v", len(beeTemplates))
|
||||
}
|
||||
out := bytes.NewBufferString("")
|
||||
|
||||
if err := beeTemplates["add.tpl"].ExecuteTemplate(out, "add.tpl", map[string]string{"Title": "Hello", "SomeVar": "val"}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -291,7 +308,7 @@ var outputBinData = `<!DOCTYPE html>
|
||||
|
||||
func TestFsBinData(t *testing.T) {
|
||||
SetTemplateFSFunc(func() http.FileSystem {
|
||||
return TestingFileSystem{&assetfs.AssetFS{Asset: testdata.Asset, AssetDir: testdata.AssetDir, AssetInfo: testdata.AssetInfo}}
|
||||
return TestingFileSystem{&assetfs.AssetFS{Asset: test.Asset, AssetDir: test.AssetDir, AssetInfo: test.AssetInfo}}
|
||||
})
|
||||
dir := "views"
|
||||
if err := AddViewPath("views"); err != nil {
|
||||
|
296
pkg/testdata/bindata.go
vendored
296
pkg/testdata/bindata.go
vendored
@ -1,296 +0,0 @@
|
||||
// Code generated by go-bindata.
|
||||
// sources:
|
||||
// views/blocks/block.tpl
|
||||
// views/header.tpl
|
||||
// views/index.tpl
|
||||
// DO NOT EDIT!
|
||||
|
||||
package testdata
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
"github.com/elazarl/go-bindata-assetfs"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func bindataRead(data []byte, name string) ([]byte, error) {
|
||||
gz, err := gzip.NewReader(bytes.NewBuffer(data))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Read %q: %v", name, err)
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
_, err = io.Copy(&buf, gz)
|
||||
clErr := gz.Close()
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Read %q: %v", name, err)
|
||||
}
|
||||
if clErr != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
type asset struct {
|
||||
bytes []byte
|
||||
info os.FileInfo
|
||||
}
|
||||
|
||||
type bindataFileInfo struct {
|
||||
name string
|
||||
size int64
|
||||
mode os.FileMode
|
||||
modTime time.Time
|
||||
}
|
||||
|
||||
func (fi bindataFileInfo) Name() string {
|
||||
return fi.name
|
||||
}
|
||||
func (fi bindataFileInfo) Size() int64 {
|
||||
return fi.size
|
||||
}
|
||||
func (fi bindataFileInfo) Mode() os.FileMode {
|
||||
return fi.mode
|
||||
}
|
||||
func (fi bindataFileInfo) ModTime() time.Time {
|
||||
return fi.modTime
|
||||
}
|
||||
func (fi bindataFileInfo) IsDir() bool {
|
||||
return false
|
||||
}
|
||||
func (fi bindataFileInfo) Sys() interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
var _viewsBlocksBlockTpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xaa\xae\x4e\x49\x4d\xcb\xcc\x4b\x55\x50\x4a\xca\xc9\x4f\xce\x56\xaa\xad\xe5\xb2\xc9\x30\xb4\xf3\x48\xcd\xc9\xc9\xd7\x51\x00\x8b\x15\x2b\xda\xe8\x67\x18\xda\x71\x55\x57\xa7\xe6\xa5\xd4\xd6\x02\x02\x00\x00\xff\xff\xfd\xa1\x7a\xf6\x32\x00\x00\x00")
|
||||
|
||||
func viewsBlocksBlockTplBytes() ([]byte, error) {
|
||||
return bindataRead(
|
||||
_viewsBlocksBlockTpl,
|
||||
"views/blocks/block.tpl",
|
||||
)
|
||||
}
|
||||
|
||||
func viewsBlocksBlockTpl() (*asset, error) {
|
||||
bytes, err := viewsBlocksBlockTplBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "views/blocks/block.tpl", size: 50, mode: os.FileMode(436), modTime: time.Unix(1541431067, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _viewsHeaderTpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xaa\xae\x4e\x49\x4d\xcb\xcc\x4b\x55\x50\xca\x48\x4d\x4c\x49\x2d\x52\xaa\xad\xe5\xb2\xc9\x30\xb4\xf3\x48\xcd\xc9\xc9\xd7\x51\x48\x2c\x2e\x49\xac\xc8\x4c\x55\xb4\xd1\xcf\x30\xb4\xe3\xaa\xae\x4e\xcd\x4b\xa9\xad\x05\x04\x00\x00\xff\xff\xe4\x12\x47\x01\x34\x00\x00\x00")
|
||||
|
||||
func viewsHeaderTplBytes() ([]byte, error) {
|
||||
return bindataRead(
|
||||
_viewsHeaderTpl,
|
||||
"views/header.tpl",
|
||||
)
|
||||
}
|
||||
|
||||
func viewsHeaderTpl() (*asset, error) {
|
||||
bytes, err := viewsHeaderTplBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "views/header.tpl", size: 52, mode: os.FileMode(436), modTime: time.Unix(1541431067, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _viewsIndexTpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x64\x8f\xbd\x8a\xc3\x30\x10\x84\x6b\xeb\x29\xe6\xfc\x00\x16\xb8\x3c\x16\x35\x77\xa9\x13\x88\x09\xa4\xf4\xcf\x12\x99\x48\x48\xd8\x82\x10\x84\xde\x3d\xc8\x8a\x8b\x90\x6a\xa4\xd9\x6f\xd8\x59\xfa\xf9\x3f\xfe\x75\xd7\xd3\x01\x3a\x58\xa3\x04\x15\x01\x48\x73\x3f\xe5\x07\x40\x61\x0e\x86\xd5\xc0\x7c\x73\x78\xb0\x19\x9d\x65\x04\xb6\xde\xf4\x81\x49\x96\x69\x8e\xc8\x3d\x43\x83\x9b\x9e\x4a\x88\x2a\xc6\x9d\x43\x3d\x18\x37\xde\xeb\x94\x3e\xdd\x1c\xe1\xe5\xcb\xde\xe0\x55\x6e\xd2\x04\x6f\x32\x20\x2a\xd2\xad\x8a\x11\x4d\x97\x57\x22\x25\x92\xba\x55\xa2\x22\xaf\xd0\xe9\x79\xc5\xbc\xe2\xec\x2c\x5f\xfa\xe5\x17\x99\x7b\x7f\x36\xd2\x97\x8a\xa5\x19\xc9\x72\xe7\x2b\x00\x00\xff\xff\xb2\x39\xca\x9f\xff\x00\x00\x00")
|
||||
|
||||
func viewsIndexTplBytes() ([]byte, error) {
|
||||
return bindataRead(
|
||||
_viewsIndexTpl,
|
||||
"views/index.tpl",
|
||||
)
|
||||
}
|
||||
|
||||
func viewsIndexTpl() (*asset, error) {
|
||||
bytes, err := viewsIndexTplBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "views/index.tpl", size: 255, mode: os.FileMode(436), modTime: time.Unix(1541434906, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
// Asset loads and returns the asset for the given name.
|
||||
// It returns an error if the asset could not be found or
|
||||
// could not be loaded.
|
||||
func Asset(name string) ([]byte, error) {
|
||||
cannonicalName := strings.Replace(name, "\\", "/", -1)
|
||||
if f, ok := _bindata[cannonicalName]; ok {
|
||||
a, err := f()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err)
|
||||
}
|
||||
return a.bytes, nil
|
||||
}
|
||||
return nil, fmt.Errorf("Asset %s not found", name)
|
||||
}
|
||||
|
||||
// MustAsset is like Asset but panics when Asset would return an error.
|
||||
// It simplifies safe initialization of global variables.
|
||||
func MustAsset(name string) []byte {
|
||||
a, err := Asset(name)
|
||||
if err != nil {
|
||||
panic("asset: Asset(" + name + "): " + err.Error())
|
||||
}
|
||||
|
||||
return a
|
||||
}
|
||||
|
||||
// AssetInfo loads and returns the asset info for the given name.
|
||||
// It returns an error if the asset could not be found or
|
||||
// could not be loaded.
|
||||
func AssetInfo(name string) (os.FileInfo, error) {
|
||||
cannonicalName := strings.Replace(name, "\\", "/", -1)
|
||||
if f, ok := _bindata[cannonicalName]; ok {
|
||||
a, err := f()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err)
|
||||
}
|
||||
return a.info, nil
|
||||
}
|
||||
return nil, fmt.Errorf("AssetInfo %s not found", name)
|
||||
}
|
||||
|
||||
// AssetNames returns the names of the assets.
|
||||
func AssetNames() []string {
|
||||
names := make([]string, 0, len(_bindata))
|
||||
for name := range _bindata {
|
||||
names = append(names, name)
|
||||
}
|
||||
return names
|
||||
}
|
||||
|
||||
// _bindata is a table, holding each asset generator, mapped to its name.
|
||||
var _bindata = map[string]func() (*asset, error){
|
||||
"views/blocks/block.tpl": viewsBlocksBlockTpl,
|
||||
"views/header.tpl": viewsHeaderTpl,
|
||||
"views/index.tpl": viewsIndexTpl,
|
||||
}
|
||||
|
||||
// AssetDir returns the file names below a certain
|
||||
// directory embedded in the file by go-bindata.
|
||||
// For example if you run go-bindata on data/... and data contains the
|
||||
// following hierarchy:
|
||||
// data/
|
||||
// foo.txt
|
||||
// img/
|
||||
// a.png
|
||||
// b.png
|
||||
// then AssetDir("data") would return []string{"foo.txt", "img"}
|
||||
// AssetDir("data/img") would return []string{"a.png", "b.png"}
|
||||
// AssetDir("foo.txt") and AssetDir("notexist") would return an error
|
||||
// AssetDir("") will return []string{"data"}.
|
||||
func AssetDir(name string) ([]string, error) {
|
||||
node := _bintree
|
||||
if len(name) != 0 {
|
||||
cannonicalName := strings.Replace(name, "\\", "/", -1)
|
||||
pathList := strings.Split(cannonicalName, "/")
|
||||
for _, p := range pathList {
|
||||
node = node.Children[p]
|
||||
if node == nil {
|
||||
return nil, fmt.Errorf("Asset %s not found", name)
|
||||
}
|
||||
}
|
||||
}
|
||||
if node.Func != nil {
|
||||
return nil, fmt.Errorf("Asset %s not found", name)
|
||||
}
|
||||
rv := make([]string, 0, len(node.Children))
|
||||
for childName := range node.Children {
|
||||
rv = append(rv, childName)
|
||||
}
|
||||
return rv, nil
|
||||
}
|
||||
|
||||
type bintree struct {
|
||||
Func func() (*asset, error)
|
||||
Children map[string]*bintree
|
||||
}
|
||||
|
||||
var _bintree = &bintree{nil, map[string]*bintree{
|
||||
"views": &bintree{nil, map[string]*bintree{
|
||||
"blocks": &bintree{nil, map[string]*bintree{
|
||||
"block.tpl": &bintree{viewsBlocksBlockTpl, map[string]*bintree{}},
|
||||
}},
|
||||
"header.tpl": &bintree{viewsHeaderTpl, map[string]*bintree{}},
|
||||
"index.tpl": &bintree{viewsIndexTpl, map[string]*bintree{}},
|
||||
}},
|
||||
}}
|
||||
|
||||
// RestoreAsset restores an asset under the given directory
|
||||
func RestoreAsset(dir, name string) error {
|
||||
data, err := Asset(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
info, err := AssetInfo(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RestoreAssets restores an asset under the given directory recursively
|
||||
func RestoreAssets(dir, name string) error {
|
||||
children, err := AssetDir(name)
|
||||
// File
|
||||
if err != nil {
|
||||
return RestoreAsset(dir, name)
|
||||
}
|
||||
// Dir
|
||||
for _, child := range children {
|
||||
err = RestoreAssets(dir, filepath.Join(name, child))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func _filePath(dir, name string) string {
|
||||
cannonicalName := strings.Replace(name, "\\", "/", -1)
|
||||
return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
|
||||
}
|
||||
|
||||
func assetFS() *assetfs.AssetFS {
|
||||
assetInfo := func(path string) (os.FileInfo, error) {
|
||||
return os.Stat(path)
|
||||
}
|
||||
for k := range _bintree.Children {
|
||||
return &assetfs.AssetFS{Asset: Asset, AssetDir: AssetDir, AssetInfo: assetInfo, Prefix: k}
|
||||
}
|
||||
panic("unreachable")
|
||||
}
|
16
pkg/web/doc.go
Normal file
16
pkg/web/doc.go
Normal file
@ -0,0 +1,16 @@
|
||||
// Copyright 2020 beego
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// we will move all web related codes here
|
||||
package web
|
58
pkg/web/filter/opentracing/filter.go
Normal file
58
pkg/web/filter/opentracing/filter.go
Normal file
@ -0,0 +1,58 @@
|
||||
// Copyright 2020 beego
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package opentracing
|
||||
|
||||
import (
|
||||
"github.com/opentracing/opentracing-go"
|
||||
|
||||
beego "github.com/astaxie/beego/pkg"
|
||||
"github.com/astaxie/beego/pkg/context"
|
||||
)
|
||||
|
||||
// FilterChainBuilder provides an extension point that we can support more configurations if necessary
|
||||
type FilterChainBuilder struct {
|
||||
// CustomSpanFunc makes users to custom the span.
|
||||
CustomSpanFunc func(span opentracing.Span, ctx *context.Context)
|
||||
}
|
||||
|
||||
|
||||
func (builder *FilterChainBuilder) FilterChain(next beego.FilterFunc) beego.FilterFunc {
|
||||
return func(ctx *context.Context) {
|
||||
span := opentracing.SpanFromContext(ctx.Request.Context())
|
||||
spanCtx := ctx.Request.Context()
|
||||
if span == nil {
|
||||
operationName := ctx.Input.URL()
|
||||
// it means that there is not any span, so we create a span as the root span.
|
||||
// TODO, if we support multiple servers, this need to be changed
|
||||
route, found := beego.BeeApp.Handlers.FindRouter(ctx)
|
||||
if found {
|
||||
operationName = route.GetPattern()
|
||||
}
|
||||
span, spanCtx = opentracing.StartSpanFromContext(spanCtx, operationName)
|
||||
newReq := ctx.Request.Clone(spanCtx)
|
||||
ctx.Reset(ctx.ResponseWriter.ResponseWriter, newReq)
|
||||
}
|
||||
|
||||
defer span.Finish()
|
||||
next(ctx)
|
||||
// if you think we need to do more things, feel free to create an issue to tell us
|
||||
span.SetTag("status", ctx.Output.Status)
|
||||
span.SetTag("method", ctx.Input.Method())
|
||||
span.SetTag("route", ctx.Input.GetData("RouterPattern"))
|
||||
if builder.CustomSpanFunc != nil {
|
||||
builder.CustomSpanFunc(span, ctx)
|
||||
}
|
||||
}
|
||||
}
|
47
pkg/web/filter/opentracing/filter_test.go
Normal file
47
pkg/web/filter/opentracing/filter_test.go
Normal file
@ -0,0 +1,47 @@
|
||||
// Copyright 2020 beego
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package opentracing
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/opentracing/opentracing-go"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/astaxie/beego/pkg/context"
|
||||
)
|
||||
|
||||
func TestFilterChainBuilder_FilterChain(t *testing.T) {
|
||||
builder := &FilterChainBuilder{
|
||||
CustomSpanFunc: func(span opentracing.Span, ctx *context.Context) {
|
||||
span.SetTag("aa", "bbb")
|
||||
},
|
||||
}
|
||||
|
||||
ctx := context.NewContext()
|
||||
r, _ := http.NewRequest("GET", "/prometheus/user", nil)
|
||||
w := httptest.NewRecorder()
|
||||
ctx.Reset(w, r)
|
||||
ctx.Input.SetData("RouterPattern", "my-route")
|
||||
|
||||
filterFunc := builder.FilterChain(func(ctx *context.Context) {
|
||||
ctx.Input.SetData("opentracing", true)
|
||||
})
|
||||
|
||||
filterFunc(ctx)
|
||||
assert.True(t, ctx.Input.GetData("opentracing").(bool))
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2020 astaxie
|
||||
// Copyright 2020 beego
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@ -12,22 +12,27 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package metric
|
||||
package prometheus
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
|
||||
"github.com/astaxie/beego/pkg"
|
||||
"github.com/astaxie/beego/pkg/logs"
|
||||
beego "github.com/astaxie/beego/pkg"
|
||||
"github.com/astaxie/beego/pkg/context"
|
||||
)
|
||||
|
||||
func PrometheusMiddleWare(next http.Handler) http.Handler {
|
||||
// FilterChainBuilder is an extension point,
|
||||
// when we want to support some configuration,
|
||||
// please use this structure
|
||||
type FilterChainBuilder struct {
|
||||
}
|
||||
|
||||
// FilterChain returns a FilterFunc. The filter will records some metrics
|
||||
func (builder *FilterChainBuilder) FilterChain(next beego.FilterFunc) beego.FilterFunc {
|
||||
summaryVec := prometheus.NewSummaryVec(prometheus.SummaryOpts{
|
||||
Name: "beego",
|
||||
Subsystem: "http_request",
|
||||
@ -43,12 +48,12 @@ func PrometheusMiddleWare(next http.Handler) http.Handler {
|
||||
|
||||
registerBuildInfo()
|
||||
|
||||
return http.HandlerFunc(func(writer http.ResponseWriter, q *http.Request) {
|
||||
start := time.Now()
|
||||
next.ServeHTTP(writer, q)
|
||||
end := time.Now()
|
||||
go report(end.Sub(start), writer, q, summaryVec)
|
||||
})
|
||||
return func(ctx *context.Context) {
|
||||
startTime := time.Now()
|
||||
next(ctx)
|
||||
endTime := time.Now()
|
||||
go report(endTime.Sub(startTime), ctx, summaryVec)
|
||||
}
|
||||
}
|
||||
|
||||
func registerBuildInfo() {
|
||||
@ -73,27 +78,9 @@ func registerBuildInfo() {
|
||||
buildInfo.WithLabelValues().Set(1)
|
||||
}
|
||||
|
||||
func report(dur time.Duration, writer http.ResponseWriter, q *http.Request, vec *prometheus.SummaryVec) {
|
||||
ctrl := beego.BeeApp.Handlers
|
||||
ctx := ctrl.GetContext()
|
||||
ctx.Reset(writer, q)
|
||||
defer ctrl.GiveBackContext(ctx)
|
||||
|
||||
// We cannot read the status code from q.Response.StatusCode
|
||||
// since the http server does not set q.Response. So q.Response is nil
|
||||
// Thus, we use reflection to read the status from writer whose concrete type is http.response
|
||||
responseVal := reflect.ValueOf(writer).Elem()
|
||||
field := responseVal.FieldByName("status")
|
||||
status := -1
|
||||
if field.IsValid() && field.Kind() == reflect.Int {
|
||||
status = int(field.Int())
|
||||
}
|
||||
ptn := "UNKNOWN"
|
||||
if rt, found := ctrl.FindRouter(ctx); found {
|
||||
ptn = rt.GetPattern()
|
||||
} else {
|
||||
logs.Warn("we can not find the router info for this request, so request will be recorded as UNKNOWN: " + q.URL.String())
|
||||
}
|
||||
func report(dur time.Duration, ctx *context.Context, vec *prometheus.SummaryVec) {
|
||||
status := ctx.Output.Status
|
||||
ptn := ctx.Input.GetData("RouterPattern").(string)
|
||||
ms := dur / time.Millisecond
|
||||
vec.WithLabelValues(ptn, q.Method, strconv.Itoa(status), strconv.Itoa(int(ms))).Observe(float64(ms))
|
||||
vec.WithLabelValues(ptn, ctx.Input.Method(), strconv.Itoa(status), strconv.Itoa(int(ms))).Observe(float64(ms))
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2020 astaxie
|
||||
// Copyright 2020 beego
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@ -12,31 +12,29 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package metric
|
||||
package prometheus
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/astaxie/beego/pkg/context"
|
||||
)
|
||||
|
||||
func TestPrometheusMiddleWare(t *testing.T) {
|
||||
middleware := PrometheusMiddleWare(http.HandlerFunc(func(http.ResponseWriter, *http.Request) {}))
|
||||
writer := &context.Response{}
|
||||
request := &http.Request{
|
||||
URL: &url.URL{
|
||||
Host: "localhost",
|
||||
RawPath: "/a/b/c",
|
||||
},
|
||||
Method: "POST",
|
||||
}
|
||||
vec := prometheus.NewSummaryVec(prometheus.SummaryOpts{}, []string{"pattern", "method", "status", "duration"})
|
||||
func TestFilterChain(t *testing.T) {
|
||||
filter := (&FilterChainBuilder{}).FilterChain(func(ctx *context.Context) {
|
||||
// do nothing
|
||||
ctx.Input.SetData("invocation", true)
|
||||
})
|
||||
|
||||
report(time.Second, writer, request, vec)
|
||||
middleware.ServeHTTP(writer, request)
|
||||
ctx := context.NewContext()
|
||||
r, _ := http.NewRequest("GET", "/prometheus/user", nil)
|
||||
w := httptest.NewRecorder()
|
||||
ctx.Reset(w, r)
|
||||
ctx.Input.SetData("RouterPattern", "my-route")
|
||||
filter(ctx)
|
||||
assert.True(t, ctx.Input.GetData("invocation").(bool))
|
||||
}
|
@ -21,9 +21,11 @@ import (
|
||||
)
|
||||
|
||||
// PolicyFunc defines a policy function which is invoked before the controller handler is executed.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
type PolicyFunc func(*context.Context)
|
||||
|
||||
// FindPolicy Find Router info for URL
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (p *ControllerRegister) FindPolicy(cont *context.Context) []PolicyFunc {
|
||||
var urlPath = cont.Input.URL()
|
||||
if !BConfig.RouterCaseSensitive {
|
||||
@ -72,6 +74,7 @@ func (p *ControllerRegister) addToPolicy(method, pattern string, r ...PolicyFunc
|
||||
}
|
||||
|
||||
// Policy Register new policy in beego
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func Policy(pattern, method string, policy ...PolicyFunc) {
|
||||
BeeApp.Handlers.addToPolicy(method, pattern, policy...)
|
||||
}
|
||||
|
29
router.go
29
router.go
@ -51,6 +51,7 @@ const (
|
||||
|
||||
var (
|
||||
// HTTPMETHOD list the supported http methods.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
HTTPMETHOD = map[string]bool{
|
||||
"GET": true,
|
||||
"POST": true,
|
||||
@ -80,10 +81,12 @@ var (
|
||||
|
||||
urlPlaceholder = "{{placeholder}}"
|
||||
// DefaultAccessLogFilter will skip the accesslog if return true
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
DefaultAccessLogFilter FilterHandler = &logFilter{}
|
||||
)
|
||||
|
||||
// FilterHandler is an interface for
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
type FilterHandler interface {
|
||||
Filter(*beecontext.Context) bool
|
||||
}
|
||||
@ -92,6 +95,7 @@ type FilterHandler interface {
|
||||
type logFilter struct {
|
||||
}
|
||||
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (l *logFilter) Filter(ctx *beecontext.Context) bool {
|
||||
requestPath := path.Clean(ctx.Request.URL.Path)
|
||||
if requestPath == "/favicon.ico" || requestPath == "/robots.txt" {
|
||||
@ -106,6 +110,7 @@ func (l *logFilter) Filter(ctx *beecontext.Context) bool {
|
||||
}
|
||||
|
||||
// ExceptMethodAppend to append a slice's value into "exceptMethod", for controller's methods shouldn't reflect to AutoRouter
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func ExceptMethodAppend(action string) {
|
||||
exceptMethod = append(exceptMethod, action)
|
||||
}
|
||||
@ -122,11 +127,13 @@ type ControllerInfo struct {
|
||||
methodParams []*param.MethodParam
|
||||
}
|
||||
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (c *ControllerInfo) GetPattern() string {
|
||||
return c.pattern
|
||||
}
|
||||
|
||||
// ControllerRegister containers registered router rules, controller handlers and filters.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
type ControllerRegister struct {
|
||||
routers map[string]*Tree
|
||||
enablePolicy bool
|
||||
@ -137,6 +144,7 @@ type ControllerRegister struct {
|
||||
}
|
||||
|
||||
// NewControllerRegister returns a new ControllerRegister.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func NewControllerRegister() *ControllerRegister {
|
||||
return &ControllerRegister{
|
||||
routers: make(map[string]*Tree),
|
||||
@ -159,6 +167,7 @@ func NewControllerRegister() *ControllerRegister {
|
||||
// Add("/api/delete",&RestController{},"delete:DeleteFood")
|
||||
// Add("/api",&RestController{},"get,post:ApiFunc"
|
||||
// Add("/simple",&SimpleController{},"get:GetFunc;post:PostFunc")
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (p *ControllerRegister) Add(pattern string, c ControllerInterface, mappingMethods ...string) {
|
||||
p.addWithMethodParams(pattern, c, nil, mappingMethods...)
|
||||
}
|
||||
@ -251,6 +260,7 @@ func (p *ControllerRegister) addToRouter(method, pattern string, r *ControllerIn
|
||||
|
||||
// Include only when the Runmode is dev will generate router file in the router/auto.go from the controller
|
||||
// Include(&BankAccount{}, &OrderController{},&RefundController{},&ReceiptController{})
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (p *ControllerRegister) Include(cList ...ControllerInterface) {
|
||||
if BConfig.RunMode == DEV {
|
||||
skip := make(map[string]bool, 10)
|
||||
@ -313,11 +323,13 @@ func (p *ControllerRegister) Include(cList ...ControllerInterface) {
|
||||
// ctx := p.GetContext()
|
||||
// ctx.Reset(w, q)
|
||||
// defer p.GiveBackContext(ctx)
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (p *ControllerRegister) GetContext() *beecontext.Context {
|
||||
return p.pool.Get().(*beecontext.Context)
|
||||
}
|
||||
|
||||
// GiveBackContext put the ctx into pool so that it could be reuse
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (p *ControllerRegister) GiveBackContext(ctx *beecontext.Context) {
|
||||
// clear input cached data
|
||||
ctx.Input.Clear()
|
||||
@ -331,6 +343,7 @@ func (p *ControllerRegister) GiveBackContext(ctx *beecontext.Context) {
|
||||
// Get("/", func(ctx *context.Context){
|
||||
// ctx.Output.Body("hello world")
|
||||
// })
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (p *ControllerRegister) Get(pattern string, f FilterFunc) {
|
||||
p.AddMethod("get", pattern, f)
|
||||
}
|
||||
@ -340,6 +353,7 @@ func (p *ControllerRegister) Get(pattern string, f FilterFunc) {
|
||||
// Post("/api", func(ctx *context.Context){
|
||||
// ctx.Output.Body("hello world")
|
||||
// })
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (p *ControllerRegister) Post(pattern string, f FilterFunc) {
|
||||
p.AddMethod("post", pattern, f)
|
||||
}
|
||||
@ -349,6 +363,7 @@ func (p *ControllerRegister) Post(pattern string, f FilterFunc) {
|
||||
// Put("/api/:id", func(ctx *context.Context){
|
||||
// ctx.Output.Body("hello world")
|
||||
// })
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (p *ControllerRegister) Put(pattern string, f FilterFunc) {
|
||||
p.AddMethod("put", pattern, f)
|
||||
}
|
||||
@ -358,6 +373,7 @@ func (p *ControllerRegister) Put(pattern string, f FilterFunc) {
|
||||
// Delete("/api/:id", func(ctx *context.Context){
|
||||
// ctx.Output.Body("hello world")
|
||||
// })
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (p *ControllerRegister) Delete(pattern string, f FilterFunc) {
|
||||
p.AddMethod("delete", pattern, f)
|
||||
}
|
||||
@ -367,6 +383,7 @@ func (p *ControllerRegister) Delete(pattern string, f FilterFunc) {
|
||||
// Head("/api/:id", func(ctx *context.Context){
|
||||
// ctx.Output.Body("hello world")
|
||||
// })
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (p *ControllerRegister) Head(pattern string, f FilterFunc) {
|
||||
p.AddMethod("head", pattern, f)
|
||||
}
|
||||
@ -376,6 +393,7 @@ func (p *ControllerRegister) Head(pattern string, f FilterFunc) {
|
||||
// Patch("/api/:id", func(ctx *context.Context){
|
||||
// ctx.Output.Body("hello world")
|
||||
// })
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (p *ControllerRegister) Patch(pattern string, f FilterFunc) {
|
||||
p.AddMethod("patch", pattern, f)
|
||||
}
|
||||
@ -385,6 +403,7 @@ func (p *ControllerRegister) Patch(pattern string, f FilterFunc) {
|
||||
// Options("/api/:id", func(ctx *context.Context){
|
||||
// ctx.Output.Body("hello world")
|
||||
// })
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (p *ControllerRegister) Options(pattern string, f FilterFunc) {
|
||||
p.AddMethod("options", pattern, f)
|
||||
}
|
||||
@ -394,6 +413,7 @@ func (p *ControllerRegister) Options(pattern string, f FilterFunc) {
|
||||
// Any("/api/:id", func(ctx *context.Context){
|
||||
// ctx.Output.Body("hello world")
|
||||
// })
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (p *ControllerRegister) Any(pattern string, f FilterFunc) {
|
||||
p.AddMethod("*", pattern, f)
|
||||
}
|
||||
@ -403,6 +423,7 @@ func (p *ControllerRegister) Any(pattern string, f FilterFunc) {
|
||||
// AddMethod("get","/api/:id", func(ctx *context.Context){
|
||||
// ctx.Output.Body("hello world")
|
||||
// })
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (p *ControllerRegister) AddMethod(method, pattern string, f FilterFunc) {
|
||||
method = strings.ToUpper(method)
|
||||
if method != "*" && !HTTPMETHOD[method] {
|
||||
@ -433,6 +454,7 @@ func (p *ControllerRegister) AddMethod(method, pattern string, f FilterFunc) {
|
||||
}
|
||||
|
||||
// Handler add user defined Handler
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (p *ControllerRegister) Handler(pattern string, h http.Handler, options ...interface{}) {
|
||||
route := &ControllerInfo{}
|
||||
route.pattern = pattern
|
||||
@ -453,6 +475,7 @@ func (p *ControllerRegister) Handler(pattern string, h http.Handler, options ...
|
||||
// MainController has method List and Page.
|
||||
// visit the url /main/list to execute List function
|
||||
// /main/page to execute Page function.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (p *ControllerRegister) AddAuto(c ControllerInterface) {
|
||||
p.AddAutoPrefix("/", c)
|
||||
}
|
||||
@ -462,6 +485,7 @@ func (p *ControllerRegister) AddAuto(c ControllerInterface) {
|
||||
// MainController has method List and Page.
|
||||
// visit the url /admin/main/list to execute List function
|
||||
// /admin/main/page to execute Page function.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (p *ControllerRegister) AddAutoPrefix(prefix string, c ControllerInterface) {
|
||||
reflectVal := reflect.ValueOf(c)
|
||||
rt := reflectVal.Type()
|
||||
@ -492,6 +516,7 @@ func (p *ControllerRegister) AddAutoPrefix(prefix string, c ControllerInterface)
|
||||
// params is for:
|
||||
// 1. setting the returnOnOutput value (false allows multiple filters to execute)
|
||||
// 2. determining whether or not params need to be reset.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (p *ControllerRegister) InsertFilter(pattern string, pos int, filter FilterFunc, params ...bool) error {
|
||||
mr := &FilterRouter{
|
||||
tree: NewTree(),
|
||||
@ -526,6 +551,7 @@ func (p *ControllerRegister) insertFilterRouter(pos int, mr *FilterRouter) (err
|
||||
|
||||
// URLFor does another controller handler in this request function.
|
||||
// it can access any controller method.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (p *ControllerRegister) URLFor(endpoint string, values ...interface{}) string {
|
||||
paths := strings.Split(endpoint, ".")
|
||||
if len(paths) <= 1 {
|
||||
@ -695,6 +721,7 @@ func (p *ControllerRegister) execFilter(context *beecontext.Context, urlPath str
|
||||
}
|
||||
|
||||
// Implement http.Handler interface.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
||||
startTime := time.Now()
|
||||
var (
|
||||
@ -993,6 +1020,7 @@ func (p *ControllerRegister) handleParamResponse(context *beecontext.Context, ex
|
||||
}
|
||||
|
||||
// FindRouter Find Router info for URL
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (p *ControllerRegister) FindRouter(context *beecontext.Context) (routerInfo *ControllerInfo, isFind bool) {
|
||||
var urlPath = context.Input.URL()
|
||||
if !BConfig.RouterCaseSensitive {
|
||||
@ -1020,6 +1048,7 @@ func toURL(params map[string]string) string {
|
||||
}
|
||||
|
||||
// LogAccess logging info HTTP Access
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func LogAccess(ctx *beecontext.Context, startTime *time.Time, statusCode int) {
|
||||
// Skip logging if AccessLogs config is false
|
||||
if !BConfig.Log.AccessLogs {
|
||||
|
11
template.go
11
template.go
@ -47,6 +47,7 @@ var (
|
||||
// ExecuteTemplate applies the template with name to the specified data object,
|
||||
// writing the output to wr.
|
||||
// A template will be executed safely in parallel.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func ExecuteTemplate(wr io.Writer, name string, data interface{}) error {
|
||||
return ExecuteViewPathTemplate(wr, name, BConfig.WebConfig.ViewsPath, data)
|
||||
}
|
||||
@ -54,6 +55,7 @@ func ExecuteTemplate(wr io.Writer, name string, data interface{}) error {
|
||||
// ExecuteViewPathTemplate applies the template with name and from specific viewPath to the specified data object,
|
||||
// writing the output to wr.
|
||||
// A template will be executed safely in parallel.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func ExecuteViewPathTemplate(wr io.Writer, name string, viewPath string, data interface{}) error {
|
||||
if BConfig.RunMode == DEV {
|
||||
templatesLock.RLock()
|
||||
@ -143,6 +145,7 @@ func (tf *templateFile) visit(paths string, f os.FileInfo, err error) error {
|
||||
}
|
||||
|
||||
// HasTemplateExt return this path contains supported template extension of beego or not.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func HasTemplateExt(paths string) bool {
|
||||
for _, v := range beeTemplateExt {
|
||||
if strings.HasSuffix(paths, "."+v) {
|
||||
@ -153,6 +156,7 @@ func HasTemplateExt(paths string) bool {
|
||||
}
|
||||
|
||||
// AddTemplateExt add new extension for template.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func AddTemplateExt(ext string) {
|
||||
for _, v := range beeTemplateExt {
|
||||
if v == ext {
|
||||
@ -165,6 +169,7 @@ func AddTemplateExt(ext string) {
|
||||
// AddViewPath adds a new path to the supported view paths.
|
||||
//Can later be used by setting a controller ViewPath to this folder
|
||||
//will panic if called after beego.Run()
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func AddViewPath(viewPath string) error {
|
||||
if beeViewPathTemplateLocked {
|
||||
if _, exist := beeViewPathTemplates[viewPath]; exist {
|
||||
@ -182,6 +187,7 @@ func lockViewPaths() {
|
||||
|
||||
// BuildTemplate will build all template files in a directory.
|
||||
// it makes beego can render any template file in view directory.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func BuildTemplate(dir string, files ...string) error {
|
||||
var err error
|
||||
fs := beeTemplateFS()
|
||||
@ -363,11 +369,13 @@ func defaultFSFunc() http.FileSystem {
|
||||
}
|
||||
|
||||
// SetTemplateFSFunc set default filesystem function
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func SetTemplateFSFunc(fnt templateFSFunc) {
|
||||
beeTemplateFS = fnt
|
||||
}
|
||||
|
||||
// SetViewsPath sets view directory path in beego application.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func SetViewsPath(path string) *App {
|
||||
BConfig.WebConfig.ViewsPath = path
|
||||
return BeeApp
|
||||
@ -375,6 +383,7 @@ func SetViewsPath(path string) *App {
|
||||
|
||||
// SetStaticPath sets static directory path and proper url pattern in beego application.
|
||||
// if beego.SetStaticPath("static","public"), visit /static/* to load static file in folder "public".
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func SetStaticPath(url string, path string) *App {
|
||||
if !strings.HasPrefix(url, "/") {
|
||||
url = "/" + url
|
||||
@ -387,6 +396,7 @@ func SetStaticPath(url string, path string) *App {
|
||||
}
|
||||
|
||||
// DelStaticPath removes the static folder setting in this url pattern in beego application.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func DelStaticPath(url string) *App {
|
||||
if !strings.HasPrefix(url, "/") {
|
||||
url = "/" + url
|
||||
@ -399,6 +409,7 @@ func DelStaticPath(url string) *App {
|
||||
}
|
||||
|
||||
// AddTemplateEngine add a new templatePreProcessor which support extension
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func AddTemplateEngine(extension string, fn templatePreProcessor) *App {
|
||||
AddTemplateExt(extension)
|
||||
beeTemplateEngines[extension] = fn
|
||||
|
@ -16,7 +16,7 @@ package beego
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/astaxie/beego/testdata"
|
||||
"github.com/astaxie/beego/test"
|
||||
"github.com/elazarl/go-bindata-assetfs"
|
||||
"net/http"
|
||||
"os"
|
||||
@ -291,7 +291,7 @@ var outputBinData = `<!DOCTYPE html>
|
||||
|
||||
func TestFsBinData(t *testing.T) {
|
||||
SetTemplateFSFunc(func() http.FileSystem {
|
||||
return TestingFileSystem{&assetfs.AssetFS{Asset: testdata.Asset, AssetDir: testdata.AssetDir, AssetInfo: testdata.AssetInfo}}
|
||||
return TestingFileSystem{&assetfs.AssetFS{Asset: test.Asset, AssetDir: test.AssetDir, AssetInfo: test.AssetInfo}}
|
||||
})
|
||||
dir := "views"
|
||||
if err := AddViewPath("views"); err != nil {
|
||||
|
@ -35,6 +35,7 @@ const (
|
||||
)
|
||||
|
||||
// Substr returns the substr from start to length.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func Substr(s string, start, length int) string {
|
||||
bt := []rune(s)
|
||||
if start < 0 {
|
||||
@ -53,6 +54,7 @@ func Substr(s string, start, length int) string {
|
||||
}
|
||||
|
||||
// HTML2str returns escaping text convert from html.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func HTML2str(html string) string {
|
||||
|
||||
re := regexp.MustCompile(`\<[\S\s]+?\>`)
|
||||
@ -76,6 +78,7 @@ func HTML2str(html string) string {
|
||||
}
|
||||
|
||||
// DateFormat takes a time and a layout string and returns a string with the formatted date. Used by the template parser as "dateformat"
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func DateFormat(t time.Time, layout string) (datestring string) {
|
||||
datestring = t.Format(layout)
|
||||
return
|
||||
@ -123,6 +126,7 @@ var datePatterns = []string{
|
||||
}
|
||||
|
||||
// DateParse Parse Date use PHP time format.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func DateParse(dateString, format string) (time.Time, error) {
|
||||
replacer := strings.NewReplacer(datePatterns...)
|
||||
format = replacer.Replace(format)
|
||||
@ -130,6 +134,7 @@ func DateParse(dateString, format string) (time.Time, error) {
|
||||
}
|
||||
|
||||
// Date takes a PHP like date func to Go's time format.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func Date(t time.Time, format string) string {
|
||||
replacer := strings.NewReplacer(datePatterns...)
|
||||
format = replacer.Replace(format)
|
||||
@ -138,6 +143,7 @@ func Date(t time.Time, format string) string {
|
||||
|
||||
// Compare is a quick and dirty comparison function. It will convert whatever you give it to strings and see if the two values are equal.
|
||||
// Whitespace is trimmed. Used by the template parser as "eq".
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func Compare(a, b interface{}) (equal bool) {
|
||||
equal = false
|
||||
if strings.TrimSpace(fmt.Sprintf("%v", a)) == strings.TrimSpace(fmt.Sprintf("%v", b)) {
|
||||
@ -147,16 +153,19 @@ func Compare(a, b interface{}) (equal bool) {
|
||||
}
|
||||
|
||||
// CompareNot !Compare
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func CompareNot(a, b interface{}) (equal bool) {
|
||||
return !Compare(a, b)
|
||||
}
|
||||
|
||||
// NotNil the same as CompareNot
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func NotNil(a interface{}) (isNil bool) {
|
||||
return CompareNot(a, nil)
|
||||
}
|
||||
|
||||
// GetConfig get the Appconfig
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func GetConfig(returnType, key string, defaultVal interface{}) (value interface{}, err error) {
|
||||
switch returnType {
|
||||
case "String":
|
||||
@ -195,11 +204,13 @@ func GetConfig(returnType, key string, defaultVal interface{}) (value interface{
|
||||
}
|
||||
|
||||
// Str2html Convert string to template.HTML type.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func Str2html(raw string) template.HTML {
|
||||
return template.HTML(raw)
|
||||
}
|
||||
|
||||
// Htmlquote returns quoted html string.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func Htmlquote(text string) string {
|
||||
//HTML编码为实体符号
|
||||
/*
|
||||
@ -219,6 +230,7 @@ func Htmlquote(text string) string {
|
||||
}
|
||||
|
||||
// Htmlunquote returns unquoted html string.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func Htmlunquote(text string) string {
|
||||
//实体符号解释为HTML
|
||||
/*
|
||||
@ -249,11 +261,13 @@ func Htmlunquote(text string) string {
|
||||
// /user/John%20Doe
|
||||
//
|
||||
// more detail http://beego.me/docs/mvc/controller/urlbuilding.md
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func URLFor(endpoint string, values ...interface{}) string {
|
||||
return BeeApp.Handlers.URLFor(endpoint, values...)
|
||||
}
|
||||
|
||||
// AssetsJs returns script tag with src string.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func AssetsJs(text string) template.HTML {
|
||||
|
||||
text = "<script src=\"" + text + "\"></script>"
|
||||
@ -262,6 +276,7 @@ func AssetsJs(text string) template.HTML {
|
||||
}
|
||||
|
||||
// AssetsCSS returns stylesheet link tag with src string.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func AssetsCSS(text string) template.HTML {
|
||||
|
||||
text = "<link href=\"" + text + "\" rel=\"stylesheet\" />"
|
||||
@ -411,6 +426,7 @@ func parseFormToStruct(form url.Values, objT reflect.Type, objV reflect.Value) e
|
||||
}
|
||||
|
||||
// ParseForm will parse form values to struct via tag.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func ParseForm(form url.Values, obj interface{}) error {
|
||||
objT := reflect.TypeOf(obj)
|
||||
objV := reflect.ValueOf(obj)
|
||||
@ -442,6 +458,7 @@ var unKind = map[reflect.Kind]bool{
|
||||
|
||||
// RenderForm will render object to form html.
|
||||
// obj must be a struct pointer.
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func RenderForm(obj interface{}) template.HTML {
|
||||
objT := reflect.TypeOf(obj)
|
||||
objV := reflect.ValueOf(obj)
|
||||
@ -715,6 +732,7 @@ func ge(arg1, arg2 interface{}) (bool, error) {
|
||||
//
|
||||
// {{ map_get m "a" }} // return 1
|
||||
// {{ map_get m 1 "c" }} // return 4
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func MapGet(arg1 interface{}, arg2 ...interface{}) (interface{}, error) {
|
||||
arg1Type := reflect.TypeOf(arg1)
|
||||
arg1Val := reflect.ValueOf(arg1)
|
||||
|
@ -5,7 +5,7 @@
|
||||
// views/index.tpl
|
||||
// DO NOT EDIT!
|
||||
|
||||
package testdata
|
||||
package test
|
||||
|
||||
import (
|
||||
"bytes"
|
2
testdata/Makefile
vendored
2
testdata/Makefile
vendored
@ -1,2 +0,0 @@
|
||||
build_view:
|
||||
$(GOPATH)/bin/go-bindata-assetfs -pkg testdata views/...
|
3
testdata/views/blocks/block.tpl
vendored
3
testdata/views/blocks/block.tpl
vendored
@ -1,3 +0,0 @@
|
||||
{{define "block"}}
|
||||
<h1>Hello, blocks!</h1>
|
||||
{{end}}
|
3
testdata/views/header.tpl
vendored
3
testdata/views/header.tpl
vendored
@ -1,3 +0,0 @@
|
||||
{{define "header"}}
|
||||
<h1>Hello, astaxie!</h1>
|
||||
{{end}}
|
15
testdata/views/index.tpl
vendored
15
testdata/views/index.tpl
vendored
@ -1,15 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>beego welcome template</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
{{template "block"}}
|
||||
{{template "header"}}
|
||||
{{template "blocks/block.tpl"}}
|
||||
|
||||
<h2>{{ .Title }}</h2>
|
||||
<p> This is SomeVar: {{ .SomeVar }}</p>
|
||||
</body>
|
||||
</html>
|
5
tree.go
5
tree.go
@ -31,6 +31,7 @@ var (
|
||||
// fixRouter stores Fixed Router
|
||||
// wildcard stores params
|
||||
// leaves store the endpoint information
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
type Tree struct {
|
||||
//prefix set for static router
|
||||
prefix string
|
||||
@ -43,12 +44,14 @@ type Tree struct {
|
||||
}
|
||||
|
||||
// NewTree return a new Tree
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func NewTree() *Tree {
|
||||
return &Tree{}
|
||||
}
|
||||
|
||||
// AddTree will add tree to the exist Tree
|
||||
// prefix should has no params
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (t *Tree) AddTree(prefix string, tree *Tree) {
|
||||
t.addtree(splitPath(prefix), tree, nil, "")
|
||||
}
|
||||
@ -200,6 +203,7 @@ func filterTreeWithPrefix(t *Tree, wildcards []string, reg string) {
|
||||
}
|
||||
|
||||
// AddRouter call addseg function
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (t *Tree) AddRouter(pattern string, runObject interface{}) {
|
||||
t.addseg(splitPath(pattern), runObject, nil, "")
|
||||
}
|
||||
@ -283,6 +287,7 @@ func (t *Tree) addseg(segments []string, route interface{}, wildcards []string,
|
||||
}
|
||||
|
||||
// Match router to runObject & params
|
||||
// Deprecated: using pkg/, we will delete this in v2.1.0
|
||||
func (t *Tree) Match(pattern string, ctx *context.Context) (runObject interface{}) {
|
||||
if len(pattern) == 0 || pattern[0] != '/' {
|
||||
return nil
|
||||
|
@ -18,6 +18,8 @@ import (
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
var noExistedFile = "/tmp/not_existed_file"
|
||||
@ -66,9 +68,8 @@ func TestGrepFile(t *testing.T) {
|
||||
|
||||
path := filepath.Join(".", "testdata", "grepe.test")
|
||||
lines, err := GrepFile(`^\s*[^#]+`, path)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
assert.Nil(t, err)
|
||||
|
||||
if !reflect.DeepEqual(lines, []string{"hello", "world"}) {
|
||||
t.Errorf("expect [hello world], but receive %v", lines)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user