mirror of
https://github.com/astaxie/beego.git
synced 2024-11-22 12:30:54 +00:00
Adapter: web module
This commit is contained in:
parent
8ef9965eef
commit
1dae2c9eb3
48
pkg/adapter/admin.go
Normal file
48
pkg/adapter/admin.go
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// Copyright 2014 beego Author. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// 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 adapter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/astaxie/beego/pkg/server/web"
|
||||||
|
)
|
||||||
|
|
||||||
|
// FilterMonitorFunc is default monitor filter when admin module is enable.
|
||||||
|
// if this func returns, admin module records qps for this request by condition of this function logic.
|
||||||
|
// usage:
|
||||||
|
// func MyFilterMonitor(method, requestPath string, t time.Duration, pattern string, statusCode int) bool {
|
||||||
|
// if method == "POST" {
|
||||||
|
// return false
|
||||||
|
// }
|
||||||
|
// if t.Nanoseconds() < 100 {
|
||||||
|
// return false
|
||||||
|
// }
|
||||||
|
// if strings.HasPrefix(requestPath, "/astaxie") {
|
||||||
|
// return false
|
||||||
|
// }
|
||||||
|
// return true
|
||||||
|
// }
|
||||||
|
// beego.FilterMonitorFunc = MyFilterMonitor.
|
||||||
|
var FilterMonitorFunc func(string, string, time.Duration, string, int) bool
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
FilterMonitorFunc = web.FilterMonitorFunc
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrintTree prints all registered routers.
|
||||||
|
func PrintTree() M {
|
||||||
|
return (M)(web.PrintTree())
|
||||||
|
}
|
261
pkg/adapter/app.go
Normal file
261
pkg/adapter/app.go
Normal file
@ -0,0 +1,261 @@
|
|||||||
|
// Copyright 2014 beego Author. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// 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 adapter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
context2 "github.com/astaxie/beego/pkg/adapter/context"
|
||||||
|
"github.com/astaxie/beego/pkg/server/web"
|
||||||
|
"github.com/astaxie/beego/pkg/server/web/context"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// BeeApp is an application instance
|
||||||
|
BeeApp *App
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// create beego application
|
||||||
|
BeeApp = (*App)(web.BeeApp)
|
||||||
|
}
|
||||||
|
|
||||||
|
// App defines beego application with a new PatternServeMux.
|
||||||
|
type App web.App
|
||||||
|
|
||||||
|
// NewApp returns a new beego application.
|
||||||
|
func NewApp() *App {
|
||||||
|
return (*App)(web.NewApp())
|
||||||
|
}
|
||||||
|
|
||||||
|
// MiddleWare function for http.Handler
|
||||||
|
type MiddleWare web.MiddleWare
|
||||||
|
|
||||||
|
// Run beego application.
|
||||||
|
func (app *App) Run(mws ...MiddleWare) {
|
||||||
|
newMws := oldMiddlewareToNew(mws)
|
||||||
|
(*web.App)(app).Run(newMws...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func oldMiddlewareToNew(mws []MiddleWare) []web.MiddleWare {
|
||||||
|
newMws := make([]web.MiddleWare, 0, len(mws))
|
||||||
|
for _, old := range mws {
|
||||||
|
newMws = append(newMws, (web.MiddleWare)(old))
|
||||||
|
}
|
||||||
|
return newMws
|
||||||
|
}
|
||||||
|
|
||||||
|
// Router adds a patterned controller handler to BeeApp.
|
||||||
|
// it's an alias method of App.Router.
|
||||||
|
// usage:
|
||||||
|
// simple router
|
||||||
|
// beego.Router("/admin", &admin.UserController{})
|
||||||
|
// beego.Router("/admin/index", &admin.ArticleController{})
|
||||||
|
//
|
||||||
|
// regex router
|
||||||
|
//
|
||||||
|
// beego.Router("/api/:id([0-9]+)", &controllers.RController{})
|
||||||
|
//
|
||||||
|
// custom rules
|
||||||
|
// beego.Router("/api/list",&RestController{},"*:ListFood")
|
||||||
|
// beego.Router("/api/create",&RestController{},"post:CreateFood")
|
||||||
|
// beego.Router("/api/update",&RestController{},"put:UpdateFood")
|
||||||
|
// beego.Router("/api/delete",&RestController{},"delete:DeleteFood")
|
||||||
|
func Router(rootpath string, c ControllerInterface, mappingMethods ...string) *App {
|
||||||
|
return (*App)(web.Router(rootpath, c, mappingMethods...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnregisterFixedRoute unregisters the route with the specified fixedRoute. It is particularly useful
|
||||||
|
// in web applications that inherit most routes from a base webapp via the underscore
|
||||||
|
// import, and aim to overwrite only certain paths.
|
||||||
|
// The method parameter can be empty or "*" for all HTTP methods, or a particular
|
||||||
|
// method type (e.g. "GET" or "POST") for selective removal.
|
||||||
|
//
|
||||||
|
// Usage (replace "GET" with "*" for all methods):
|
||||||
|
// beego.UnregisterFixedRoute("/yourpreviouspath", "GET")
|
||||||
|
// beego.Router("/yourpreviouspath", yourControllerAddress, "get:GetNewPage")
|
||||||
|
func UnregisterFixedRoute(fixedRoute string, method string) *App {
|
||||||
|
return (*App)(web.UnregisterFixedRoute(fixedRoute, method))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Include will generate router file in the router/xxx.go from the controller's comments
|
||||||
|
// usage:
|
||||||
|
// beego.Include(&BankAccount{}, &OrderController{},&RefundController{},&ReceiptController{})
|
||||||
|
// type BankAccount struct{
|
||||||
|
// beego.Controller
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// register the function
|
||||||
|
// func (b *BankAccount)Mapping(){
|
||||||
|
// b.Mapping("ShowAccount" , b.ShowAccount)
|
||||||
|
// b.Mapping("ModifyAccount", b.ModifyAccount)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// //@router /account/:id [get]
|
||||||
|
// func (b *BankAccount) ShowAccount(){
|
||||||
|
// //logic
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// //@router /account/:id [post]
|
||||||
|
// func (b *BankAccount) ModifyAccount(){
|
||||||
|
// //logic
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// the comments @router url methodlist
|
||||||
|
// url support all the function Router's pattern
|
||||||
|
// methodlist [get post head put delete options *]
|
||||||
|
func Include(cList ...ControllerInterface) *App {
|
||||||
|
newList := oldToNewCtrlIntfs(cList)
|
||||||
|
return (*App)(web.Include(newList...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func oldToNewCtrlIntfs(cList []ControllerInterface) []web.ControllerInterface {
|
||||||
|
newList := make([]web.ControllerInterface, 0, len(cList))
|
||||||
|
for _, c := range cList {
|
||||||
|
newList = append(newList, c)
|
||||||
|
}
|
||||||
|
return newList
|
||||||
|
}
|
||||||
|
|
||||||
|
// RESTRouter adds a restful controller handler to BeeApp.
|
||||||
|
// its' controller implements beego.ControllerInterface and
|
||||||
|
// defines a param "pattern/:objectId" to visit each resource.
|
||||||
|
func RESTRouter(rootpath string, c ControllerInterface) *App {
|
||||||
|
return (*App)(web.RESTRouter(rootpath, c))
|
||||||
|
}
|
||||||
|
|
||||||
|
// AutoRouter adds defined controller handler to BeeApp.
|
||||||
|
// 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.
|
||||||
|
func AutoRouter(c ControllerInterface) *App {
|
||||||
|
return (*App)(web.AutoRouter(c))
|
||||||
|
}
|
||||||
|
|
||||||
|
// AutoPrefix adds controller handler to BeeApp with prefix.
|
||||||
|
// 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.
|
||||||
|
func AutoPrefix(prefix string, c ControllerInterface) *App {
|
||||||
|
return (*App)(web.AutoPrefix(prefix, c))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get used to register router for Get method
|
||||||
|
// usage:
|
||||||
|
// beego.Get("/", func(ctx *context.Context){
|
||||||
|
// ctx.Output.Body("hello world")
|
||||||
|
// })
|
||||||
|
func Get(rootpath string, f FilterFunc) *App {
|
||||||
|
return (*App)(web.Get(rootpath, func(ctx *context.Context) {
|
||||||
|
f((*context2.Context)(ctx))
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Post used to register router for Post method
|
||||||
|
// usage:
|
||||||
|
// beego.Post("/api", func(ctx *context.Context){
|
||||||
|
// ctx.Output.Body("hello world")
|
||||||
|
// })
|
||||||
|
func Post(rootpath string, f FilterFunc) *App {
|
||||||
|
return (*App)(web.Post(rootpath, func(ctx *context.Context) {
|
||||||
|
f((*context2.Context)(ctx))
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete used to register router for Delete method
|
||||||
|
// usage:
|
||||||
|
// beego.Delete("/api", func(ctx *context.Context){
|
||||||
|
// ctx.Output.Body("hello world")
|
||||||
|
// })
|
||||||
|
func Delete(rootpath string, f FilterFunc) *App {
|
||||||
|
return (*App)(web.Delete(rootpath, func(ctx *context.Context) {
|
||||||
|
f((*context2.Context)(ctx))
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put used to register router for Put method
|
||||||
|
// usage:
|
||||||
|
// beego.Put("/api", func(ctx *context.Context){
|
||||||
|
// ctx.Output.Body("hello world")
|
||||||
|
// })
|
||||||
|
func Put(rootpath string, f FilterFunc) *App {
|
||||||
|
return (*App)(web.Put(rootpath, func(ctx *context.Context) {
|
||||||
|
f((*context2.Context)(ctx))
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Head used to register router for Head method
|
||||||
|
// usage:
|
||||||
|
// beego.Head("/api", func(ctx *context.Context){
|
||||||
|
// ctx.Output.Body("hello world")
|
||||||
|
// })
|
||||||
|
func Head(rootpath string, f FilterFunc) *App {
|
||||||
|
return (*App)(web.Head(rootpath, func(ctx *context.Context) {
|
||||||
|
f((*context2.Context)(ctx))
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Options used to register router for Options method
|
||||||
|
// usage:
|
||||||
|
// beego.Options("/api", func(ctx *context.Context){
|
||||||
|
// ctx.Output.Body("hello world")
|
||||||
|
// })
|
||||||
|
func Options(rootpath string, f FilterFunc) *App {
|
||||||
|
return (*App)(web.Options(rootpath, func(ctx *context.Context) {
|
||||||
|
f((*context2.Context)(ctx))
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Patch used to register router for Patch method
|
||||||
|
// usage:
|
||||||
|
// beego.Patch("/api", func(ctx *context.Context){
|
||||||
|
// ctx.Output.Body("hello world")
|
||||||
|
// })
|
||||||
|
func Patch(rootpath string, f FilterFunc) *App {
|
||||||
|
return (*App)(web.Patch(rootpath, func(ctx *context.Context) {
|
||||||
|
f((*context2.Context)(ctx))
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Any used to register router for all methods
|
||||||
|
// usage:
|
||||||
|
// beego.Any("/api", func(ctx *context.Context){
|
||||||
|
// ctx.Output.Body("hello world")
|
||||||
|
// })
|
||||||
|
func Any(rootpath string, f FilterFunc) *App {
|
||||||
|
return (*App)(web.Any(rootpath, func(ctx *context.Context) {
|
||||||
|
f((*context2.Context)(ctx))
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handler used to register a Handler router
|
||||||
|
// usage:
|
||||||
|
// beego.Handler("/api", http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) {
|
||||||
|
// fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
|
||||||
|
// }))
|
||||||
|
func Handler(rootpath string, h http.Handler, options ...interface{}) *App {
|
||||||
|
return (*App)(web.Handler(rootpath, h, options))
|
||||||
|
}
|
||||||
|
|
||||||
|
// InsertFilter adds a FilterFunc with pattern condition and action constant.
|
||||||
|
// 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)
|
||||||
|
func InsertFilter(pattern string, pos int, filter FilterFunc, params ...bool) *App {
|
||||||
|
return (*App)(web.InsertFilter(pattern, pos, func(ctx *context.Context) {
|
||||||
|
filter((*context2.Context)(ctx))
|
||||||
|
}, params...))
|
||||||
|
}
|
75
pkg/adapter/beego.go
Normal file
75
pkg/adapter/beego.go
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
// Copyright 2014 beego Author. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// 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 adapter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/astaxie/beego/pkg/server/web"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// VERSION represent beego web framework version.
|
||||||
|
VERSION = web.VERSION
|
||||||
|
|
||||||
|
// DEV is for develop
|
||||||
|
DEV = web.DEV
|
||||||
|
// PROD is for production
|
||||||
|
PROD = web.PROD
|
||||||
|
)
|
||||||
|
|
||||||
|
// M is Map shortcut
|
||||||
|
type M web.M
|
||||||
|
|
||||||
|
// Hook function to run
|
||||||
|
type hookfunc func() error
|
||||||
|
|
||||||
|
var (
|
||||||
|
hooks = make([]hookfunc, 0) // hook function slice to store the hookfunc
|
||||||
|
)
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
func AddAPPStartHook(hf ...hookfunc) {
|
||||||
|
for _, f := range hf {
|
||||||
|
web.AddAPPStartHook(func() error {
|
||||||
|
return f()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run beego application.
|
||||||
|
// beego.Run() default run on HttpPort
|
||||||
|
// beego.Run("localhost")
|
||||||
|
// beego.Run(":8089")
|
||||||
|
// beego.Run("127.0.0.1:8089")
|
||||||
|
func Run(params ...string) {
|
||||||
|
web.Run(params...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RunWithMiddleWares Run beego application with middlewares.
|
||||||
|
func RunWithMiddleWares(addr string, mws ...MiddleWare) {
|
||||||
|
newMws := oldMiddlewareToNew(mws)
|
||||||
|
web.RunWithMiddleWares(addr, newMws...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestBeegoInit is for test package init
|
||||||
|
func TestBeegoInit(ap string) {
|
||||||
|
web.TestBeegoInit(ap)
|
||||||
|
}
|
||||||
|
|
||||||
|
// InitBeegoBeforeTest is for test package init
|
||||||
|
func InitBeegoBeforeTest(appConfigPath string) {
|
||||||
|
web.InitBeegoBeforeTest(appConfigPath)
|
||||||
|
}
|
27
pkg/adapter/build_info.go
Normal file
27
pkg/adapter/build_info.go
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// Copyright 2020 astaxie
|
||||||
|
//
|
||||||
|
// 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 adapter
|
||||||
|
|
||||||
|
var (
|
||||||
|
BuildVersion string
|
||||||
|
BuildGitRevision string
|
||||||
|
BuildStatus string
|
||||||
|
BuildTag string
|
||||||
|
BuildTime string
|
||||||
|
|
||||||
|
GoVersion string
|
||||||
|
|
||||||
|
GitBranch string
|
||||||
|
)
|
179
pkg/adapter/config.go
Normal file
179
pkg/adapter/config.go
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
// Copyright 2014 beego Author. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// 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 adapter
|
||||||
|
|
||||||
|
import (
|
||||||
|
context2 "context"
|
||||||
|
|
||||||
|
"github.com/astaxie/beego/pkg/adapter/session"
|
||||||
|
newCfg "github.com/astaxie/beego/pkg/infrastructure/config"
|
||||||
|
"github.com/astaxie/beego/pkg/server/web"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Config is the main struct for BConfig
|
||||||
|
type Config web.Config
|
||||||
|
|
||||||
|
// Listen holds for http and https related config
|
||||||
|
type Listen web.Listen
|
||||||
|
|
||||||
|
// WebConfig holds web related config
|
||||||
|
type WebConfig web.WebConfig
|
||||||
|
|
||||||
|
// SessionConfig holds session related config
|
||||||
|
type SessionConfig web.SessionConfig
|
||||||
|
|
||||||
|
// LogConfig holds Log related config
|
||||||
|
type LogConfig web.LogConfig
|
||||||
|
|
||||||
|
var (
|
||||||
|
// BConfig is the default config for Application
|
||||||
|
BConfig *Config
|
||||||
|
// AppConfig is the instance of Config, store the config information from file
|
||||||
|
AppConfig *beegoAppConfig
|
||||||
|
// AppPath is the absolute path to the app
|
||||||
|
AppPath string
|
||||||
|
// GlobalSessions is the instance for the session manager
|
||||||
|
GlobalSessions *session.Manager
|
||||||
|
|
||||||
|
// appConfigPath is the path to the config files
|
||||||
|
appConfigPath string
|
||||||
|
// appConfigProvider is the provider for the config, default is ini
|
||||||
|
appConfigProvider = "ini"
|
||||||
|
// WorkPath is the absolute path to project root directory
|
||||||
|
WorkPath string
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
BConfig = (*Config)(web.BConfig)
|
||||||
|
AppPath = web.AppPath
|
||||||
|
|
||||||
|
WorkPath = web.WorkPath
|
||||||
|
|
||||||
|
AppConfig = &beegoAppConfig{innerConfig: (newCfg.Configer)(web.AppConfig)}
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadAppConfig allow developer to apply a config file
|
||||||
|
func LoadAppConfig(adapterName, configPath string) error {
|
||||||
|
return web.LoadAppConfig(adapterName, configPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
type beegoAppConfig struct {
|
||||||
|
innerConfig newCfg.Configer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *beegoAppConfig) Set(key, val string) error {
|
||||||
|
if err := b.innerConfig.Set(context2.Background(), BConfig.RunMode+"::"+key, val); err != nil {
|
||||||
|
return b.innerConfig.Set(context2.Background(), key, val)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *beegoAppConfig) String(key string) string {
|
||||||
|
if v, err := b.innerConfig.String(context2.Background(), BConfig.RunMode+"::"+key); v != "" && err != nil {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
res, _ := b.innerConfig.String(context2.Background(), key)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *beegoAppConfig) Strings(key string) []string {
|
||||||
|
if v, err := b.innerConfig.Strings(context2.Background(), BConfig.RunMode+"::"+key); len(v) > 0 && err != nil {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
res, _ := b.innerConfig.Strings(context2.Background(), key)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *beegoAppConfig) Int(key string) (int, error) {
|
||||||
|
if v, err := b.innerConfig.Int(context2.Background(), BConfig.RunMode+"::"+key); err == nil {
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
return b.innerConfig.Int(context2.Background(), key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *beegoAppConfig) Int64(key string) (int64, error) {
|
||||||
|
if v, err := b.innerConfig.Int64(context2.Background(), BConfig.RunMode+"::"+key); err == nil {
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
return b.innerConfig.Int64(context2.Background(), key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *beegoAppConfig) Bool(key string) (bool, error) {
|
||||||
|
if v, err := b.innerConfig.Bool(context2.Background(), BConfig.RunMode+"::"+key); err == nil {
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
return b.innerConfig.Bool(context2.Background(), key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *beegoAppConfig) Float(key string) (float64, error) {
|
||||||
|
if v, err := b.innerConfig.Float(context2.Background(), BConfig.RunMode+"::"+key); err == nil {
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
return b.innerConfig.Float(context2.Background(), key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *beegoAppConfig) DefaultString(key string, defaultVal string) string {
|
||||||
|
if v := b.String(key); v != "" {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
return defaultVal
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *beegoAppConfig) DefaultStrings(key string, defaultVal []string) []string {
|
||||||
|
if v := b.Strings(key); len(v) != 0 {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
return defaultVal
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *beegoAppConfig) DefaultInt(key string, defaultVal int) int {
|
||||||
|
if v, err := b.Int(key); err == nil {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
return defaultVal
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *beegoAppConfig) DefaultInt64(key string, defaultVal int64) int64 {
|
||||||
|
if v, err := b.Int64(key); err == nil {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
return defaultVal
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *beegoAppConfig) DefaultBool(key string, defaultVal bool) bool {
|
||||||
|
if v, err := b.Bool(key); err == nil {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
return defaultVal
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *beegoAppConfig) DefaultFloat(key string, defaultVal float64) float64 {
|
||||||
|
if v, err := b.Float(key); err == nil {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
return defaultVal
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *beegoAppConfig) DIY(key string) (interface{}, error) {
|
||||||
|
return b.innerConfig.DIY(context2.Background(), key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *beegoAppConfig) GetSection(section string) (map[string]string, error) {
|
||||||
|
return b.innerConfig.GetSection(context2.Background(), section)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *beegoAppConfig) SaveConfigFile(filename string) error {
|
||||||
|
return b.innerConfig.SaveConfigFile(context2.Background(), filename)
|
||||||
|
}
|
401
pkg/adapter/controller.go
Normal file
401
pkg/adapter/controller.go
Normal file
@ -0,0 +1,401 @@
|
|||||||
|
// Copyright 2014 beego Author. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// 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 adapter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"mime/multipart"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/astaxie/beego/pkg/adapter/context"
|
||||||
|
"github.com/astaxie/beego/pkg/adapter/session"
|
||||||
|
webContext "github.com/astaxie/beego/pkg/server/web/context"
|
||||||
|
|
||||||
|
"github.com/astaxie/beego/pkg/server/web"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// ErrAbort custom error when user stop request handler manually.
|
||||||
|
ErrAbort = web.ErrAbort
|
||||||
|
// GlobalControllerRouter store comments with controller. pkgpath+controller:comments
|
||||||
|
GlobalControllerRouter = web.GlobalControllerRouter
|
||||||
|
)
|
||||||
|
|
||||||
|
// ControllerFilter store the filter for controller
|
||||||
|
type ControllerFilter web.ControllerFilter
|
||||||
|
|
||||||
|
// ControllerFilterComments store the comment for controller level filter
|
||||||
|
type ControllerFilterComments web.ControllerFilterComments
|
||||||
|
|
||||||
|
// ControllerImportComments store the import comment for controller needed
|
||||||
|
type ControllerImportComments web.ControllerImportComments
|
||||||
|
|
||||||
|
// ControllerComments store the comment for the controller method
|
||||||
|
type ControllerComments web.ControllerComments
|
||||||
|
|
||||||
|
// ControllerCommentsSlice implements the sort interface
|
||||||
|
type ControllerCommentsSlice web.ControllerCommentsSlice
|
||||||
|
|
||||||
|
func (p ControllerCommentsSlice) Len() int {
|
||||||
|
return (web.ControllerCommentsSlice)(p).Len()
|
||||||
|
}
|
||||||
|
func (p ControllerCommentsSlice) Less(i, j int) bool {
|
||||||
|
return (web.ControllerCommentsSlice)(p).Less(i, j)
|
||||||
|
}
|
||||||
|
func (p ControllerCommentsSlice) Swap(i, j int) {
|
||||||
|
(web.ControllerCommentsSlice)(p).Swap(i, j)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Controller defines some basic http request handler operations, such as
|
||||||
|
// http context, template and view, session and xsrf.
|
||||||
|
type Controller web.Controller
|
||||||
|
|
||||||
|
// ControllerInterface is an interface to uniform all controller handler.
|
||||||
|
type ControllerInterface web.ControllerInterface
|
||||||
|
|
||||||
|
// Init generates default values of controller operations.
|
||||||
|
func (c *Controller) Init(ctx *context.Context, controllerName, actionName string, app interface{}) {
|
||||||
|
(*web.Controller)(c).Init((*webContext.Context)(ctx), controllerName, actionName, app)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare runs after Init before request function execution.
|
||||||
|
func (c *Controller) Prepare() {
|
||||||
|
(*web.Controller)(c).Prepare()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finish runs after request function execution.
|
||||||
|
func (c *Controller) Finish() {
|
||||||
|
(*web.Controller)(c).Finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get adds a request function to handle GET request.
|
||||||
|
func (c *Controller) Get() {
|
||||||
|
(*web.Controller)(c).Get()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Post adds a request function to handle POST request.
|
||||||
|
func (c *Controller) Post() {
|
||||||
|
(*web.Controller)(c).Post()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete adds a request function to handle DELETE request.
|
||||||
|
func (c *Controller) Delete() {
|
||||||
|
(*web.Controller)(c).Delete()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put adds a request function to handle PUT request.
|
||||||
|
func (c *Controller) Put() {
|
||||||
|
(*web.Controller)(c).Put()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Head adds a request function to handle HEAD request.
|
||||||
|
func (c *Controller) Head() {
|
||||||
|
(*web.Controller)(c).Head()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Patch adds a request function to handle PATCH request.
|
||||||
|
func (c *Controller) Patch() {
|
||||||
|
(*web.Controller)(c).Patch()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Options adds a request function to handle OPTIONS request.
|
||||||
|
func (c *Controller) Options() {
|
||||||
|
(*web.Controller)(c).Options()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trace adds a request function to handle Trace request.
|
||||||
|
// this method SHOULD NOT be overridden.
|
||||||
|
// https://tools.ietf.org/html/rfc7231#section-4.3.8
|
||||||
|
// The TRACE method requests a remote, application-level loop-back of
|
||||||
|
// the request message. The final recipient of the request SHOULD
|
||||||
|
// 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]).
|
||||||
|
func (c *Controller) Trace() {
|
||||||
|
(*web.Controller)(c).Trace()
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandlerFunc call function with the name
|
||||||
|
func (c *Controller) HandlerFunc(fnname string) bool {
|
||||||
|
return (*web.Controller)(c).HandlerFunc(fnname)
|
||||||
|
}
|
||||||
|
|
||||||
|
// URLMapping register the internal Controller router.
|
||||||
|
func (c *Controller) URLMapping() {
|
||||||
|
(*web.Controller)(c).URLMapping()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mapping the method to function
|
||||||
|
func (c *Controller) Mapping(method string, fn func()) {
|
||||||
|
(*web.Controller)(c).Mapping(method, fn)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render sends the response with rendered template bytes as text/html type.
|
||||||
|
func (c *Controller) Render() error {
|
||||||
|
return (*web.Controller)(c).Render()
|
||||||
|
}
|
||||||
|
|
||||||
|
// RenderString returns the rendered template string. Do not send out response.
|
||||||
|
func (c *Controller) RenderString() (string, error) {
|
||||||
|
return (*web.Controller)(c).RenderString()
|
||||||
|
}
|
||||||
|
|
||||||
|
// RenderBytes returns the bytes of rendered template string. Do not send out response.
|
||||||
|
func (c *Controller) RenderBytes() ([]byte, error) {
|
||||||
|
return (*web.Controller)(c).RenderBytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Redirect sends the redirection response to url with status code.
|
||||||
|
func (c *Controller) Redirect(url string, code int) {
|
||||||
|
(*web.Controller)(c).Redirect(url, code)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetData set the data depending on the accepted
|
||||||
|
func (c *Controller) SetData(data interface{}) {
|
||||||
|
(*web.Controller)(c).SetData(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Abort stops controller handler and show the error data if code is defined in ErrorMap or code string.
|
||||||
|
func (c *Controller) Abort(code string) {
|
||||||
|
(*web.Controller)(c).Abort(code)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CustomAbort stops controller handler and show the error data, it's similar Aborts, but support status code and body.
|
||||||
|
func (c *Controller) CustomAbort(status int, body string) {
|
||||||
|
(*web.Controller)(c).CustomAbort(status, body)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StopRun makes panic of USERSTOPRUN error and go to recover function if defined.
|
||||||
|
func (c *Controller) StopRun() {
|
||||||
|
(*web.Controller)(c).StopRun()
|
||||||
|
}
|
||||||
|
|
||||||
|
// URLFor does another controller handler in this request function.
|
||||||
|
// it goes to this controller method if endpoint is not clear.
|
||||||
|
func (c *Controller) URLFor(endpoint string, values ...interface{}) string {
|
||||||
|
return (*web.Controller)(c).URLFor(endpoint, values...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServeJSON sends a json response with encoding charset.
|
||||||
|
func (c *Controller) ServeJSON(encoding ...bool) {
|
||||||
|
(*web.Controller)(c).ServeJSON(encoding...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServeJSONP sends a jsonp response.
|
||||||
|
func (c *Controller) ServeJSONP() {
|
||||||
|
(*web.Controller)(c).ServeJSONP()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServeXML sends xml response.
|
||||||
|
func (c *Controller) ServeXML() {
|
||||||
|
(*web.Controller)(c).ServeXML()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServeYAML sends yaml response.
|
||||||
|
func (c *Controller) ServeYAML() {
|
||||||
|
(*web.Controller)(c).ServeYAML()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServeFormatted serve YAML, XML OR JSON, depending on the value of the Accept header
|
||||||
|
func (c *Controller) ServeFormatted(encoding ...bool) {
|
||||||
|
(*web.Controller)(c).ServeFormatted(encoding...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Input returns the input data map from POST or PUT request body and query string.
|
||||||
|
func (c *Controller) Input() url.Values {
|
||||||
|
return (*web.Controller)(c).Input()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseForm maps input data map to obj struct.
|
||||||
|
func (c *Controller) ParseForm(obj interface{}) error {
|
||||||
|
return (*web.Controller)(c).ParseForm(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetString returns the input value by key string or the default value while it's present and input is blank
|
||||||
|
func (c *Controller) GetString(key string, def ...string) string {
|
||||||
|
return (*web.Controller)(c).GetString(key, def...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
func (c *Controller) GetStrings(key string, def ...[]string) []string {
|
||||||
|
return (*web.Controller)(c).GetStrings(key, def...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetInt returns input as an int or the default value while it's present and input is blank
|
||||||
|
func (c *Controller) GetInt(key string, def ...int) (int, error) {
|
||||||
|
return (*web.Controller)(c).GetInt(key, def...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetInt8 return input as an int8 or the default value while it's present and input is blank
|
||||||
|
func (c *Controller) GetInt8(key string, def ...int8) (int8, error) {
|
||||||
|
return (*web.Controller)(c).GetInt8(key, def...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUint8 return input as an uint8 or the default value while it's present and input is blank
|
||||||
|
func (c *Controller) GetUint8(key string, def ...uint8) (uint8, error) {
|
||||||
|
return (*web.Controller)(c).GetUint8(key, def...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetInt16 returns input as an int16 or the default value while it's present and input is blank
|
||||||
|
func (c *Controller) GetInt16(key string, def ...int16) (int16, error) {
|
||||||
|
return (*web.Controller)(c).GetInt16(key, def...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUint16 returns input as an uint16 or the default value while it's present and input is blank
|
||||||
|
func (c *Controller) GetUint16(key string, def ...uint16) (uint16, error) {
|
||||||
|
return (*web.Controller)(c).GetUint16(key, def...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetInt32 returns input as an int32 or the default value while it's present and input is blank
|
||||||
|
func (c *Controller) GetInt32(key string, def ...int32) (int32, error) {
|
||||||
|
return (*web.Controller)(c).GetInt32(key, def...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUint32 returns input as an uint32 or the default value while it's present and input is blank
|
||||||
|
func (c *Controller) GetUint32(key string, def ...uint32) (uint32, error) {
|
||||||
|
return (*web.Controller)(c).GetUint32(key, def...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetInt64 returns input value as int64 or the default value while it's present and input is blank.
|
||||||
|
func (c *Controller) GetInt64(key string, def ...int64) (int64, error) {
|
||||||
|
return (*web.Controller)(c).GetInt64(key, def...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUint64 returns input value as uint64 or the default value while it's present and input is blank.
|
||||||
|
func (c *Controller) GetUint64(key string, def ...uint64) (uint64, error) {
|
||||||
|
return (*web.Controller)(c).GetUint64(key, def...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBool returns input value as bool or the default value while it's present and input is blank.
|
||||||
|
func (c *Controller) GetBool(key string, def ...bool) (bool, error) {
|
||||||
|
return (*web.Controller)(c).GetBool(key, def...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFloat returns input value as float64 or the default value while it's present and input is blank.
|
||||||
|
func (c *Controller) GetFloat(key string, def ...float64) (float64, error) {
|
||||||
|
return (*web.Controller)(c).GetFloat(key, def...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFile returns the file data in file upload field named as key.
|
||||||
|
// it returns the first one of multi-uploaded files.
|
||||||
|
func (c *Controller) GetFile(key string) (multipart.File, *multipart.FileHeader, error) {
|
||||||
|
return (*web.Controller)(c).GetFile(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFiles return multi-upload files
|
||||||
|
// files, err:=c.GetFiles("myfiles")
|
||||||
|
// if err != nil {
|
||||||
|
// http.Error(w, err.Error(), http.StatusNoContent)
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// for i, _ := range files {
|
||||||
|
// //for each fileheader, get a handle to the actual file
|
||||||
|
// file, err := files[i].Open()
|
||||||
|
// defer file.Close()
|
||||||
|
// if err != nil {
|
||||||
|
// http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// //create destination file making sure the path is writeable.
|
||||||
|
// dst, err := os.Create("upload/" + files[i].Filename)
|
||||||
|
// defer dst.Close()
|
||||||
|
// if err != nil {
|
||||||
|
// http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// //copy the uploaded file to the destination file
|
||||||
|
// if _, err := io.Copy(dst, file); err != nil {
|
||||||
|
// http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
func (c *Controller) GetFiles(key string) ([]*multipart.FileHeader, error) {
|
||||||
|
return (*web.Controller)(c).GetFiles(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SaveToFile saves uploaded file to new path.
|
||||||
|
// it only operates the first one of mutil-upload form file field.
|
||||||
|
func (c *Controller) SaveToFile(fromfile, tofile string) error {
|
||||||
|
return (*web.Controller)(c).SaveToFile(fromfile, tofile)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StartSession starts session and load old session data info this controller.
|
||||||
|
func (c *Controller) StartSession() session.Store {
|
||||||
|
s := (*web.Controller)(c).StartSession()
|
||||||
|
return session.CreateNewToOldStoreAdapter(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetSession puts value into session.
|
||||||
|
func (c *Controller) SetSession(name interface{}, value interface{}) {
|
||||||
|
(*web.Controller)(c).SetSession(name, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSession gets value from session.
|
||||||
|
func (c *Controller) GetSession(name interface{}) interface{} {
|
||||||
|
return (*web.Controller)(c).GetSession(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DelSession removes value from session.
|
||||||
|
func (c *Controller) DelSession(name interface{}) {
|
||||||
|
(*web.Controller)(c).DelSession(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SessionRegenerateID regenerates session id for this session.
|
||||||
|
// the session data have no changes.
|
||||||
|
func (c *Controller) SessionRegenerateID() {
|
||||||
|
(*web.Controller)(c).SessionRegenerateID()
|
||||||
|
}
|
||||||
|
|
||||||
|
// DestroySession cleans session data and session cookie.
|
||||||
|
func (c *Controller) DestroySession() {
|
||||||
|
(*web.Controller)(c).DestroySession()
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsAjax returns this request is ajax or not.
|
||||||
|
func (c *Controller) IsAjax() bool {
|
||||||
|
return (*web.Controller)(c).IsAjax()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSecureCookie returns decoded cookie value from encoded browser cookie values.
|
||||||
|
func (c *Controller) GetSecureCookie(Secret, key string) (string, bool) {
|
||||||
|
return (*web.Controller)(c).GetSecureCookie(Secret, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetSecureCookie puts value into cookie after encoded the value.
|
||||||
|
func (c *Controller) SetSecureCookie(Secret, name, value string, others ...interface{}) {
|
||||||
|
(*web.Controller)(c).SetSecureCookie(Secret, name, value, others...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// XSRFToken creates a CSRF token string and returns.
|
||||||
|
func (c *Controller) XSRFToken() string {
|
||||||
|
return (*web.Controller)(c).XSRFToken()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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".
|
||||||
|
func (c *Controller) CheckXSRFCookie() bool {
|
||||||
|
return (*web.Controller)(c).CheckXSRFCookie()
|
||||||
|
}
|
||||||
|
|
||||||
|
// XSRFFormHTML writes an input field contains xsrf token value.
|
||||||
|
func (c *Controller) XSRFFormHTML() string {
|
||||||
|
return (*web.Controller)(c).XSRFFormHTML()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetControllerAndAction gets the executing controller name and action name.
|
||||||
|
func (c *Controller) GetControllerAndAction() (string, string) {
|
||||||
|
return (*web.Controller)(c).GetControllerAndAction()
|
||||||
|
}
|
202
pkg/adapter/error.go
Normal file
202
pkg/adapter/error.go
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
// Copyright 2014 beego Author. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// 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 adapter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/astaxie/beego/pkg/adapter/context"
|
||||||
|
beecontext "github.com/astaxie/beego/pkg/server/web/context"
|
||||||
|
|
||||||
|
"github.com/astaxie/beego/pkg/server/web"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
errorTypeHandler = iota
|
||||||
|
errorTypeController
|
||||||
|
)
|
||||||
|
|
||||||
|
var tpl = `
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
|
<title>beego application error</title>
|
||||||
|
<style>
|
||||||
|
html, body, body * {padding: 0; margin: 0;}
|
||||||
|
#header {background:#ffd; border-bottom:solid 2px #A31515; padding: 20px 10px;}
|
||||||
|
#header h2{ }
|
||||||
|
#footer {border-top:solid 1px #aaa; padding: 5px 10px; font-size: 12px; color:green;}
|
||||||
|
#content {padding: 5px;}
|
||||||
|
#content .stack b{ font-size: 13px; color: red;}
|
||||||
|
#content .stack pre{padding-left: 10px;}
|
||||||
|
table {}
|
||||||
|
td.t {text-align: right; padding-right: 5px; color: #888;}
|
||||||
|
</style>
|
||||||
|
<script type="text/javascript">
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="header">
|
||||||
|
<h2>{{.AppError}}</h2>
|
||||||
|
</div>
|
||||||
|
<div id="content">
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td class="t">Request Method: </td><td>{{.RequestMethod}}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="t">Request URL: </td><td>{{.RequestURL}}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="t">RemoteAddr: </td><td>{{.RemoteAddr }}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<div class="stack">
|
||||||
|
<b>Stack</b>
|
||||||
|
<pre>{{.Stack}}</pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="footer">
|
||||||
|
<p>beego {{ .BeegoVersion }} (beego framework)</p>
|
||||||
|
<p>golang version: {{.GoVersion}}</p>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`
|
||||||
|
|
||||||
|
var errtpl = `
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
|
<title>{{.Title}}</title>
|
||||||
|
<style type="text/css">
|
||||||
|
* {
|
||||||
|
margin:0;
|
||||||
|
padding:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color:#EFEFEF;
|
||||||
|
font: .9em "Lucida Sans Unicode", "Lucida Grande", sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
#wrapper{
|
||||||
|
width:600px;
|
||||||
|
margin:40px auto 0;
|
||||||
|
text-align:center;
|
||||||
|
-moz-box-shadow: 5px 5px 10px rgba(0,0,0,0.3);
|
||||||
|
-webkit-box-shadow: 5px 5px 10px rgba(0,0,0,0.3);
|
||||||
|
box-shadow: 5px 5px 10px rgba(0,0,0,0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
#wrapper h1{
|
||||||
|
color:#FFF;
|
||||||
|
text-align:center;
|
||||||
|
margin-bottom:20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#wrapper a{
|
||||||
|
display:block;
|
||||||
|
font-size:.9em;
|
||||||
|
padding-top:20px;
|
||||||
|
color:#FFF;
|
||||||
|
text-decoration:none;
|
||||||
|
text-align:center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#container {
|
||||||
|
width:600px;
|
||||||
|
padding-bottom:15px;
|
||||||
|
background-color:#FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navtop{
|
||||||
|
height:40px;
|
||||||
|
background-color:#24B2EB;
|
||||||
|
padding:13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
padding:10px 10px 25px;
|
||||||
|
background: #FFFFFF;
|
||||||
|
margin:;
|
||||||
|
color:#333;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.button{
|
||||||
|
color:white;
|
||||||
|
padding:15px 20px;
|
||||||
|
text-shadow:1px 1px 0 #00A5FF;
|
||||||
|
font-weight:bold;
|
||||||
|
text-align:center;
|
||||||
|
border:1px solid #24B2EB;
|
||||||
|
margin:0px 200px;
|
||||||
|
clear:both;
|
||||||
|
background-color: #24B2EB;
|
||||||
|
border-radius:100px;
|
||||||
|
-moz-border-radius:100px;
|
||||||
|
-webkit-border-radius:100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.button:hover{
|
||||||
|
text-decoration:none;
|
||||||
|
background-color: #24B2EB;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="wrapper">
|
||||||
|
<div id="container">
|
||||||
|
<div class="navtop">
|
||||||
|
<h1>{{.Title}}</h1>
|
||||||
|
</div>
|
||||||
|
<div id="content">
|
||||||
|
{{.Content}}
|
||||||
|
<a href="/" title="Home" class="button">Go Home</a><br />
|
||||||
|
|
||||||
|
<br>Powered by beego {{.BeegoVersion}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`
|
||||||
|
|
||||||
|
// ErrorMaps holds map of http handlers for each error string.
|
||||||
|
// there is 10 kinds default error(40x and 50x)
|
||||||
|
var ErrorMaps = web.ErrorMaps
|
||||||
|
|
||||||
|
// ErrorHandler registers http.HandlerFunc to each http err code string.
|
||||||
|
// usage:
|
||||||
|
// beego.ErrorHandler("404",NotFound)
|
||||||
|
// beego.ErrorHandler("500",InternalServerError)
|
||||||
|
func ErrorHandler(code string, h http.HandlerFunc) *App {
|
||||||
|
return (*App)(web.ErrorHandler(code, h))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrorController registers ControllerInterface to each http err code string.
|
||||||
|
// usage:
|
||||||
|
// beego.ErrorController(&controllers.ErrorController{})
|
||||||
|
func ErrorController(c ControllerInterface) *App {
|
||||||
|
return (*App)(web.ErrorController(c))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exception Write HttpStatus with errCode and Exec error handler if exist.
|
||||||
|
func Exception(errCode uint64, ctx *context.Context) {
|
||||||
|
web.Exception(errCode, (*beecontext.Context)(ctx))
|
||||||
|
}
|
36
pkg/adapter/filter.go
Normal file
36
pkg/adapter/filter.go
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
// Copyright 2014 beego Author. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// 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 adapter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/astaxie/beego/pkg/adapter/context"
|
||||||
|
"github.com/astaxie/beego/pkg/server/web"
|
||||||
|
beecontext "github.com/astaxie/beego/pkg/server/web/context"
|
||||||
|
)
|
||||||
|
|
||||||
|
// FilterFunc defines a filter function which is invoked before the controller handler is executed.
|
||||||
|
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.
|
||||||
|
type FilterRouter web.FilterRouter
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
func (f *FilterRouter) ValidRouter(url string, ctx *context.Context) bool {
|
||||||
|
return (*web.FilterRouter)(f).ValidRouter(url, (*beecontext.Context)(ctx))
|
||||||
|
}
|
63
pkg/adapter/flash.go
Normal file
63
pkg/adapter/flash.go
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
// Copyright 2014 beego Author. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// 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 adapter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/astaxie/beego/pkg/server/web"
|
||||||
|
)
|
||||||
|
|
||||||
|
// FlashData is a tools to maintain data when using across request.
|
||||||
|
type FlashData web.FlashData
|
||||||
|
|
||||||
|
// NewFlash return a new empty FlashData struct.
|
||||||
|
func NewFlash() *FlashData {
|
||||||
|
return (*FlashData)(web.NewFlash())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set message to flash
|
||||||
|
func (fd *FlashData) Set(key string, msg string, args ...interface{}) {
|
||||||
|
(*web.FlashData)(fd).Set(key, msg, args)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Success writes success message to flash.
|
||||||
|
func (fd *FlashData) Success(msg string, args ...interface{}) {
|
||||||
|
(*web.FlashData)(fd).Success(msg, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notice writes notice message to flash.
|
||||||
|
func (fd *FlashData) Notice(msg string, args ...interface{}) {
|
||||||
|
(*web.FlashData)(fd).Notice(msg, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Warning writes warning message to flash.
|
||||||
|
func (fd *FlashData) Warning(msg string, args ...interface{}) {
|
||||||
|
(*web.FlashData)(fd).Warning(msg, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error writes error message to flash.
|
||||||
|
func (fd *FlashData) Error(msg string, args ...interface{}) {
|
||||||
|
(*web.FlashData)(fd).Error(msg, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store does the saving operation of flash data.
|
||||||
|
// the data are encoded and saved in cookie.
|
||||||
|
func (fd *FlashData) Store(c *Controller) {
|
||||||
|
(*web.FlashData)(fd).Store((*web.Controller)(c))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadFromRequest parsed flash data from encoded values in cookie.
|
||||||
|
func ReadFromRequest(c *Controller) *FlashData {
|
||||||
|
return (*FlashData)(web.ReadFromRequest((*web.Controller)(c)))
|
||||||
|
}
|
35
pkg/adapter/fs.go
Normal file
35
pkg/adapter/fs.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// 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 adapter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/astaxie/beego/pkg/server/web"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FileSystem web.FileSystem
|
||||||
|
|
||||||
|
func (d FileSystem) Open(name string) (http.File, error) {
|
||||||
|
return (web.FileSystem)(d).Open(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
func Walk(fs http.FileSystem, root string, walkFn filepath.WalkFunc) error {
|
||||||
|
return web.Walk(fs, root, walkFn)
|
||||||
|
}
|
129
pkg/adapter/log.go
Normal file
129
pkg/adapter/log.go
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
// Copyright 2014 beego Author. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// 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 adapter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/astaxie/beego/pkg/infrastructure/logs"
|
||||||
|
|
||||||
|
webLog "github.com/astaxie/beego/pkg/infrastructure/logs"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Log levels to control the logging output.
|
||||||
|
// Deprecated: use github.com/astaxie/beego/logs instead.
|
||||||
|
const (
|
||||||
|
LevelEmergency = webLog.LevelEmergency
|
||||||
|
LevelAlert = webLog.LevelAlert
|
||||||
|
LevelCritical = webLog.LevelCritical
|
||||||
|
LevelError = webLog.LevelError
|
||||||
|
LevelWarning = webLog.LevelWarning
|
||||||
|
LevelNotice = webLog.LevelNotice
|
||||||
|
LevelInformational = webLog.LevelInformational
|
||||||
|
LevelDebug = webLog.LevelDebug
|
||||||
|
)
|
||||||
|
|
||||||
|
// BeeLogger references the used application logger.
|
||||||
|
// Deprecated: use github.com/astaxie/beego/logs instead.
|
||||||
|
var BeeLogger = logs.GetBeeLogger()
|
||||||
|
|
||||||
|
// SetLevel sets the global log level used by the simple logger.
|
||||||
|
// Deprecated: use github.com/astaxie/beego/logs instead.
|
||||||
|
func SetLevel(l int) {
|
||||||
|
logs.SetLevel(l)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetLogFuncCall set the CallDepth, default is 3
|
||||||
|
// Deprecated: use github.com/astaxie/beego/logs instead.
|
||||||
|
func SetLogFuncCall(b bool) {
|
||||||
|
logs.SetLogFuncCall(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetLogger sets a new logger.
|
||||||
|
// Deprecated: use github.com/astaxie/beego/logs instead.
|
||||||
|
func SetLogger(adaptername string, config string) error {
|
||||||
|
return logs.SetLogger(adaptername, config)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Emergency logs a message at emergency level.
|
||||||
|
// Deprecated: use github.com/astaxie/beego/logs instead.
|
||||||
|
func Emergency(v ...interface{}) {
|
||||||
|
logs.Emergency(generateFmtStr(len(v)), v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Alert logs a message at alert level.
|
||||||
|
// Deprecated: use github.com/astaxie/beego/logs instead.
|
||||||
|
func Alert(v ...interface{}) {
|
||||||
|
logs.Alert(generateFmtStr(len(v)), v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Critical logs a message at critical level.
|
||||||
|
// Deprecated: use github.com/astaxie/beego/logs instead.
|
||||||
|
func Critical(v ...interface{}) {
|
||||||
|
logs.Critical(generateFmtStr(len(v)), v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error logs a message at error level.
|
||||||
|
// Deprecated: use github.com/astaxie/beego/logs instead.
|
||||||
|
func Error(v ...interface{}) {
|
||||||
|
logs.Error(generateFmtStr(len(v)), v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Warning logs a message at warning level.
|
||||||
|
// Deprecated: use github.com/astaxie/beego/logs instead.
|
||||||
|
func Warning(v ...interface{}) {
|
||||||
|
logs.Warning(generateFmtStr(len(v)), v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Warn compatibility alias for Warning()
|
||||||
|
// Deprecated: use github.com/astaxie/beego/logs instead.
|
||||||
|
func Warn(v ...interface{}) {
|
||||||
|
logs.Warn(generateFmtStr(len(v)), v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notice logs a message at notice level.
|
||||||
|
// Deprecated: use github.com/astaxie/beego/logs instead.
|
||||||
|
func Notice(v ...interface{}) {
|
||||||
|
logs.Notice(generateFmtStr(len(v)), v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Informational logs a message at info level.
|
||||||
|
// Deprecated: use github.com/astaxie/beego/logs instead.
|
||||||
|
func Informational(v ...interface{}) {
|
||||||
|
logs.Informational(generateFmtStr(len(v)), v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Info compatibility alias for Warning()
|
||||||
|
// Deprecated: use github.com/astaxie/beego/logs instead.
|
||||||
|
func Info(v ...interface{}) {
|
||||||
|
logs.Info(generateFmtStr(len(v)), v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Debug logs a message at debug level.
|
||||||
|
// Deprecated: use github.com/astaxie/beego/logs instead.
|
||||||
|
func Debug(v ...interface{}) {
|
||||||
|
logs.Debug(generateFmtStr(len(v)), v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trace logs a message at trace level.
|
||||||
|
// compatibility alias for Warning()
|
||||||
|
// Deprecated: use github.com/astaxie/beego/logs instead.
|
||||||
|
func Trace(v ...interface{}) {
|
||||||
|
logs.Trace(generateFmtStr(len(v)), v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateFmtStr(n int) string {
|
||||||
|
return strings.Repeat("%v ", n)
|
||||||
|
}
|
378
pkg/adapter/namespace.go
Normal file
378
pkg/adapter/namespace.go
Normal file
@ -0,0 +1,378 @@
|
|||||||
|
// Copyright 2014 beego Author. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// 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 adapter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
adtContext "github.com/astaxie/beego/pkg/adapter/context"
|
||||||
|
"github.com/astaxie/beego/pkg/server/web/context"
|
||||||
|
|
||||||
|
"github.com/astaxie/beego/pkg/server/web"
|
||||||
|
)
|
||||||
|
|
||||||
|
type namespaceCond func(*adtContext.Context) bool
|
||||||
|
|
||||||
|
// LinkNamespace used as link action
|
||||||
|
type LinkNamespace func(*Namespace)
|
||||||
|
|
||||||
|
// Namespace is store all the info
|
||||||
|
type Namespace web.Namespace
|
||||||
|
|
||||||
|
// NewNamespace get new Namespace
|
||||||
|
func NewNamespace(prefix string, params ...LinkNamespace) *Namespace {
|
||||||
|
nps := oldToNewLinkNs(params)
|
||||||
|
return (*Namespace)(web.NewNamespace(prefix, nps...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func oldToNewLinkNs(params []LinkNamespace) []web.LinkNamespace {
|
||||||
|
nps := make([]web.LinkNamespace, 0, len(params))
|
||||||
|
for _, p := range params {
|
||||||
|
nps = append(nps, func(namespace *web.Namespace) {
|
||||||
|
p((*Namespace)(namespace))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return nps
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cond set condition function
|
||||||
|
// if cond return true can run this namespace, else can't
|
||||||
|
// usage:
|
||||||
|
// ns.Cond(func (ctx *context.Context) bool{
|
||||||
|
// if ctx.Input.Domain() == "api.beego.me" {
|
||||||
|
// return true
|
||||||
|
// }
|
||||||
|
// return false
|
||||||
|
// })
|
||||||
|
// Cond as the first filter
|
||||||
|
func (n *Namespace) Cond(cond namespaceCond) *Namespace {
|
||||||
|
(*web.Namespace)(n).Cond(func(context *context.Context) bool {
|
||||||
|
return cond((*adtContext.Context)(context))
|
||||||
|
})
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter add filter in the Namespace
|
||||||
|
// action has before & after
|
||||||
|
// FilterFunc
|
||||||
|
// usage:
|
||||||
|
// Filter("before", func (ctx *context.Context){
|
||||||
|
// _, ok := ctx.Input.Session("uid").(int)
|
||||||
|
// if !ok && ctx.Request.RequestURI != "/login" {
|
||||||
|
// ctx.Redirect(302, "/login")
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
func (n *Namespace) Filter(action string, filter ...FilterFunc) *Namespace {
|
||||||
|
nfs := oldToNewFilter(filter)
|
||||||
|
(*web.Namespace)(n).Filter(action, nfs...)
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
func oldToNewFilter(filter []FilterFunc) []web.FilterFunc {
|
||||||
|
nfs := make([]web.FilterFunc, 0, len(filter))
|
||||||
|
for _, f := range filter {
|
||||||
|
nfs = append(nfs, func(ctx *context.Context) {
|
||||||
|
f((*adtContext.Context)(ctx))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return nfs
|
||||||
|
}
|
||||||
|
|
||||||
|
// Router same as beego.Rourer
|
||||||
|
// refer: https://godoc.org/github.com/astaxie/beego#Router
|
||||||
|
func (n *Namespace) Router(rootpath string, c ControllerInterface, mappingMethods ...string) *Namespace {
|
||||||
|
(*web.Namespace)(n).Router(rootpath, c, mappingMethods...)
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
// AutoRouter same as beego.AutoRouter
|
||||||
|
// refer: https://godoc.org/github.com/astaxie/beego#AutoRouter
|
||||||
|
func (n *Namespace) AutoRouter(c ControllerInterface) *Namespace {
|
||||||
|
(*web.Namespace)(n).AutoRouter(c)
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
// AutoPrefix same as beego.AutoPrefix
|
||||||
|
// refer: https://godoc.org/github.com/astaxie/beego#AutoPrefix
|
||||||
|
func (n *Namespace) AutoPrefix(prefix string, c ControllerInterface) *Namespace {
|
||||||
|
(*web.Namespace)(n).AutoPrefix(prefix, c)
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get same as beego.Get
|
||||||
|
// refer: https://godoc.org/github.com/astaxie/beego#Get
|
||||||
|
func (n *Namespace) Get(rootpath string, f FilterFunc) *Namespace {
|
||||||
|
(*web.Namespace)(n).Get(rootpath, func(ctx *context.Context) {
|
||||||
|
f((*adtContext.Context)(ctx))
|
||||||
|
})
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
// Post same as beego.Post
|
||||||
|
// refer: https://godoc.org/github.com/astaxie/beego#Post
|
||||||
|
func (n *Namespace) Post(rootpath string, f FilterFunc) *Namespace {
|
||||||
|
(*web.Namespace)(n).Post(rootpath, func(ctx *context.Context) {
|
||||||
|
f((*adtContext.Context)(ctx))
|
||||||
|
})
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete same as beego.Delete
|
||||||
|
// refer: https://godoc.org/github.com/astaxie/beego#Delete
|
||||||
|
func (n *Namespace) Delete(rootpath string, f FilterFunc) *Namespace {
|
||||||
|
(*web.Namespace)(n).Delete(rootpath, func(ctx *context.Context) {
|
||||||
|
f((*adtContext.Context)(ctx))
|
||||||
|
})
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put same as beego.Put
|
||||||
|
// refer: https://godoc.org/github.com/astaxie/beego#Put
|
||||||
|
func (n *Namespace) Put(rootpath string, f FilterFunc) *Namespace {
|
||||||
|
(*web.Namespace)(n).Put(rootpath, func(ctx *context.Context) {
|
||||||
|
f((*adtContext.Context)(ctx))
|
||||||
|
})
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
// Head same as beego.Head
|
||||||
|
// refer: https://godoc.org/github.com/astaxie/beego#Head
|
||||||
|
func (n *Namespace) Head(rootpath string, f FilterFunc) *Namespace {
|
||||||
|
(*web.Namespace)(n).Head(rootpath, func(ctx *context.Context) {
|
||||||
|
f((*adtContext.Context)(ctx))
|
||||||
|
})
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
// Options same as beego.Options
|
||||||
|
// refer: https://godoc.org/github.com/astaxie/beego#Options
|
||||||
|
func (n *Namespace) Options(rootpath string, f FilterFunc) *Namespace {
|
||||||
|
(*web.Namespace)(n).Options(rootpath, func(ctx *context.Context) {
|
||||||
|
f((*adtContext.Context)(ctx))
|
||||||
|
})
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
// Patch same as beego.Patch
|
||||||
|
// refer: https://godoc.org/github.com/astaxie/beego#Patch
|
||||||
|
func (n *Namespace) Patch(rootpath string, f FilterFunc) *Namespace {
|
||||||
|
(*web.Namespace)(n).Patch(rootpath, func(ctx *context.Context) {
|
||||||
|
f((*adtContext.Context)(ctx))
|
||||||
|
})
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
// Any same as beego.Any
|
||||||
|
// refer: https://godoc.org/github.com/astaxie/beego#Any
|
||||||
|
func (n *Namespace) Any(rootpath string, f FilterFunc) *Namespace {
|
||||||
|
(*web.Namespace)(n).Any(rootpath, func(ctx *context.Context) {
|
||||||
|
f((*adtContext.Context)(ctx))
|
||||||
|
})
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handler same as beego.Handler
|
||||||
|
// refer: https://godoc.org/github.com/astaxie/beego#Handler
|
||||||
|
func (n *Namespace) Handler(rootpath string, h http.Handler) *Namespace {
|
||||||
|
(*web.Namespace)(n).Handler(rootpath, h)
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
// Include add include class
|
||||||
|
// refer: https://godoc.org/github.com/astaxie/beego#Include
|
||||||
|
func (n *Namespace) Include(cList ...ControllerInterface) *Namespace {
|
||||||
|
nL := oldToNewCtrlIntfs(cList)
|
||||||
|
(*web.Namespace)(n).Include(nL...)
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
// Namespace add nest Namespace
|
||||||
|
// usage:
|
||||||
|
// ns := beego.NewNamespace(“/v1”).
|
||||||
|
// Namespace(
|
||||||
|
// beego.NewNamespace("/shop").
|
||||||
|
// Get("/:id", func(ctx *context.Context) {
|
||||||
|
// ctx.Output.Body([]byte("shopinfo"))
|
||||||
|
// }),
|
||||||
|
// beego.NewNamespace("/order").
|
||||||
|
// Get("/:id", func(ctx *context.Context) {
|
||||||
|
// ctx.Output.Body([]byte("orderinfo"))
|
||||||
|
// }),
|
||||||
|
// beego.NewNamespace("/crm").
|
||||||
|
// Get("/:id", func(ctx *context.Context) {
|
||||||
|
// ctx.Output.Body([]byte("crminfo"))
|
||||||
|
// }),
|
||||||
|
// )
|
||||||
|
func (n *Namespace) Namespace(ns ...*Namespace) *Namespace {
|
||||||
|
nns := oldToNewNs(ns)
|
||||||
|
(*web.Namespace)(n).Namespace(nns...)
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
func oldToNewNs(ns []*Namespace) []*web.Namespace {
|
||||||
|
nns := make([]*web.Namespace, 0, len(ns))
|
||||||
|
for _, n := range ns {
|
||||||
|
nns = append(nns, (*web.Namespace)(n))
|
||||||
|
}
|
||||||
|
return nns
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddNamespace register Namespace into beego.Handler
|
||||||
|
// support multi Namespace
|
||||||
|
func AddNamespace(nl ...*Namespace) {
|
||||||
|
nnl := oldToNewNs(nl)
|
||||||
|
web.AddNamespace(nnl...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NSCond is Namespace Condition
|
||||||
|
func NSCond(cond namespaceCond) LinkNamespace {
|
||||||
|
return func(namespace *Namespace) {
|
||||||
|
web.NSCond(func(b *context.Context) bool {
|
||||||
|
return cond((*adtContext.Context)(b))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NSBefore Namespace BeforeRouter filter
|
||||||
|
func NSBefore(filterList ...FilterFunc) LinkNamespace {
|
||||||
|
return func(namespace *Namespace) {
|
||||||
|
nfs := oldToNewFilter(filterList)
|
||||||
|
web.NSBefore(nfs...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NSAfter add Namespace FinishRouter filter
|
||||||
|
func NSAfter(filterList ...FilterFunc) LinkNamespace {
|
||||||
|
return func(namespace *Namespace) {
|
||||||
|
nfs := oldToNewFilter(filterList)
|
||||||
|
web.NSAfter(nfs...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NSInclude Namespace Include ControllerInterface
|
||||||
|
func NSInclude(cList ...ControllerInterface) LinkNamespace {
|
||||||
|
return func(namespace *Namespace) {
|
||||||
|
nfs := oldToNewCtrlIntfs(cList)
|
||||||
|
web.NSInclude(nfs...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NSRouter call Namespace Router
|
||||||
|
func NSRouter(rootpath string, c ControllerInterface, mappingMethods ...string) LinkNamespace {
|
||||||
|
return func(namespace *Namespace) {
|
||||||
|
web.Router(rootpath, c, mappingMethods...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NSGet call Namespace Get
|
||||||
|
func NSGet(rootpath string, f FilterFunc) LinkNamespace {
|
||||||
|
return func(ns *Namespace) {
|
||||||
|
web.NSGet(rootpath, func(ctx *context.Context) {
|
||||||
|
f((*adtContext.Context)(ctx))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NSPost call Namespace Post
|
||||||
|
func NSPost(rootpath string, f FilterFunc) LinkNamespace {
|
||||||
|
return func(ns *Namespace) {
|
||||||
|
web.Post(rootpath, func(ctx *context.Context) {
|
||||||
|
f((*adtContext.Context)(ctx))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NSHead call Namespace Head
|
||||||
|
func NSHead(rootpath string, f FilterFunc) LinkNamespace {
|
||||||
|
return func(ns *Namespace) {
|
||||||
|
web.NSHead(rootpath, func(ctx *context.Context) {
|
||||||
|
f((*adtContext.Context)(ctx))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NSPut call Namespace Put
|
||||||
|
func NSPut(rootpath string, f FilterFunc) LinkNamespace {
|
||||||
|
return func(ns *Namespace) {
|
||||||
|
web.NSPut(rootpath, func(ctx *context.Context) {
|
||||||
|
f((*adtContext.Context)(ctx))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NSDelete call Namespace Delete
|
||||||
|
func NSDelete(rootpath string, f FilterFunc) LinkNamespace {
|
||||||
|
return func(ns *Namespace) {
|
||||||
|
web.NSDelete(rootpath, func(ctx *context.Context) {
|
||||||
|
f((*adtContext.Context)(ctx))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NSAny call Namespace Any
|
||||||
|
func NSAny(rootpath string, f FilterFunc) LinkNamespace {
|
||||||
|
return func(ns *Namespace) {
|
||||||
|
web.NSAny(rootpath, func(ctx *context.Context) {
|
||||||
|
f((*adtContext.Context)(ctx))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NSOptions call Namespace Options
|
||||||
|
func NSOptions(rootpath string, f FilterFunc) LinkNamespace {
|
||||||
|
return func(ns *Namespace) {
|
||||||
|
web.NSOptions(rootpath, func(ctx *context.Context) {
|
||||||
|
f((*adtContext.Context)(ctx))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NSPatch call Namespace Patch
|
||||||
|
func NSPatch(rootpath string, f FilterFunc) LinkNamespace {
|
||||||
|
return func(ns *Namespace) {
|
||||||
|
web.NSPatch(rootpath, func(ctx *context.Context) {
|
||||||
|
f((*adtContext.Context)(ctx))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NSAutoRouter call Namespace AutoRouter
|
||||||
|
func NSAutoRouter(c ControllerInterface) LinkNamespace {
|
||||||
|
return func(ns *Namespace) {
|
||||||
|
web.NSAutoRouter(c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NSAutoPrefix call Namespace AutoPrefix
|
||||||
|
func NSAutoPrefix(prefix string, c ControllerInterface) LinkNamespace {
|
||||||
|
return func(ns *Namespace) {
|
||||||
|
web.NSAutoPrefix(prefix, c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NSNamespace add sub Namespace
|
||||||
|
func NSNamespace(prefix string, params ...LinkNamespace) LinkNamespace {
|
||||||
|
return func(ns *Namespace) {
|
||||||
|
nps := oldToNewLinkNs(params)
|
||||||
|
web.NSNamespace(prefix, nps...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NSHandler add handler
|
||||||
|
func NSHandler(rootpath string, h http.Handler) LinkNamespace {
|
||||||
|
return func(ns *Namespace) {
|
||||||
|
web.NSHandler(rootpath, h)
|
||||||
|
}
|
||||||
|
}
|
57
pkg/adapter/policy.go
Normal file
57
pkg/adapter/policy.go
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
// Copyright 2016 beego authors. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// 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 adapter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/astaxie/beego/pkg/adapter/context"
|
||||||
|
"github.com/astaxie/beego/pkg/server/web"
|
||||||
|
beecontext "github.com/astaxie/beego/pkg/server/web/context"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PolicyFunc defines a policy function which is invoked before the controller handler is executed.
|
||||||
|
type PolicyFunc func(*context.Context)
|
||||||
|
|
||||||
|
// FindPolicy Find Router info for URL
|
||||||
|
func (p *ControllerRegister) FindPolicy(cont *context.Context) []PolicyFunc {
|
||||||
|
pf := (*web.ControllerRegister)(p).FindPolicy((*beecontext.Context)(cont))
|
||||||
|
npf := newToOldPolicyFunc(pf)
|
||||||
|
return npf
|
||||||
|
}
|
||||||
|
|
||||||
|
func newToOldPolicyFunc(pf []web.PolicyFunc) []PolicyFunc {
|
||||||
|
npf := make([]PolicyFunc, 0, len(pf))
|
||||||
|
for _, f := range pf {
|
||||||
|
npf = append(npf, func(c *context.Context) {
|
||||||
|
f((*beecontext.Context)(c))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return npf
|
||||||
|
}
|
||||||
|
|
||||||
|
func oldToNewPolicyFunc(pf []PolicyFunc) []web.PolicyFunc {
|
||||||
|
npf := make([]web.PolicyFunc, 0, len(pf))
|
||||||
|
for _, f := range pf {
|
||||||
|
npf = append(npf, func(c *beecontext.Context) {
|
||||||
|
f((*context.Context)(c))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return npf
|
||||||
|
}
|
||||||
|
|
||||||
|
// Policy Register new policy in beego
|
||||||
|
func Policy(pattern, method string, policy ...PolicyFunc) {
|
||||||
|
pf := oldToNewPolicyFunc(policy)
|
||||||
|
web.Policy(pattern, method, pf...)
|
||||||
|
}
|
279
pkg/adapter/router.go
Normal file
279
pkg/adapter/router.go
Normal file
@ -0,0 +1,279 @@
|
|||||||
|
// Copyright 2014 beego Author. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// 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 adapter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
beecontext "github.com/astaxie/beego/pkg/adapter/context"
|
||||||
|
"github.com/astaxie/beego/pkg/server/web/context"
|
||||||
|
|
||||||
|
"github.com/astaxie/beego/pkg/server/web"
|
||||||
|
)
|
||||||
|
|
||||||
|
// default filter execution points
|
||||||
|
const (
|
||||||
|
BeforeStatic = web.BeforeStatic
|
||||||
|
BeforeRouter = web.BeforeRouter
|
||||||
|
BeforeExec = web.BeforeExec
|
||||||
|
AfterExec = web.AfterExec
|
||||||
|
FinishRouter = web.FinishRouter
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// HTTPMETHOD list the supported http methods.
|
||||||
|
HTTPMETHOD = web.HTTPMETHOD
|
||||||
|
|
||||||
|
// DefaultAccessLogFilter will skip the accesslog if return true
|
||||||
|
DefaultAccessLogFilter FilterHandler = &newToOldFtHdlAdapter{
|
||||||
|
delegate: web.DefaultAccessLogFilter,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// FilterHandler is an interface for
|
||||||
|
type FilterHandler interface {
|
||||||
|
Filter(*beecontext.Context) bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type newToOldFtHdlAdapter struct {
|
||||||
|
delegate web.FilterHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *newToOldFtHdlAdapter) Filter(ctx *beecontext.Context) bool {
|
||||||
|
return n.delegate.Filter((*context.Context)(ctx))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExceptMethodAppend to append a slice's value into "exceptMethod", for controller's methods shouldn't reflect to AutoRouter
|
||||||
|
func ExceptMethodAppend(action string) {
|
||||||
|
web.ExceptMethodAppend(action)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ControllerInfo holds information about the controller.
|
||||||
|
type ControllerInfo web.ControllerInfo
|
||||||
|
|
||||||
|
func (c *ControllerInfo) GetPattern() string {
|
||||||
|
return (*web.ControllerInfo)(c).GetPattern()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ControllerRegister containers registered router rules, controller handlers and filters.
|
||||||
|
type ControllerRegister web.ControllerRegister
|
||||||
|
|
||||||
|
// NewControllerRegister returns a new ControllerRegister.
|
||||||
|
func NewControllerRegister() *ControllerRegister {
|
||||||
|
return (*ControllerRegister)(web.NewControllerRegister())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add controller handler and pattern rules to ControllerRegister.
|
||||||
|
// usage:
|
||||||
|
// default methods is the same name as method
|
||||||
|
// Add("/user",&UserController{})
|
||||||
|
// Add("/api/list",&RestController{},"*:ListFood")
|
||||||
|
// Add("/api/create",&RestController{},"post:CreateFood")
|
||||||
|
// Add("/api/update",&RestController{},"put:UpdateFood")
|
||||||
|
// Add("/api/delete",&RestController{},"delete:DeleteFood")
|
||||||
|
// Add("/api",&RestController{},"get,post:ApiFunc"
|
||||||
|
// Add("/simple",&SimpleController{},"get:GetFunc;post:PostFunc")
|
||||||
|
func (p *ControllerRegister) Add(pattern string, c ControllerInterface, mappingMethods ...string) {
|
||||||
|
(*web.ControllerRegister)(p).Add(pattern, c, mappingMethods...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Include only when the Runmode is dev will generate router file in the router/auto.go from the controller
|
||||||
|
// Include(&BankAccount{}, &OrderController{},&RefundController{},&ReceiptController{})
|
||||||
|
func (p *ControllerRegister) Include(cList ...ControllerInterface) {
|
||||||
|
nls := oldToNewCtrlIntfs(cList)
|
||||||
|
(*web.ControllerRegister)(p).Include(nls...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetContext returns a context from pool, so usually you should remember to call Reset function to clean the context
|
||||||
|
// And don't forget to give back context to pool
|
||||||
|
// example:
|
||||||
|
// ctx := p.GetContext()
|
||||||
|
// ctx.Reset(w, q)
|
||||||
|
// defer p.GiveBackContext(ctx)
|
||||||
|
func (p *ControllerRegister) GetContext() *beecontext.Context {
|
||||||
|
return (*beecontext.Context)((*web.ControllerRegister)(p).GetContext())
|
||||||
|
}
|
||||||
|
|
||||||
|
// GiveBackContext put the ctx into pool so that it could be reuse
|
||||||
|
func (p *ControllerRegister) GiveBackContext(ctx *beecontext.Context) {
|
||||||
|
(*web.ControllerRegister)(p).GiveBackContext((*context.Context)(ctx))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get add get method
|
||||||
|
// usage:
|
||||||
|
// Get("/", func(ctx *context.Context){
|
||||||
|
// ctx.Output.Body("hello world")
|
||||||
|
// })
|
||||||
|
func (p *ControllerRegister) Get(pattern string, f FilterFunc) {
|
||||||
|
(*web.ControllerRegister)(p).Get(pattern, func(ctx *context.Context) {
|
||||||
|
f((*beecontext.Context)(ctx))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Post add post method
|
||||||
|
// usage:
|
||||||
|
// Post("/api", func(ctx *context.Context){
|
||||||
|
// ctx.Output.Body("hello world")
|
||||||
|
// })
|
||||||
|
func (p *ControllerRegister) Post(pattern string, f FilterFunc) {
|
||||||
|
(*web.ControllerRegister)(p).Post(pattern, func(ctx *context.Context) {
|
||||||
|
f((*beecontext.Context)(ctx))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put add put method
|
||||||
|
// usage:
|
||||||
|
// Put("/api/:id", func(ctx *context.Context){
|
||||||
|
// ctx.Output.Body("hello world")
|
||||||
|
// })
|
||||||
|
func (p *ControllerRegister) Put(pattern string, f FilterFunc) {
|
||||||
|
(*web.ControllerRegister)(p).Put(pattern, func(ctx *context.Context) {
|
||||||
|
f((*beecontext.Context)(ctx))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete add delete method
|
||||||
|
// usage:
|
||||||
|
// Delete("/api/:id", func(ctx *context.Context){
|
||||||
|
// ctx.Output.Body("hello world")
|
||||||
|
// })
|
||||||
|
func (p *ControllerRegister) Delete(pattern string, f FilterFunc) {
|
||||||
|
(*web.ControllerRegister)(p).Delete(pattern, func(ctx *context.Context) {
|
||||||
|
f((*beecontext.Context)(ctx))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Head add head method
|
||||||
|
// usage:
|
||||||
|
// Head("/api/:id", func(ctx *context.Context){
|
||||||
|
// ctx.Output.Body("hello world")
|
||||||
|
// })
|
||||||
|
func (p *ControllerRegister) Head(pattern string, f FilterFunc) {
|
||||||
|
(*web.ControllerRegister)(p).Head(pattern, func(ctx *context.Context) {
|
||||||
|
f((*beecontext.Context)(ctx))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Patch add patch method
|
||||||
|
// usage:
|
||||||
|
// Patch("/api/:id", func(ctx *context.Context){
|
||||||
|
// ctx.Output.Body("hello world")
|
||||||
|
// })
|
||||||
|
func (p *ControllerRegister) Patch(pattern string, f FilterFunc) {
|
||||||
|
(*web.ControllerRegister)(p).Patch(pattern, func(ctx *context.Context) {
|
||||||
|
f((*beecontext.Context)(ctx))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Options add options method
|
||||||
|
// usage:
|
||||||
|
// Options("/api/:id", func(ctx *context.Context){
|
||||||
|
// ctx.Output.Body("hello world")
|
||||||
|
// })
|
||||||
|
func (p *ControllerRegister) Options(pattern string, f FilterFunc) {
|
||||||
|
(*web.ControllerRegister)(p).Options(pattern, func(ctx *context.Context) {
|
||||||
|
f((*beecontext.Context)(ctx))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Any add all method
|
||||||
|
// usage:
|
||||||
|
// Any("/api/:id", func(ctx *context.Context){
|
||||||
|
// ctx.Output.Body("hello world")
|
||||||
|
// })
|
||||||
|
func (p *ControllerRegister) Any(pattern string, f FilterFunc) {
|
||||||
|
(*web.ControllerRegister)(p).Any(pattern, func(ctx *context.Context) {
|
||||||
|
f((*beecontext.Context)(ctx))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddMethod add http method router
|
||||||
|
// usage:
|
||||||
|
// AddMethod("get","/api/:id", func(ctx *context.Context){
|
||||||
|
// ctx.Output.Body("hello world")
|
||||||
|
// })
|
||||||
|
func (p *ControllerRegister) AddMethod(method, pattern string, f FilterFunc) {
|
||||||
|
(*web.ControllerRegister)(p).AddMethod(method, pattern, func(ctx *context.Context) {
|
||||||
|
f((*beecontext.Context)(ctx))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handler add user defined Handler
|
||||||
|
func (p *ControllerRegister) Handler(pattern string, h http.Handler, options ...interface{}) {
|
||||||
|
(*web.ControllerRegister)(p).Handler(pattern, h, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddAuto router to ControllerRegister.
|
||||||
|
// example beego.AddAuto(&MainContorlller{}),
|
||||||
|
// MainController has method List and Page.
|
||||||
|
// visit the url /main/list to execute List function
|
||||||
|
// /main/page to execute Page function.
|
||||||
|
func (p *ControllerRegister) AddAuto(c ControllerInterface) {
|
||||||
|
(*web.ControllerRegister)(p).AddAuto(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddAutoPrefix Add auto router to ControllerRegister with prefix.
|
||||||
|
// example beego.AddAutoPrefix("/admin",&MainContorlller{}),
|
||||||
|
// MainController has method List and Page.
|
||||||
|
// visit the url /admin/main/list to execute List function
|
||||||
|
// /admin/main/page to execute Page function.
|
||||||
|
func (p *ControllerRegister) AddAutoPrefix(prefix string, c ControllerInterface) {
|
||||||
|
(*web.ControllerRegister)(p).AddAutoPrefix(prefix, c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// InsertFilter Add a FilterFunc with pattern rule and action constant.
|
||||||
|
// 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 (p *ControllerRegister) InsertFilter(pattern string, pos int, filter FilterFunc, params ...bool) error {
|
||||||
|
opts := oldToNewFilterOpts(params)
|
||||||
|
return (*web.ControllerRegister)(p).InsertFilter(pattern, pos, func(ctx *context.Context) {
|
||||||
|
filter((*beecontext.Context)(ctx))
|
||||||
|
}, opts...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func oldToNewFilterOpts(params []bool) []web.FilterOpt {
|
||||||
|
opts := make([]web.FilterOpt, 0, 4)
|
||||||
|
if len(params) > 0 {
|
||||||
|
opts = append(opts, web.WithReturnOnOutput(params[0]))
|
||||||
|
}
|
||||||
|
if len(params) > 1 {
|
||||||
|
opts = append(opts, web.WithResetParams(params[1]))
|
||||||
|
}
|
||||||
|
return opts
|
||||||
|
}
|
||||||
|
|
||||||
|
// URLFor does another controller handler in this request function.
|
||||||
|
// it can access any controller method.
|
||||||
|
func (p *ControllerRegister) URLFor(endpoint string, values ...interface{}) string {
|
||||||
|
return (*web.ControllerRegister)(p).URLFor(endpoint, values...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implement http.Handler interface.
|
||||||
|
func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
||||||
|
(*web.ControllerRegister)(p).ServeHTTP(rw, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindRouter Find Router info for URL
|
||||||
|
func (p *ControllerRegister) FindRouter(ctx *beecontext.Context) (routerInfo *ControllerInfo, isFind bool) {
|
||||||
|
r, ok := (*web.ControllerRegister)(p).FindRouter((*context.Context)(ctx))
|
||||||
|
return (*ControllerInfo)(r), ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// LogAccess logging info HTTP Access
|
||||||
|
func LogAccess(ctx *beecontext.Context, startTime *time.Time, statusCode int) {
|
||||||
|
web.LogAccess((*context.Context)(ctx), startTime, statusCode)
|
||||||
|
}
|
108
pkg/adapter/template.go
Normal file
108
pkg/adapter/template.go
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
// Copyright 2014 beego Author. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// 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 adapter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"html/template"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/astaxie/beego/pkg/server/web"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ExecuteTemplate applies the template with name to the specified data object,
|
||||||
|
// writing the output to wr.
|
||||||
|
// A template will be executed safely in parallel.
|
||||||
|
func ExecuteTemplate(wr io.Writer, name string, data interface{}) error {
|
||||||
|
return web.ExecuteTemplate(wr, name, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
func ExecuteViewPathTemplate(wr io.Writer, name string, viewPath string, data interface{}) error {
|
||||||
|
return web.ExecuteViewPathTemplate(wr, name, viewPath, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddFuncMap let user to register a func in the template.
|
||||||
|
func AddFuncMap(key string, fn interface{}) error {
|
||||||
|
return web.AddFuncMap(key, fn)
|
||||||
|
}
|
||||||
|
|
||||||
|
type templatePreProcessor func(root, path string, funcs template.FuncMap) (*template.Template, error)
|
||||||
|
|
||||||
|
type templateFile struct {
|
||||||
|
root string
|
||||||
|
files map[string][]string
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasTemplateExt return this path contains supported template extension of beego or not.
|
||||||
|
func HasTemplateExt(paths string) bool {
|
||||||
|
return web.HasTemplateExt(paths)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddTemplateExt add new extension for template.
|
||||||
|
func AddTemplateExt(ext string) {
|
||||||
|
web.AddTemplateExt(ext)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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()
|
||||||
|
func AddViewPath(viewPath string) error {
|
||||||
|
return web.AddViewPath(viewPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BuildTemplate will build all template files in a directory.
|
||||||
|
// it makes beego can render any template file in view directory.
|
||||||
|
func BuildTemplate(dir string, files ...string) error {
|
||||||
|
return web.BuildTemplate(dir, files...)
|
||||||
|
}
|
||||||
|
|
||||||
|
type templateFSFunc func() http.FileSystem
|
||||||
|
|
||||||
|
func defaultFSFunc() http.FileSystem {
|
||||||
|
return FileSystem{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTemplateFSFunc set default filesystem function
|
||||||
|
func SetTemplateFSFunc(fnt templateFSFunc) {
|
||||||
|
web.SetTemplateFSFunc(func() http.FileSystem {
|
||||||
|
return fnt()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetViewsPath sets view directory path in beego application.
|
||||||
|
func SetViewsPath(path string) *App {
|
||||||
|
return (*App)(web.SetViewsPath(path))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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".
|
||||||
|
func SetStaticPath(url string, path string) *App {
|
||||||
|
return (*App)(web.SetStaticPath(url, path))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DelStaticPath removes the static folder setting in this url pattern in beego application.
|
||||||
|
func DelStaticPath(url string) *App {
|
||||||
|
return (*App)(web.DelStaticPath(url))
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddTemplateEngine add a new templatePreProcessor which support extension
|
||||||
|
func AddTemplateEngine(extension string, fn templatePreProcessor) *App {
|
||||||
|
return (*App)(web.AddTemplateEngine(extension, func(root, path string, funcs template.FuncMap) (*template.Template, error) {
|
||||||
|
return fn(root, path, funcs)
|
||||||
|
}))
|
||||||
|
}
|
151
pkg/adapter/templatefunc.go
Normal file
151
pkg/adapter/templatefunc.go
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
// Copyright 2014 beego Author. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// 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 adapter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"html/template"
|
||||||
|
"net/url"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/astaxie/beego/pkg/server/web"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
formatTime = "15:04:05"
|
||||||
|
formatDate = "2006-01-02"
|
||||||
|
formatDateTime = "2006-01-02 15:04:05"
|
||||||
|
formatDateTimeT = "2006-01-02T15:04:05"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Substr returns the substr from start to length.
|
||||||
|
func Substr(s string, start, length int) string {
|
||||||
|
return web.Substr(s, start, length)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HTML2str returns escaping text convert from html.
|
||||||
|
func HTML2str(html string) string {
|
||||||
|
return web.HTML2str(html)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DateFormat takes a time and a layout string and returns a string with the formatted date. Used by the template parser as "dateformat"
|
||||||
|
func DateFormat(t time.Time, layout string) (datestring string) {
|
||||||
|
return web.DateFormat(t, layout)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DateParse Parse Date use PHP time format.
|
||||||
|
func DateParse(dateString, format string) (time.Time, error) {
|
||||||
|
return web.DateParse(dateString, format)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Date takes a PHP like date func to Go's time format.
|
||||||
|
func Date(t time.Time, format string) string {
|
||||||
|
return web.Date(t, format)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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".
|
||||||
|
func Compare(a, b interface{}) (equal bool) {
|
||||||
|
return web.Compare(a, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CompareNot !Compare
|
||||||
|
func CompareNot(a, b interface{}) (equal bool) {
|
||||||
|
return web.CompareNot(a, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NotNil the same as CompareNot
|
||||||
|
func NotNil(a interface{}) (isNil bool) {
|
||||||
|
return web.NotNil(a)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetConfig get the Appconfig
|
||||||
|
func GetConfig(returnType, key string, defaultVal interface{}) (interface{}, error) {
|
||||||
|
return web.GetConfig(returnType, key, defaultVal)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Str2html Convert string to template.HTML type.
|
||||||
|
func Str2html(raw string) template.HTML {
|
||||||
|
return web.Str2html(raw)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Htmlquote returns quoted html string.
|
||||||
|
func Htmlquote(text string) string {
|
||||||
|
return web.Htmlquote(text)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Htmlunquote returns unquoted html string.
|
||||||
|
func Htmlunquote(text string) string {
|
||||||
|
return web.Htmlunquote(text)
|
||||||
|
}
|
||||||
|
|
||||||
|
// URLFor returns url string with another registered controller handler with params.
|
||||||
|
// usage:
|
||||||
|
//
|
||||||
|
// URLFor(".index")
|
||||||
|
// print URLFor("index")
|
||||||
|
// router /login
|
||||||
|
// print URLFor("login")
|
||||||
|
// print URLFor("login", "next","/"")
|
||||||
|
// router /profile/:username
|
||||||
|
// print UrlFor("profile", ":username","John Doe")
|
||||||
|
// result:
|
||||||
|
// /
|
||||||
|
// /login
|
||||||
|
// /login?next=/
|
||||||
|
// /user/John%20Doe
|
||||||
|
//
|
||||||
|
// more detail http://beego.me/docs/mvc/controller/urlbuilding.md
|
||||||
|
func URLFor(endpoint string, values ...interface{}) string {
|
||||||
|
return web.URLFor(endpoint, values...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AssetsJs returns script tag with src string.
|
||||||
|
func AssetsJs(text string) template.HTML {
|
||||||
|
return web.AssetsJs(text)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AssetsCSS returns stylesheet link tag with src string.
|
||||||
|
func AssetsCSS(text string) template.HTML {
|
||||||
|
|
||||||
|
text = "<link href=\"" + text + "\" rel=\"stylesheet\" />"
|
||||||
|
|
||||||
|
return template.HTML(text)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseForm will parse form values to struct via tag.
|
||||||
|
func ParseForm(form url.Values, obj interface{}) error {
|
||||||
|
return web.ParseForm(form, obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RenderForm will render object to form html.
|
||||||
|
// obj must be a struct pointer.
|
||||||
|
func RenderForm(obj interface{}) template.HTML {
|
||||||
|
return web.RenderForm(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MapGet getting value from map by keys
|
||||||
|
// usage:
|
||||||
|
// Data["m"] = M{
|
||||||
|
// "a": 1,
|
||||||
|
// "1": map[string]float64{
|
||||||
|
// "c": 4,
|
||||||
|
// },
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// {{ map_get m "a" }} // return 1
|
||||||
|
// {{ map_get m 1 "c" }} // return 4
|
||||||
|
func MapGet(arg1 interface{}, arg2 ...interface{}) (interface{}, error) {
|
||||||
|
return web.MapGet(arg1, arg2...)
|
||||||
|
}
|
304
pkg/adapter/templatefunc_test.go
Normal file
304
pkg/adapter/templatefunc_test.go
Normal file
@ -0,0 +1,304 @@
|
|||||||
|
// Copyright 2014 beego Author. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// 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 adapter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"html/template"
|
||||||
|
"net/url"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSubstr(t *testing.T) {
|
||||||
|
s := `012345`
|
||||||
|
if Substr(s, 0, 2) != "01" {
|
||||||
|
t.Error("should be equal")
|
||||||
|
}
|
||||||
|
if Substr(s, 0, 100) != "012345" {
|
||||||
|
t.Error("should be equal")
|
||||||
|
}
|
||||||
|
if Substr(s, 12, 100) != "012345" {
|
||||||
|
t.Error("should be equal")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHtml2str(t *testing.T) {
|
||||||
|
h := `<HTML><style></style><script>x<x</script></HTML><123> 123\n
|
||||||
|
|
||||||
|
|
||||||
|
\n`
|
||||||
|
if HTML2str(h) != "123\\n\n\\n" {
|
||||||
|
t.Error("should be equal")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDateFormat(t *testing.T) {
|
||||||
|
ts := "Mon, 01 Jul 2013 13:27:42 CST"
|
||||||
|
tt, _ := time.Parse(time.RFC1123, ts)
|
||||||
|
|
||||||
|
if ss := DateFormat(tt, "2006-01-02 15:04:05"); ss != "2013-07-01 13:27:42" {
|
||||||
|
t.Errorf("2013-07-01 13:27:42 does not equal %v", ss)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDate(t *testing.T) {
|
||||||
|
ts := "Mon, 01 Jul 2013 13:27:42 CST"
|
||||||
|
tt, _ := time.Parse(time.RFC1123, ts)
|
||||||
|
|
||||||
|
if ss := Date(tt, "Y-m-d H:i:s"); ss != "2013-07-01 13:27:42" {
|
||||||
|
t.Errorf("2013-07-01 13:27:42 does not equal %v", ss)
|
||||||
|
}
|
||||||
|
if ss := Date(tt, "y-n-j h:i:s A"); ss != "13-7-1 01:27:42 PM" {
|
||||||
|
t.Errorf("13-7-1 01:27:42 PM does not equal %v", ss)
|
||||||
|
}
|
||||||
|
if ss := Date(tt, "D, d M Y g:i:s a"); ss != "Mon, 01 Jul 2013 1:27:42 pm" {
|
||||||
|
t.Errorf("Mon, 01 Jul 2013 1:27:42 pm does not equal %v", ss)
|
||||||
|
}
|
||||||
|
if ss := Date(tt, "l, d F Y G:i:s"); ss != "Monday, 01 July 2013 13:27:42" {
|
||||||
|
t.Errorf("Monday, 01 July 2013 13:27:42 does not equal %v", ss)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCompareRelated(t *testing.T) {
|
||||||
|
if !Compare("abc", "abc") {
|
||||||
|
t.Error("should be equal")
|
||||||
|
}
|
||||||
|
if Compare("abc", "aBc") {
|
||||||
|
t.Error("should be not equal")
|
||||||
|
}
|
||||||
|
if !Compare("1", 1) {
|
||||||
|
t.Error("should be equal")
|
||||||
|
}
|
||||||
|
if CompareNot("abc", "abc") {
|
||||||
|
t.Error("should be equal")
|
||||||
|
}
|
||||||
|
if !CompareNot("abc", "aBc") {
|
||||||
|
t.Error("should be not equal")
|
||||||
|
}
|
||||||
|
if !NotNil("a string") {
|
||||||
|
t.Error("should not be nil")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHtmlquote(t *testing.T) {
|
||||||
|
h := `<' ”“&">`
|
||||||
|
s := `<' ”“&">`
|
||||||
|
if Htmlquote(s) != h {
|
||||||
|
t.Error("should be equal")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHtmlunquote(t *testing.T) {
|
||||||
|
h := `<' ”“&">`
|
||||||
|
s := `<' ”“&">`
|
||||||
|
if Htmlunquote(h) != s {
|
||||||
|
t.Error("should be equal")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseForm(t *testing.T) {
|
||||||
|
type ExtendInfo struct {
|
||||||
|
Hobby []string `form:"hobby"`
|
||||||
|
Memo string
|
||||||
|
}
|
||||||
|
|
||||||
|
type OtherInfo struct {
|
||||||
|
Organization string `form:"organization"`
|
||||||
|
Title string `form:"title"`
|
||||||
|
ExtendInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
type user struct {
|
||||||
|
ID int `form:"-"`
|
||||||
|
tag string `form:"tag"`
|
||||||
|
Name interface{} `form:"username"`
|
||||||
|
Age int `form:"age,text"`
|
||||||
|
Email string
|
||||||
|
Intro string `form:",textarea"`
|
||||||
|
StrBool bool `form:"strbool"`
|
||||||
|
Date time.Time `form:"date,2006-01-02"`
|
||||||
|
OtherInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
u := user{}
|
||||||
|
form := url.Values{
|
||||||
|
"ID": []string{"1"},
|
||||||
|
"-": []string{"1"},
|
||||||
|
"tag": []string{"no"},
|
||||||
|
"username": []string{"test"},
|
||||||
|
"age": []string{"40"},
|
||||||
|
"Email": []string{"test@gmail.com"},
|
||||||
|
"Intro": []string{"I am an engineer!"},
|
||||||
|
"strbool": []string{"yes"},
|
||||||
|
"date": []string{"2014-11-12"},
|
||||||
|
"organization": []string{"beego"},
|
||||||
|
"title": []string{"CXO"},
|
||||||
|
"hobby": []string{"", "Basketball", "Football"},
|
||||||
|
"memo": []string{"nothing"},
|
||||||
|
}
|
||||||
|
if err := ParseForm(form, u); err == nil {
|
||||||
|
t.Fatal("nothing will be changed")
|
||||||
|
}
|
||||||
|
if err := ParseForm(form, &u); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if u.ID != 0 {
|
||||||
|
t.Errorf("ID should equal 0 but got %v", u.ID)
|
||||||
|
}
|
||||||
|
if len(u.tag) != 0 {
|
||||||
|
t.Errorf("tag's length should equal 0 but got %v", len(u.tag))
|
||||||
|
}
|
||||||
|
if u.Name.(string) != "test" {
|
||||||
|
t.Errorf("Name should equal `test` but got `%v`", u.Name.(string))
|
||||||
|
}
|
||||||
|
if u.Age != 40 {
|
||||||
|
t.Errorf("Age should equal 40 but got %v", u.Age)
|
||||||
|
}
|
||||||
|
if u.Email != "test@gmail.com" {
|
||||||
|
t.Errorf("Email should equal `test@gmail.com` but got `%v`", u.Email)
|
||||||
|
}
|
||||||
|
if u.Intro != "I am an engineer!" {
|
||||||
|
t.Errorf("Intro should equal `I am an engineer!` but got `%v`", u.Intro)
|
||||||
|
}
|
||||||
|
if !u.StrBool {
|
||||||
|
t.Errorf("strboll should equal `true`, but got `%v`", u.StrBool)
|
||||||
|
}
|
||||||
|
y, m, d := u.Date.Date()
|
||||||
|
if y != 2014 || m.String() != "November" || d != 12 {
|
||||||
|
t.Errorf("Date should equal `2014-11-12`, but got `%v`", u.Date.String())
|
||||||
|
}
|
||||||
|
if u.Organization != "beego" {
|
||||||
|
t.Errorf("Organization should equal `beego`, but got `%v`", u.Organization)
|
||||||
|
}
|
||||||
|
if u.Title != "CXO" {
|
||||||
|
t.Errorf("Title should equal `CXO`, but got `%v`", u.Title)
|
||||||
|
}
|
||||||
|
if u.Hobby[0] != "" {
|
||||||
|
t.Errorf("Hobby should equal ``, but got `%v`", u.Hobby[0])
|
||||||
|
}
|
||||||
|
if u.Hobby[1] != "Basketball" {
|
||||||
|
t.Errorf("Hobby should equal `Basketball`, but got `%v`", u.Hobby[1])
|
||||||
|
}
|
||||||
|
if u.Hobby[2] != "Football" {
|
||||||
|
t.Errorf("Hobby should equal `Football`, but got `%v`", u.Hobby[2])
|
||||||
|
}
|
||||||
|
if len(u.Memo) != 0 {
|
||||||
|
t.Errorf("Memo's length should equal 0 but got %v", len(u.Memo))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRenderForm(t *testing.T) {
|
||||||
|
type user struct {
|
||||||
|
ID int `form:"-"`
|
||||||
|
Name interface{} `form:"username"`
|
||||||
|
Age int `form:"age,text,年龄:"`
|
||||||
|
Sex string
|
||||||
|
Email []string
|
||||||
|
Intro string `form:",textarea"`
|
||||||
|
Ignored string `form:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
u := user{Name: "test", Intro: "Some Text"}
|
||||||
|
output := RenderForm(u)
|
||||||
|
if output != template.HTML("") {
|
||||||
|
t.Errorf("output should be empty but got %v", output)
|
||||||
|
}
|
||||||
|
output = RenderForm(&u)
|
||||||
|
result := template.HTML(
|
||||||
|
`Name: <input name="username" type="text" value="test"></br>` +
|
||||||
|
`年龄:<input name="age" type="text" value="0"></br>` +
|
||||||
|
`Sex: <input name="Sex" type="text" value=""></br>` +
|
||||||
|
`Intro: <textarea name="Intro">Some Text</textarea>`)
|
||||||
|
if output != result {
|
||||||
|
t.Errorf("output should equal `%v` but got `%v`", result, output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMapGet(t *testing.T) {
|
||||||
|
// test one level map
|
||||||
|
m1 := map[string]int64{
|
||||||
|
"a": 1,
|
||||||
|
"1": 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
if res, err := MapGet(m1, "a"); err == nil {
|
||||||
|
if res.(int64) != 1 {
|
||||||
|
t.Errorf("Should return 1, but return %v", res)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
t.Errorf("Error happens %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if res, err := MapGet(m1, "1"); err == nil {
|
||||||
|
if res.(int64) != 2 {
|
||||||
|
t.Errorf("Should return 2, but return %v", res)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
t.Errorf("Error happens %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if res, err := MapGet(m1, 1); err == nil {
|
||||||
|
if res.(int64) != 2 {
|
||||||
|
t.Errorf("Should return 2, but return %v", res)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
t.Errorf("Error happens %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// test 2 level map
|
||||||
|
m2 := M{
|
||||||
|
"1": map[string]float64{
|
||||||
|
"2": 3.5,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if res, err := MapGet(m2, 1, 2); err == nil {
|
||||||
|
if res.(float64) != 3.5 {
|
||||||
|
t.Errorf("Should return 3.5, but return %v", res)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
t.Errorf("Error happens %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// test 5 level map
|
||||||
|
m5 := M{
|
||||||
|
"1": M{
|
||||||
|
"2": M{
|
||||||
|
"3": M{
|
||||||
|
"4": M{
|
||||||
|
"5": 1.2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if res, err := MapGet(m5, 1, 2, 3, 4, 5); err == nil {
|
||||||
|
if res.(float64) != 1.2 {
|
||||||
|
t.Errorf("Should return 1.2, but return %v", res)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
t.Errorf("Error happens %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// check whether element not exists in map
|
||||||
|
if res, err := MapGet(m5, 5, 4, 3, 2, 1); err == nil {
|
||||||
|
if res != nil {
|
||||||
|
t.Errorf("Should return nil, but return %v", res)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
t.Errorf("Error happens %v", err)
|
||||||
|
}
|
||||||
|
}
|
49
pkg/adapter/tree.go
Normal file
49
pkg/adapter/tree.go
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
// Copyright 2014 beego Author. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// 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 adapter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/astaxie/beego/pkg/adapter/context"
|
||||||
|
beecontext "github.com/astaxie/beego/pkg/server/web/context"
|
||||||
|
|
||||||
|
"github.com/astaxie/beego/pkg/server/web"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Tree has three elements: FixRouter/wildcard/leaves
|
||||||
|
// fixRouter stores Fixed Router
|
||||||
|
// wildcard stores params
|
||||||
|
// leaves store the endpoint information
|
||||||
|
type Tree web.Tree
|
||||||
|
|
||||||
|
// NewTree return a new Tree
|
||||||
|
func NewTree() *Tree {
|
||||||
|
return (*Tree)(web.NewTree())
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddTree will add tree to the exist Tree
|
||||||
|
// prefix should has no params
|
||||||
|
func (t *Tree) AddTree(prefix string, tree *Tree) {
|
||||||
|
(*web.Tree)(t).AddTree(prefix, (*web.Tree)(tree))
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddRouter call addseg function
|
||||||
|
func (t *Tree) AddRouter(pattern string, runObject interface{}) {
|
||||||
|
(*web.Tree)(t).AddRouter(pattern, runObject)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Match router to runObject & params
|
||||||
|
func (t *Tree) Match(pattern string, ctx *context.Context) (runObject interface{}) {
|
||||||
|
return (*web.Tree)(t).Match(pattern, (*beecontext.Context)(ctx))
|
||||||
|
}
|
249
pkg/adapter/tree_test.go
Normal file
249
pkg/adapter/tree_test.go
Normal file
@ -0,0 +1,249 @@
|
|||||||
|
// Copyright 2014 beego Author. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// 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 adapter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/astaxie/beego/pkg/adapter/context"
|
||||||
|
beecontext "github.com/astaxie/beego/pkg/server/web/context"
|
||||||
|
)
|
||||||
|
|
||||||
|
type testinfo struct {
|
||||||
|
url string
|
||||||
|
requesturl string
|
||||||
|
params map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
var routers []testinfo
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
routers = make([]testinfo, 0)
|
||||||
|
routers = append(routers, testinfo{"/topic/?:auth:int", "/topic", nil})
|
||||||
|
routers = append(routers, testinfo{"/topic/?:auth:int", "/topic/123", map[string]string{":auth": "123"}})
|
||||||
|
routers = append(routers, testinfo{"/topic/:id/?:auth", "/topic/1", map[string]string{":id": "1"}})
|
||||||
|
routers = append(routers, testinfo{"/topic/:id/?:auth", "/topic/1/2", map[string]string{":id": "1", ":auth": "2"}})
|
||||||
|
routers = append(routers, testinfo{"/topic/:id/?:auth:int", "/topic/1", map[string]string{":id": "1"}})
|
||||||
|
routers = append(routers, testinfo{"/topic/:id/?:auth:int", "/topic/1/123", map[string]string{":id": "1", ":auth": "123"}})
|
||||||
|
routers = append(routers, testinfo{"/:id", "/123", map[string]string{":id": "123"}})
|
||||||
|
routers = append(routers, testinfo{"/hello/?:id", "/hello", map[string]string{":id": ""}})
|
||||||
|
routers = append(routers, testinfo{"/", "/", nil})
|
||||||
|
routers = append(routers, testinfo{"/customer/login", "/customer/login", nil})
|
||||||
|
routers = append(routers, testinfo{"/customer/login", "/customer/login.json", map[string]string{":ext": "json"}})
|
||||||
|
routers = append(routers, testinfo{"/*", "/http://customer/123/", map[string]string{":splat": "http://customer/123/"}})
|
||||||
|
routers = append(routers, testinfo{"/*", "/customer/2009/12/11", map[string]string{":splat": "customer/2009/12/11"}})
|
||||||
|
routers = append(routers, testinfo{"/aa/*/bb", "/aa/2009/bb", map[string]string{":splat": "2009"}})
|
||||||
|
routers = append(routers, testinfo{"/cc/*/dd", "/cc/2009/11/dd", map[string]string{":splat": "2009/11"}})
|
||||||
|
routers = append(routers, testinfo{"/cc/:id/*", "/cc/2009/11/dd", map[string]string{":id": "2009", ":splat": "11/dd"}})
|
||||||
|
routers = append(routers, testinfo{"/ee/:year/*/ff", "/ee/2009/11/ff", map[string]string{":year": "2009", ":splat": "11"}})
|
||||||
|
routers = append(routers, testinfo{"/thumbnail/:size/uploads/*",
|
||||||
|
"/thumbnail/100x100/uploads/items/2014/04/20/dPRCdChkUd651t1Hvs18.jpg",
|
||||||
|
map[string]string{":size": "100x100", ":splat": "items/2014/04/20/dPRCdChkUd651t1Hvs18.jpg"}})
|
||||||
|
routers = append(routers, testinfo{"/*.*", "/nice/api.json", map[string]string{":path": "nice/api", ":ext": "json"}})
|
||||||
|
routers = append(routers, testinfo{"/:name/*.*", "/nice/api.json", map[string]string{":name": "nice", ":path": "api", ":ext": "json"}})
|
||||||
|
routers = append(routers, testinfo{"/:name/test/*.*", "/nice/test/api.json", map[string]string{":name": "nice", ":path": "api", ":ext": "json"}})
|
||||||
|
routers = append(routers, testinfo{"/dl/:width:int/:height:int/*.*",
|
||||||
|
"/dl/48/48/05ac66d9bda00a3acf948c43e306fc9a.jpg",
|
||||||
|
map[string]string{":width": "48", ":height": "48", ":ext": "jpg", ":path": "05ac66d9bda00a3acf948c43e306fc9a"}})
|
||||||
|
routers = append(routers, testinfo{"/v1/shop/:id:int", "/v1/shop/123", map[string]string{":id": "123"}})
|
||||||
|
routers = append(routers, testinfo{"/v1/shop/:id\\((a|b|c)\\)", "/v1/shop/123(a)", map[string]string{":id": "123"}})
|
||||||
|
routers = append(routers, testinfo{"/v1/shop/:id\\((a|b|c)\\)", "/v1/shop/123(b)", map[string]string{":id": "123"}})
|
||||||
|
routers = append(routers, testinfo{"/v1/shop/:id\\((a|b|c)\\)", "/v1/shop/123(c)", map[string]string{":id": "123"}})
|
||||||
|
routers = append(routers, testinfo{"/:year:int/:month:int/:id/:endid", "/1111/111/aaa/aaa", map[string]string{":year": "1111", ":month": "111", ":id": "aaa", ":endid": "aaa"}})
|
||||||
|
routers = append(routers, testinfo{"/v1/shop/:id/:name", "/v1/shop/123/nike", map[string]string{":id": "123", ":name": "nike"}})
|
||||||
|
routers = append(routers, testinfo{"/v1/shop/:id/account", "/v1/shop/123/account", map[string]string{":id": "123"}})
|
||||||
|
routers = append(routers, testinfo{"/v1/shop/:name:string", "/v1/shop/nike", map[string]string{":name": "nike"}})
|
||||||
|
routers = append(routers, testinfo{"/v1/shop/:id([0-9]+)", "/v1/shop//123", map[string]string{":id": "123"}})
|
||||||
|
routers = append(routers, testinfo{"/v1/shop/:id([0-9]+)_:name", "/v1/shop/123_nike", map[string]string{":id": "123", ":name": "nike"}})
|
||||||
|
routers = append(routers, testinfo{"/v1/shop/:id(.+)_cms.html", "/v1/shop/123_cms.html", map[string]string{":id": "123"}})
|
||||||
|
routers = append(routers, testinfo{"/v1/shop/cms_:id(.+)_:page(.+).html", "/v1/shop/cms_123_1.html", map[string]string{":id": "123", ":page": "1"}})
|
||||||
|
routers = append(routers, testinfo{"/v1/:v/cms/aaa_:id(.+)_:page(.+).html", "/v1/2/cms/aaa_123_1.html", map[string]string{":v": "2", ":id": "123", ":page": "1"}})
|
||||||
|
routers = append(routers, testinfo{"/v1/:v/cms_:id(.+)_:page(.+).html", "/v1/2/cms_123_1.html", map[string]string{":v": "2", ":id": "123", ":page": "1"}})
|
||||||
|
routers = append(routers, testinfo{"/v1/:v(.+)_cms/ttt_:id(.+)_:page(.+).html", "/v1/2_cms/ttt_123_1.html", map[string]string{":v": "2", ":id": "123", ":page": "1"}})
|
||||||
|
routers = append(routers, testinfo{"/api/projects/:pid/members/?:mid", "/api/projects/1/members", map[string]string{":pid": "1"}})
|
||||||
|
routers = append(routers, testinfo{"/api/projects/:pid/members/?:mid", "/api/projects/1/members/2", map[string]string{":pid": "1", ":mid": "2"}})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTreeRouters(t *testing.T) {
|
||||||
|
for _, r := range routers {
|
||||||
|
tr := NewTree()
|
||||||
|
tr.AddRouter(r.url, "astaxie")
|
||||||
|
ctx := context.NewContext()
|
||||||
|
obj := tr.Match(r.requesturl, ctx)
|
||||||
|
if obj == nil || obj.(string) != "astaxie" {
|
||||||
|
t.Fatal(r.url+" can't get obj, Expect ", r.requesturl)
|
||||||
|
}
|
||||||
|
if r.params != nil {
|
||||||
|
for k, v := range r.params {
|
||||||
|
if vv := ctx.Input.Param(k); vv != v {
|
||||||
|
t.Fatal("The Rule: " + r.url + "\nThe RequestURL:" + r.requesturl + "\nThe Key is " + k + ", The Value should be: " + v + ", but get: " + vv)
|
||||||
|
} else if vv == "" && v != "" {
|
||||||
|
t.Fatal(r.url + " " + r.requesturl + " get param empty:" + k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStaticPath(t *testing.T) {
|
||||||
|
tr := NewTree()
|
||||||
|
tr.AddRouter("/topic/:id", "wildcard")
|
||||||
|
tr.AddRouter("/topic", "static")
|
||||||
|
ctx := context.NewContext()
|
||||||
|
obj := tr.Match("/topic", ctx)
|
||||||
|
if obj == nil || obj.(string) != "static" {
|
||||||
|
t.Fatal("/topic is a static route")
|
||||||
|
}
|
||||||
|
obj = tr.Match("/topic/1", ctx)
|
||||||
|
if obj == nil || obj.(string) != "wildcard" {
|
||||||
|
t.Fatal("/topic/1 is a wildcard route")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAddTree(t *testing.T) {
|
||||||
|
tr := NewTree()
|
||||||
|
tr.AddRouter("/shop/:id/account", "astaxie")
|
||||||
|
tr.AddRouter("/shop/:sd/ttt_:id(.+)_:page(.+).html", "astaxie")
|
||||||
|
t1 := NewTree()
|
||||||
|
t1.AddTree("/v1/zl", tr)
|
||||||
|
ctx := context.NewContext()
|
||||||
|
obj := t1.Match("/v1/zl/shop/123/account", ctx)
|
||||||
|
if obj == nil || obj.(string) != "astaxie" {
|
||||||
|
t.Fatal("/v1/zl/shop/:id/account can't get obj ")
|
||||||
|
}
|
||||||
|
if ctx.Input.ParamsLen() == 0 {
|
||||||
|
t.Fatal("get param error")
|
||||||
|
}
|
||||||
|
if ctx.Input.Param(":id") != "123" {
|
||||||
|
t.Fatal("get :id param error")
|
||||||
|
}
|
||||||
|
ctx.Input.Reset((*beecontext.Context)(ctx))
|
||||||
|
obj = t1.Match("/v1/zl/shop/123/ttt_1_12.html", ctx)
|
||||||
|
if obj == nil || obj.(string) != "astaxie" {
|
||||||
|
t.Fatal("/v1/zl//shop/:sd/ttt_:id(.+)_:page(.+).html can't get obj ")
|
||||||
|
}
|
||||||
|
if ctx.Input.ParamsLen() == 0 {
|
||||||
|
t.Fatal("get param error")
|
||||||
|
}
|
||||||
|
if ctx.Input.Param(":sd") != "123" || ctx.Input.Param(":id") != "1" || ctx.Input.Param(":page") != "12" {
|
||||||
|
t.Fatal("get :sd :id :page param error")
|
||||||
|
}
|
||||||
|
|
||||||
|
t2 := NewTree()
|
||||||
|
t2.AddTree("/v1/:shopid", tr)
|
||||||
|
ctx.Input.Reset((*beecontext.Context)(ctx))
|
||||||
|
obj = t2.Match("/v1/zl/shop/123/account", ctx)
|
||||||
|
if obj == nil || obj.(string) != "astaxie" {
|
||||||
|
t.Fatal("/v1/:shopid/shop/:id/account can't get obj ")
|
||||||
|
}
|
||||||
|
if ctx.Input.ParamsLen() == 0 {
|
||||||
|
t.Fatal("get param error")
|
||||||
|
}
|
||||||
|
if ctx.Input.Param(":id") != "123" || ctx.Input.Param(":shopid") != "zl" {
|
||||||
|
t.Fatal("get :id :shopid param error")
|
||||||
|
}
|
||||||
|
ctx.Input.Reset((*beecontext.Context)(ctx))
|
||||||
|
obj = t2.Match("/v1/zl/shop/123/ttt_1_12.html", ctx)
|
||||||
|
if obj == nil || obj.(string) != "astaxie" {
|
||||||
|
t.Fatal("/v1/:shopid/shop/:sd/ttt_:id(.+)_:page(.+).html can't get obj ")
|
||||||
|
}
|
||||||
|
if ctx.Input.ParamsLen() == 0 {
|
||||||
|
t.Fatal("get :shopid param error")
|
||||||
|
}
|
||||||
|
if ctx.Input.Param(":sd") != "123" || ctx.Input.Param(":id") != "1" || ctx.Input.Param(":page") != "12" || ctx.Input.Param(":shopid") != "zl" {
|
||||||
|
t.Fatal("get :sd :id :page :shopid param error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAddTree2(t *testing.T) {
|
||||||
|
tr := NewTree()
|
||||||
|
tr.AddRouter("/shop/:id/account", "astaxie")
|
||||||
|
tr.AddRouter("/shop/:sd/ttt_:id(.+)_:page(.+).html", "astaxie")
|
||||||
|
t3 := NewTree()
|
||||||
|
t3.AddTree("/:version(v1|v2)/:prefix", tr)
|
||||||
|
ctx := context.NewContext()
|
||||||
|
obj := t3.Match("/v1/zl/shop/123/account", ctx)
|
||||||
|
if obj == nil || obj.(string) != "astaxie" {
|
||||||
|
t.Fatal("/:version(v1|v2)/:prefix/shop/:id/account can't get obj ")
|
||||||
|
}
|
||||||
|
if ctx.Input.ParamsLen() == 0 {
|
||||||
|
t.Fatal("get param error")
|
||||||
|
}
|
||||||
|
if ctx.Input.Param(":id") != "123" || ctx.Input.Param(":prefix") != "zl" || ctx.Input.Param(":version") != "v1" {
|
||||||
|
t.Fatal("get :id :prefix :version param error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAddTree3(t *testing.T) {
|
||||||
|
tr := NewTree()
|
||||||
|
tr.AddRouter("/create", "astaxie")
|
||||||
|
tr.AddRouter("/shop/:sd/account", "astaxie")
|
||||||
|
t3 := NewTree()
|
||||||
|
t3.AddTree("/table/:num", tr)
|
||||||
|
ctx := context.NewContext()
|
||||||
|
obj := t3.Match("/table/123/shop/123/account", ctx)
|
||||||
|
if obj == nil || obj.(string) != "astaxie" {
|
||||||
|
t.Fatal("/table/:num/shop/:sd/account can't get obj ")
|
||||||
|
}
|
||||||
|
if ctx.Input.ParamsLen() == 0 {
|
||||||
|
t.Fatal("get param error")
|
||||||
|
}
|
||||||
|
if ctx.Input.Param(":num") != "123" || ctx.Input.Param(":sd") != "123" {
|
||||||
|
t.Fatal("get :num :sd param error")
|
||||||
|
}
|
||||||
|
ctx.Input.Reset((*beecontext.Context)(ctx))
|
||||||
|
obj = t3.Match("/table/123/create", ctx)
|
||||||
|
if obj == nil || obj.(string) != "astaxie" {
|
||||||
|
t.Fatal("/table/:num/create can't get obj ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAddTree4(t *testing.T) {
|
||||||
|
tr := NewTree()
|
||||||
|
tr.AddRouter("/create", "astaxie")
|
||||||
|
tr.AddRouter("/shop/:sd/:account", "astaxie")
|
||||||
|
t4 := NewTree()
|
||||||
|
t4.AddTree("/:info:int/:num/:id", tr)
|
||||||
|
ctx := context.NewContext()
|
||||||
|
obj := t4.Match("/12/123/456/shop/123/account", ctx)
|
||||||
|
if obj == nil || obj.(string) != "astaxie" {
|
||||||
|
t.Fatal("/:info:int/:num/:id/shop/:sd/:account can't get obj ")
|
||||||
|
}
|
||||||
|
if ctx.Input.ParamsLen() == 0 {
|
||||||
|
t.Fatal("get param error")
|
||||||
|
}
|
||||||
|
if ctx.Input.Param(":info") != "12" || ctx.Input.Param(":num") != "123" ||
|
||||||
|
ctx.Input.Param(":id") != "456" || ctx.Input.Param(":sd") != "123" ||
|
||||||
|
ctx.Input.Param(":account") != "account" {
|
||||||
|
t.Fatal("get :info :num :id :sd :account param error")
|
||||||
|
}
|
||||||
|
ctx.Input.Reset((*beecontext.Context)(ctx))
|
||||||
|
obj = t4.Match("/12/123/456/create", ctx)
|
||||||
|
if obj == nil || obj.(string) != "astaxie" {
|
||||||
|
t.Fatal("/:info:int/:num/:id/create can't get obj ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test for issue #1595
|
||||||
|
func TestAddTree5(t *testing.T) {
|
||||||
|
tr := NewTree()
|
||||||
|
tr.AddRouter("/v1/shop/:id", "shopdetail")
|
||||||
|
tr.AddRouter("/v1/shop/", "shophome")
|
||||||
|
ctx := context.NewContext()
|
||||||
|
obj := tr.Match("/v1/shop/", ctx)
|
||||||
|
if obj == nil || obj.(string) != "shophome" {
|
||||||
|
t.Fatal("url /v1/shop/ need match router /v1/shop/ ")
|
||||||
|
}
|
||||||
|
}
|
@ -199,7 +199,7 @@ func (app *App) Run(mws ...MiddleWare) {
|
|||||||
pool.AppendCertsFromPEM(data)
|
pool.AppendCertsFromPEM(data)
|
||||||
app.Server.TLSConfig = &tls.Config{
|
app.Server.TLSConfig = &tls.Config{
|
||||||
ClientCAs: pool,
|
ClientCAs: pool,
|
||||||
ClientAuth: tls.RequireAndVerifyClientCert,
|
ClientAuth: tls.ClientAuthType(BConfig.Listen.ClientAuth),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := app.Server.ListenAndServeTLS(BConfig.Listen.HTTPSCertFile, BConfig.Listen.HTTPSKeyFile); err != nil {
|
if err := app.Server.ListenAndServeTLS(BConfig.Listen.HTTPSCertFile, BConfig.Listen.HTTPSKeyFile); err != nil {
|
||||||
|
@ -16,6 +16,7 @@ package web
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
context2 "context"
|
context2 "context"
|
||||||
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@ -72,6 +73,7 @@ type Listen struct {
|
|||||||
AdminPort int
|
AdminPort int
|
||||||
EnableFcgi bool
|
EnableFcgi bool
|
||||||
EnableStdIo bool // EnableStdIo works with EnableFcgi Use FCGI via standard I/O
|
EnableStdIo bool // EnableStdIo works with EnableFcgi Use FCGI via standard I/O
|
||||||
|
ClientAuth int
|
||||||
}
|
}
|
||||||
|
|
||||||
// WebConfig holds web related config
|
// WebConfig holds web related config
|
||||||
@ -234,6 +236,7 @@ func newBConfig() *Config {
|
|||||||
AdminPort: 8088,
|
AdminPort: 8088,
|
||||||
EnableFcgi: false,
|
EnableFcgi: false,
|
||||||
EnableStdIo: false,
|
EnableStdIo: false,
|
||||||
|
ClientAuth: int(tls.RequireAndVerifyClientCert),
|
||||||
},
|
},
|
||||||
WebConfig: WebConfig{
|
WebConfig: WebConfig{
|
||||||
AutoRender: true,
|
AutoRender: true,
|
||||||
|
@ -43,24 +43,26 @@ type FilterRouter struct {
|
|||||||
// params is for:
|
// params is for:
|
||||||
// 1. setting the returnOnOutput value (false allows multiple filters to execute)
|
// 1. setting the returnOnOutput value (false allows multiple filters to execute)
|
||||||
// 2. determining whether or not params need to be reset.
|
// 2. determining whether or not params need to be reset.
|
||||||
func newFilterRouter(pattern string, routerCaseSensitive bool, filter FilterFunc, params ...bool) *FilterRouter {
|
func newFilterRouter(pattern string, filter FilterFunc, opts ...FilterOpt) *FilterRouter {
|
||||||
mr := &FilterRouter{
|
mr := &FilterRouter{
|
||||||
tree: NewTree(),
|
tree: NewTree(),
|
||||||
pattern: pattern,
|
pattern: pattern,
|
||||||
filterFunc: filter,
|
filterFunc: filter,
|
||||||
returnOnOutput: true,
|
returnOnOutput: true,
|
||||||
}
|
}
|
||||||
if !routerCaseSensitive {
|
|
||||||
|
fos := &filterOpts{}
|
||||||
|
|
||||||
|
for _, o := range opts {
|
||||||
|
o(fos)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !fos.routerCaseSensitive {
|
||||||
mr.pattern = strings.ToLower(pattern)
|
mr.pattern = strings.ToLower(pattern)
|
||||||
}
|
}
|
||||||
|
|
||||||
paramsLen := len(params)
|
mr.returnOnOutput = fos.returnOnOutput
|
||||||
if paramsLen > 0 {
|
mr.resetParams = fos.resetParams
|
||||||
mr.returnOnOutput = params[0]
|
|
||||||
}
|
|
||||||
if paramsLen > 1 {
|
|
||||||
mr.resetParams = params[1]
|
|
||||||
}
|
|
||||||
mr.tree.AddRouter(pattern, true)
|
mr.tree.AddRouter(pattern, true)
|
||||||
return mr
|
return mr
|
||||||
}
|
}
|
||||||
@ -103,3 +105,29 @@ func (f *FilterRouter) ValidRouter(url string, ctx *context.Context) bool {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type filterOpts struct {
|
||||||
|
returnOnOutput bool
|
||||||
|
resetParams bool
|
||||||
|
routerCaseSensitive bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type FilterOpt func(opts *filterOpts)
|
||||||
|
|
||||||
|
func WithReturnOnOutput(ret bool) FilterOpt {
|
||||||
|
return func(opts *filterOpts) {
|
||||||
|
opts.returnOnOutput = ret
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithResetParams(reset bool) FilterOpt {
|
||||||
|
return func(opts *filterOpts) {
|
||||||
|
opts.resetParams = reset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithCaseSensitive(sensitive bool) FilterOpt {
|
||||||
|
return func(opts *filterOpts) {
|
||||||
|
opts.routerCaseSensitive = sensitive
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -148,7 +148,7 @@ func NewControllerRegister() *ControllerRegister {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
res.chainRoot = newFilterRouter("/*", false, res.serveHttp)
|
res.chainRoot = newFilterRouter("/*", res.serveHttp, WithCaseSensitive(false))
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,7 +262,7 @@ func (p *ControllerRegister) Include(cList ...ControllerInterface) {
|
|||||||
if comm, ok := GlobalControllerRouter[key]; ok {
|
if comm, ok := GlobalControllerRouter[key]; ok {
|
||||||
for _, a := range comm {
|
for _, a := range comm {
|
||||||
for _, f := range a.Filters {
|
for _, f := range a.Filters {
|
||||||
p.InsertFilter(f.Pattern, f.Pos, f.Filter, f.ReturnOnOutput, f.ResetParams)
|
p.InsertFilter(f.Pattern, f.Pos, f.Filter, WithReturnOnOutput(f.ReturnOnOutput), WithResetParams(f.ResetParams))
|
||||||
}
|
}
|
||||||
|
|
||||||
p.addWithMethodParams(a.Router, c, a.MethodParams, strings.Join(a.AllowHTTPMethods, ",")+":"+a.Method)
|
p.addWithMethodParams(a.Router, c, a.MethodParams, strings.Join(a.AllowHTTPMethods, ",")+":"+a.Method)
|
||||||
@ -452,8 +452,9 @@ func (p *ControllerRegister) AddAutoPrefix(prefix string, c ControllerInterface)
|
|||||||
// params is for:
|
// params is for:
|
||||||
// 1. setting the returnOnOutput value (false allows multiple filters to execute)
|
// 1. setting the returnOnOutput value (false allows multiple filters to execute)
|
||||||
// 2. determining whether or not params need to be reset.
|
// 2. determining whether or not params need to be reset.
|
||||||
func (p *ControllerRegister) InsertFilter(pattern string, pos int, filter FilterFunc, params ...bool) error {
|
func (p *ControllerRegister) InsertFilter(pattern string, pos int, filter FilterFunc, opts ...FilterOpt) error {
|
||||||
mr := newFilterRouter(pattern, BConfig.RouterCaseSensitive, filter, params...)
|
opts = append(opts, WithCaseSensitive(BConfig.RouterCaseSensitive))
|
||||||
|
mr := newFilterRouter(pattern, filter, opts...)
|
||||||
return p.insertFilterRouter(pos, mr)
|
return p.insertFilterRouter(pos, mr)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -468,10 +469,11 @@ func (p *ControllerRegister) InsertFilter(pattern string, pos int, filter Filter
|
|||||||
// // do something
|
// // do something
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
func (p *ControllerRegister) InsertFilterChain(pattern string, chain FilterChain, params ...bool) {
|
func (p *ControllerRegister) InsertFilterChain(pattern string, chain FilterChain, opts ...FilterOpt) {
|
||||||
root := p.chainRoot
|
root := p.chainRoot
|
||||||
filterFunc := chain(root.filterFunc)
|
filterFunc := chain(root.filterFunc)
|
||||||
p.chainRoot = newFilterRouter(pattern, BConfig.RouterCaseSensitive, filterFunc, params...)
|
opts = append(opts, WithCaseSensitive(BConfig.RouterCaseSensitive))
|
||||||
|
p.chainRoot = newFilterRouter(pattern, filterFunc, opts...)
|
||||||
p.chainRoot.next = root
|
p.chainRoot.next = root
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user