Commit d1bba029 authored by astaxie's avatar astaxie

refact beego config

parent 3d4ad560
......@@ -85,50 +85,11 @@ func listConf(rw http.ResponseWriter, r *http.Request) {
data := make(map[interface{}]interface{})
switch command {
case "conf":
m := make(map[string]interface{})
m["AppName"] = AppName
m["AppPath"] = AppPath
m["AppConfigPath"] = AppConfigPath
m["StaticDir"] = StaticDir
m["StaticExtensionsToGzip"] = StaticExtensionsToGzip
m["HTTPAddr"] = HTTPAddr
m["HTTPPort"] = HTTPPort
m["HTTPTLS"] = EnableHTTPTLS
m["HTTPCertFile"] = HTTPCertFile
m["HTTPKeyFile"] = HTTPKeyFile
m["RecoverPanic"] = RecoverPanic
m["AutoRender"] = AutoRender
m["ViewsPath"] = ViewsPath
m["RunMode"] = RunMode
m["SessionOn"] = SessionOn
m["SessionProvider"] = SessionProvider
m["SessionName"] = SessionName
m["SessionGCMaxLifetime"] = SessionGCMaxLifetime
m["SessionProviderConfig"] = SessionProviderConfig
m["SessionCookieLifeTime"] = SessionCookieLifeTime
m["EnableFcgi"] = EnableFcgi
m["MaxMemory"] = MaxMemory
m["EnableGzip"] = EnableGzip
m["DirectoryIndex"] = DirectoryIndex
m["HTTPServerTimeOut"] = HTTPServerTimeOut
m["EnableErrorsShow"] = EnableErrorsShow
m["XSRFKEY"] = XSRFKEY
m["EnableXSRF"] = EnableXSRF
m["XSRFExpire"] = XSRFExpire
m["CopyRequestBody"] = CopyRequestBody
m["TemplateLeft"] = TemplateLeft
m["TemplateRight"] = TemplateRight
m["BeegoServerName"] = BeegoServerName
m["EnableAdmin"] = EnableAdmin
m["AdminHTTPAddr"] = AdminHTTPAddr
m["AdminHTTPPort"] = AdminHTTPPort
tmpl := template.Must(template.New("dashboard").Parse(dashboardTpl))
tmpl = template.Must(tmpl.Parse(configTpl))
tmpl = template.Must(tmpl.Parse(defaultScriptsTpl))
data["Content"] = m
data["Content"] = BConfig
tmpl.Execute(rw, data)
......@@ -391,10 +352,10 @@ func (admin *adminApp) Run() {
if len(toolbox.AdminTaskList) > 0 {
toolbox.StartTask()
}
addr := AdminHTTPAddr
addr := BConfig.Listen.AdminAddr
if AdminHTTPPort != 0 {
addr = fmt.Sprintf("%s:%d", AdminHTTPAddr, AdminHTTPPort)
if BConfig.Listen.AdminPort != 0 {
addr = fmt.Sprintf("%s:%d", BConfig.Listen.AdminAddr, BConfig.Listen.AdminPort)
}
for p, f := range admin.routers {
http.Handle(p, f)
......@@ -402,7 +363,7 @@ func (admin *adminApp) Run() {
BeeLogger.Info("Admin server Running on %s", addr)
var err error
if Graceful {
if BConfig.Listen.Graceful {
err = grace.ListenAndServe(addr, nil)
} else {
err = http.ListenAndServe(addr, nil)
......
......@@ -52,10 +52,10 @@ func NewApp() *App {
// Run beego application.
func (app *App) Run() {
addr := HTTPAddr
addr := BConfig.Listen.HTTPAddr
if HTTPPort != 0 {
addr = fmt.Sprintf("%s:%d", HTTPAddr, HTTPPort)
if BConfig.Listen.HTTPPort != 0 {
addr = fmt.Sprintf("%s:%d", BConfig.Listen.HTTPAddr, BConfig.Listen.HTTPPort)
}
var (
......@@ -64,8 +64,8 @@ func (app *App) Run() {
)
endRunning := make(chan bool, 1)
if EnableFcgi {
if EnableStdIo {
if BConfig.Listen.EnableFcgi {
if BConfig.Listen.EnableStdIo {
err = fcgi.Serve(nil, app.Handlers) // standard I/O
if err == nil {
BeeLogger.Info("Use FCGI via standard I/O")
......@@ -73,7 +73,7 @@ func (app *App) Run() {
BeeLogger.Info("Cannot use FCGI via standard I/O", err)
}
} else {
if HTTPPort == 0 {
if BConfig.Listen.HTTPPort == 0 {
// remove the Socket file before start
if utils.FileExists(addr) {
os.Remove(addr)
......@@ -88,23 +88,23 @@ func (app *App) Run() {
err = fcgi.Serve(l, app.Handlers)
}
} else {
if Graceful {
httpsAddr := addr
app.Server.Addr = addr
if BConfig.Listen.Graceful {
httpsAddr := BConfig.Listen.HTTPSAddr
app.Server.Addr = httpsAddr
app.Server.Handler = app.Handlers
app.Server.ReadTimeout = time.Duration(HTTPServerTimeOut) * time.Second
app.Server.WriteTimeout = time.Duration(HTTPServerTimeOut) * time.Second
if EnableHTTPTLS {
app.Server.ReadTimeout = time.Duration(BConfig.Listen.ServerTimeOut) * time.Second
app.Server.WriteTimeout = time.Duration(BConfig.Listen.ServerTimeOut) * time.Second
if BConfig.Listen.HTTPSEnable {
go func() {
time.Sleep(20 * time.Microsecond)
if HTTPSPort != 0 {
httpsAddr = fmt.Sprintf("%s:%d", HTTPAddr, HTTPSPort)
if BConfig.Listen.HTTPSPort != 0 {
httpsAddr = fmt.Sprintf("%s:%d", BConfig.Listen.HTTPSAddr, BConfig.Listen.HTTPSPort)
app.Server.Addr = httpsAddr
}
server := grace.NewServer(httpsAddr, app.Handlers)
server.Server.ReadTimeout = app.Server.ReadTimeout
server.Server.WriteTimeout = app.Server.WriteTimeout
err := server.ListenAndServeTLS(HTTPCertFile, HTTPKeyFile)
err := server.ListenAndServeTLS(BConfig.Listen.HTTPSCertFile, BConfig.Listen.HTTPSKeyFile)
if err != nil {
BeeLogger.Critical("ListenAndServeTLS: ", err, fmt.Sprintf("%d", os.Getpid()))
time.Sleep(100 * time.Microsecond)
......@@ -112,12 +112,12 @@ func (app *App) Run() {
}
}()
}
if EnableHTTPListen {
if BConfig.Listen.HTTPEnable {
go func() {
server := grace.NewServer(addr, app.Handlers)
server.Server.ReadTimeout = app.Server.ReadTimeout
server.Server.WriteTimeout = app.Server.WriteTimeout
if ListenTCP4 {
if BConfig.Listen.ListenTCP4 {
server.Network = "tcp4"
}
err := server.ListenAndServe()
......@@ -131,17 +131,17 @@ func (app *App) Run() {
} else {
app.Server.Addr = addr
app.Server.Handler = app.Handlers
app.Server.ReadTimeout = time.Duration(HTTPServerTimeOut) * time.Second
app.Server.WriteTimeout = time.Duration(HTTPServerTimeOut) * time.Second
app.Server.ReadTimeout = time.Duration(BConfig.Listen.ServerTimeOut) * time.Second
app.Server.WriteTimeout = time.Duration(BConfig.Listen.ServerTimeOut) * time.Second
if EnableHTTPTLS {
if BConfig.Listen.HTTPSEnable {
go func() {
time.Sleep(20 * time.Microsecond)
if HTTPSPort != 0 {
app.Server.Addr = fmt.Sprintf("%s:%d", HTTPAddr, HTTPSPort)
if BConfig.Listen.HTTPSPort != 0 {
app.Server.Addr = fmt.Sprintf("%s:%d", BConfig.Listen.HTTPSAddr, BConfig.Listen.HTTPSPort)
}
BeeLogger.Info("https server Running on %s", app.Server.Addr)
err := app.Server.ListenAndServeTLS(HTTPCertFile, HTTPKeyFile)
err := app.Server.ListenAndServeTLS(BConfig.Listen.HTTPSCertFile, BConfig.Listen.HTTPSKeyFile)
if err != nil {
BeeLogger.Critical("ListenAndServeTLS: ", err)
time.Sleep(100 * time.Microsecond)
......@@ -150,11 +150,11 @@ func (app *App) Run() {
}()
}
if EnableHTTPListen {
if BConfig.Listen.HTTPEnable {
go func() {
app.Server.Addr = addr
BeeLogger.Info("http server Running on %s", app.Server.Addr)
if ListenTCP4 {
if BConfig.Listen.ListenTCP4 {
ln, err := net.Listen("tcp4", app.Server.Addr)
if err != nil {
BeeLogger.Critical("ListenAndServe: ", err)
......
......@@ -15,10 +15,13 @@
package beego
import (
"fmt"
"os"
"path/filepath"
"strconv"
"strings"
"github.com/astaxie/beego/logs"
)
// beego web framework version.
......@@ -49,10 +52,10 @@ func Run(params ...string) {
if len(params) > 0 && params[0] != "" {
strs := strings.Split(params[0], ":")
if len(strs) > 0 && strs[0] != "" {
HTTPAddr = strs[0]
BConfig.Listen.HTTPAddr = strs[0]
}
if len(strs) > 1 && strs[1] != "" {
HTTPPort, _ = strconv.Atoi(strs[1])
BConfig.Listen.HTTPPort, _ = strconv.Atoi(strs[1])
}
}
......@@ -60,15 +63,22 @@ func Run(params ...string) {
}
func initBeforeHTTPRun() {
// if AppConfigPath not In the conf/app.conf reParse config
if AppConfigPath != filepath.Join(AppPath, "conf", "app.conf") {
err := ParseConfig()
if err != nil && AppConfigPath != filepath.Join(workPath, "conf", "app.conf") {
// configuration is critical to app, panic here if parse failed
panic(err)
// if AppConfigPath is setted or conf/app.conf exist
err := ParseConfig()
if err != nil {
panic(err)
}
//init log
BeeLogger = logs.NewLogger(10000)
for adaptor, config := range BConfig.Log.Output {
err = BeeLogger.SetLogger(adaptor, config)
if err != nil {
fmt.Printf("%s with the config `%s` got err:%s\n", adaptor, config, err)
}
}
SetLogFuncCall(BConfig.Log.FileLineNum)
//init hooks
AddAPPStartHook(registerMime)
AddAPPStartHook(registerDefaultErrorHandler)
......@@ -85,15 +95,9 @@ func initBeforeHTTPRun() {
}
// TestBeegoInit is for test package init
func TestBeegoInit(apppath string) {
AppPath = apppath
func TestBeegoInit(ap string) {
os.Setenv("BEEGO_RUNMODE", "test")
AppConfigPath = filepath.Join(AppPath, "conf", "app.conf")
err := ParseConfig()
if err != nil && !os.IsNotExist(err) {
// for init if doesn't have app.conf will not panic
Info(err)
}
os.Chdir(AppPath)
AppConfigPath = filepath.Join(ap, "conf", "app.conf")
os.Chdir(ap)
initBeforeHTTPRun()
}
......@@ -15,358 +15,173 @@
package beego
import (
"fmt"
"html/template"
"os"
"path/filepath"
"runtime"
"strings"
"github.com/astaxie/beego/config"
"github.com/astaxie/beego/logs"
"github.com/astaxie/beego/session"
"github.com/astaxie/beego/utils"
)
var (
// AccessLogs represent whether output the access logs, default is false
AccessLogs bool
// AdminHTTPAddr is address for admin
AdminHTTPAddr string
// AdminHTTPPort is listens port for admin
AdminHTTPPort int
// AppConfig is the instance of Config, store the config information from file
AppConfig *beegoAppConfig
// AppName represent Application name, always the project folder name
AppName string
// AppPath is the path to the application
AppPath string
// AppConfigPath is the path to the config files
AppConfigPath string
// AppConfigProvider is the provider for the config, default is ini
AppConfigProvider string
// AutoRender is a flag of render template automatically. It's always turn off in API application
// default is true
AutoRender bool
// BeegoServerName exported in response header.
BeegoServerName string
// CopyRequestBody is just useful for raw request body in context. default is false
CopyRequestBody bool
// DirectoryIndex wheather display directory index. default is false.
DirectoryIndex bool
// EnableAdmin means turn on admin module to log every request info.
EnableAdmin bool
// EnableDocs enable generate docs & server docs API Swagger
EnableDocs bool
// EnableErrorsShow wheather show errors in page. if true, show error and trace info in page rendered with error template.
EnableErrorsShow bool
// EnableFcgi turn on the fcgi Listen, default is false
EnableFcgi bool
// EnableGzip means gzip the response
EnableGzip bool
// EnableHTTPListen represent whether turn on the HTTP, default is true
EnableHTTPListen bool
// EnableHTTPTLS represent whether turn on the HTTPS, default is true
EnableHTTPTLS bool
// EnableStdIo works with EnableFcgi Use FCGI via standard I/O
EnableStdIo bool
// EnableXSRF whether turn on xsrf. default is false
EnableXSRF bool
// FlashName is the name of the flash variable found in response header and cookie
FlashName string
// FlashSeperator used to seperate flash key:value, default is BEEGOFLASH
FlashSeperator string
// GlobalSessions is the instance for the session manager
GlobalSessions *session.Manager
// Graceful means use graceful module to start the server
Graceful bool
// workPath is always the same as AppPath, but sometime when it started with other
// program, like supervisor
workPath string
// ListenTCP4 represent only Listen in TCP4, default is false
ListenTCP4 bool
// MaxMemory The whole request body is parsed and up to a total of maxMemory
// bytes of its file parts are stored in memory, with the remainder stored on disk in temporary files
MaxMemory int64
// HTTPAddr is the TCP network address addr for HTTP
HTTPAddr string
// HTTPPort is listens port for HTTP
HTTPPort int
// HTTPSPort is listens port for HTTPS
HTTPSPort int
// HTTPCertFile is the path to certificate file
HTTPCertFile string
// HTTPKeyFile is the path to private key file
HTTPKeyFile string
// HTTPServerTimeOut HTTP server timeout. default is 0, no timeout
HTTPServerTimeOut int64
// RecoverPanic is a flag for auto recover panic, default is true
RecoverPanic bool
// RouterCaseSensitive means whether router case sensitive, default is true
type BeegoConfig struct {
AppName string //Application name
RunMode string //Running Mode: dev | prod
RouterCaseSensitive bool
// RunMode represent the staging, "dev" or "prod"
RunMode string
// SessionOn means whether turn on the session auto when application started. default is false.
SessionOn bool
// SessionProvider means session provider, e.q memory, mysql, redis,etc.
SessionProvider string
// SessionName is the cookie name when saving session id into cookie.
SessionName string
// SessionGCMaxLifetime for auto cleaning expired session.
SessionGCMaxLifetime int64
// SessionProviderConfig is for the provider config, define save path or connection info.
SessionProviderConfig string
// SessionCookieLifeTime means the life time of session id in cookie.
SessionCookieLifeTime int
// SessionAutoSetCookie auto setcookie
SessionAutoSetCookie bool
// SessionDomain means the cookie domain default is empty
SessionDomain string
// StaticDir store the static path, key is path, value is the folder
StaticDir map[string]string
// StaticExtensionsToGzip stores the extensions which need to gzip(.js,.css,etc)
StaticExtensionsToGzip []string
// TemplateCache store the caching template
TemplateCache map[string]*template.Template
// TemplateLeft left delimiter
TemplateLeft string
// TemplateRight right delimiter
TemplateRight string
// ViewsPath means the template folder
ViewsPath string
// XSRFKEY xsrf hash salt string.
XSRFKEY string
// XSRFExpire is the expiry of xsrf value.
XSRFExpire int
)
type beegoAppConfig struct {
innerConfig config.Configer
}
func newAppConfig(AppConfigProvider, AppConfigPath string) (*beegoAppConfig, error) {
ac, err := config.NewConfig(AppConfigProvider, AppConfigPath)
if err != nil {
return nil, err
}
rac := &beegoAppConfig{ac}
return rac, nil
}
func (b *beegoAppConfig) Set(key, val string) error {
err := b.innerConfig.Set(RunMode+"::"+key, val)
if err == nil {
return err
}
return b.innerConfig.Set(key, val)
}
func (b *beegoAppConfig) String(key string) string {
v := b.innerConfig.String(RunMode + "::" + key)
if v == "" {
return b.innerConfig.String(key)
}
return v
}
func (b *beegoAppConfig) Strings(key string) []string {
v := b.innerConfig.Strings(RunMode + "::" + key)
if v[0] == "" {
return b.innerConfig.Strings(key)
}
return v
}
func (b *beegoAppConfig) Int(key string) (int, error) {
v, err := b.innerConfig.Int(RunMode + "::" + key)
if err != nil {
return b.innerConfig.Int(key)
}
return v, nil
}
func (b *beegoAppConfig) Int64(key string) (int64, error) {
v, err := b.innerConfig.Int64(RunMode + "::" + key)
if err != nil {
return b.innerConfig.Int64(key)
}
return v, nil
ServerName string
RecoverPanic bool
CopyRequestBody bool
EnableGzip bool
MaxMemory int64
EnableErrorsShow bool
Listen Listen
WebConfig WebConfig
Log LogConfig
}
func (b *beegoAppConfig) Bool(key string) (bool, error) {
v, err := b.innerConfig.Bool(RunMode + "::" + key)
if err != nil {
return b.innerConfig.Bool(key)
}
return v, nil
type Listen struct {
Graceful bool // Graceful means use graceful module to start the server
ServerTimeOut int64
ListenTCP4 bool
HTTPEnable bool
HTTPAddr string
HTTPPort int
HTTPSEnable bool
HTTPSAddr string
HTTPSPort int
HTTPSCertFile string
HTTPSKeyFile string
AdminEnable bool
AdminAddr string
AdminPort int
EnableFcgi bool
EnableStdIo bool // EnableStdIo works with EnableFcgi Use FCGI via standard I/O
}
func (b *beegoAppConfig) Float(key string) (float64, error) {
v, err := b.innerConfig.Float(RunMode + "::" + key)
if err != nil {
return b.innerConfig.Float(key)
}
return v, nil
}
func (b *beegoAppConfig) DefaultString(key string, defaultval string) string {
v := b.String(key)
if v != "" {
return v
}
return defaultval
}
func (b *beegoAppConfig) DefaultStrings(key string, defaultval []string) []string {
v := b.Strings(key)
if len(v) != 0 {
return v
}
return defaultval
type WebConfig struct {
AutoRender bool
EnableDocs bool
FlashName string
FlashSeperator string
DirectoryIndex bool
StaticDir map[string]string
StaticExtensionsToGzip []string
TemplateLeft string
TemplateRight string
ViewsPath string
EnableXSRF bool
XSRFKEY string
XSRFExpire int
Session SessionConfig
}
func (b *beegoAppConfig) DefaultInt(key string, defaultval int) int {
v, err := b.Int(key)
if err == nil {
return v
}
return defaultval
type SessionConfig struct {
SessionOn bool
SessionProvider string
SessionName string
SessionGCMaxLifetime int64
SessionProviderConfig string
SessionCookieLifeTime int
SessionAutoSetCookie bool
SessionDomain string
}
func (b *beegoAppConfig) DefaultInt64(key string, defaultval int64) int64 {
v, err := b.Int64(key)
if err == nil {
return v
}
return defaultval
type LogConfig struct {
AccessLogs bool
FileLineNum bool
Output map[string]string // Store Adaptor : config
}
func (b *beegoAppConfig) DefaultBool(key string, defaultval bool) bool {
v, err := b.Bool(key)
if err == nil {
return v
}
return defaultval
}
var (
// BConfig is the default config for Application
BConfig *BeegoConfig
// AppConfig is the instance of Config, store the config information from file
AppConfig *beegoAppConfig
// AppConfigPath is the path to the config files
AppConfigPath string
// AppConfigProvider is the provider for the config, default is ini
AppConfigProvider = "ini"
// TemplateCache stores template caching
TemplateCache map[string]*template.Template
// GlobalSessions is the instance for the session manager
GlobalSessions *session.Manager
)
func (b *beegoAppConfig) DefaultFloat(key string, defaultval float64) float64 {
v, err := b.Float(key)
if err == nil {
return v
func init() {
BConfig = &BeegoConfig{
AppName: "beego",
RunMode: "dev",
RouterCaseSensitive: true,
ServerName: "beegoServer:" + VERSION,
RecoverPanic: true,
CopyRequestBody: false,
EnableGzip: false,
MaxMemory: 1 << 26, //64MB
EnableErrorsShow: true,
Listen: Listen{
Graceful: false,
ServerTimeOut: 0,
ListenTCP4: false,
HTTPEnable: true,
HTTPAddr: "",
HTTPPort: 8080,
HTTPSEnable: false,
HTTPSAddr: "",
HTTPSPort: 10443,
HTTPSCertFile: "",
HTTPSKeyFile: "",
AdminEnable: false,
AdminAddr: "",
AdminPort: 8088,
EnableFcgi: false,
EnableStdIo: false,
},
WebConfig: WebConfig{
AutoRender: true,
EnableDocs: false,
FlashName: "BEEGO_FLASH",
FlashSeperator: "BEEGOFLASH",
DirectoryIndex: false,
StaticDir: map[string]string{"/static": "static"},
StaticExtensionsToGzip: []string{".css", ".js"},
TemplateLeft: "{{",
TemplateRight: "}}",
ViewsPath: "views",
EnableXSRF: false,
XSRFKEY: "beegoxsrf",
XSRFExpire: 0,
Session: SessionConfig{
SessionOn: false,
SessionProvider: "memory",
SessionName: "beegosessionID",
SessionGCMaxLifetime: 3600,
SessionProviderConfig: "",
SessionCookieLifeTime: 0, //set cookie default is the brower life
SessionAutoSetCookie: true,
SessionDomain: "",
},
},
Log: LogConfig{
AccessLogs: false,
FileLineNum: true,
Output: map[string]string{"console": ""},
},
}
return defaultval
}
func (b *beegoAppConfig) DIY(key string) (interface{}, error) {
return b.innerConfig.DIY(key)
}
func (b *beegoAppConfig) GetSection(section string) (map[string]string, error) {
return b.innerConfig.GetSection(section)
}
func (b *beegoAppConfig) SaveConfigFile(filename string) error {
return b.innerConfig.SaveConfigFile(filename)
}
func init() {
workPath, _ = os.Getwd()
workPath, _ = filepath.Abs(workPath)
// initialize default configurations
AppPath, _ = filepath.Abs(filepath.Dir(os.Args[0]))
AppConfigPath = filepath.Join(AppPath, "conf", "app.conf")
if workPath != AppPath {
if utils.FileExists(AppConfigPath) {
os.Chdir(AppPath)
// ParseConfig parsed default config file.
// now only support ini, next will support json.
func ParseConfig() (err error) {
if AppConfigPath == "" {
if utils.FileExists(filepath.Join("conf", "app.conf")) {
AppConfigPath = filepath.Join("conf", "app.conf")
} else {
AppConfigPath = filepath.Join(workPath, "conf", "app.conf")
}
}
AppConfigProvider = "ini"
StaticDir = make(map[string]string)
StaticDir["/static"] = "static"
StaticExtensionsToGzip = []string{".css", ".js"}
TemplateCache = make(map[string]*template.Template)
// set this to 0.0.0.0 to make this app available to externally
EnableHTTPListen = true //default enable http Listen
HTTPAddr = ""
HTTPPort = 8080
HTTPSPort = 10443
AppName = "beego"
RunMode = "dev" //default runmod
AutoRender = true
RecoverPanic = true
ViewsPath = "views"
SessionOn = false
SessionProvider = "memory"
SessionName = "beegosessionID"
SessionGCMaxLifetime = 3600
SessionProviderConfig = ""
SessionCookieLifeTime = 0 //set cookie default is the brower life
SessionAutoSetCookie = true
MaxMemory = 1 << 26 //64MB
HTTPServerTimeOut = 0
EnableErrorsShow = true
XSRFKEY = "beegoxsrf"
XSRFExpire = 0
TemplateLeft = "{{"
TemplateRight = "}}"
BeegoServerName = "beegoServer:" + VERSION
EnableAdmin = false
AdminHTTPAddr = "127.0.0.1"
AdminHTTPPort = 8088
FlashName = "BEEGO_FLASH"
FlashSeperator = "BEEGOFLASH"
RouterCaseSensitive = true
runtime.GOMAXPROCS(runtime.NumCPU())
// init BeeLogger
BeeLogger = logs.NewLogger(10000)
err := BeeLogger.SetLogger("console", "")
if err != nil {
fmt.Println("init console log error:", err)
}
SetLogFuncCall(true)
err = ParseConfig()
if err != nil {
if os.IsNotExist(err) {
// for init if doesn't have app.conf will not panic
ac := config.NewFakeConfig()
AppConfig = &beegoAppConfig{ac}
return
}
Warning(err)
}
}
// ParseConfig parsed default config file.
// now only support ini, next will support json.
func ParseConfig() (err error) {
AppConfig, err = newAppConfig(AppConfigProvider, AppConfigPath)
if err != nil {
return err
......@@ -374,151 +189,151 @@ func ParseConfig() (err error) {
envRunMode := os.Getenv("BEEGO_RUNMODE")
// set the runmode first
if envRunMode != "" {
RunMode = envRunMode
BConfig.RunMode = envRunMode
} else if runmode := AppConfig.String("RunMode"); runmode != "" {
RunMode = runmode
BConfig.RunMode = runmode
}
HTTPAddr = AppConfig.String("HTTPAddr")
BConfig.Listen.HTTPAddr = AppConfig.String("HTTPAddr")
if v, err := AppConfig.Int("HTTPPort"); err == nil {
HTTPPort = v
BConfig.Listen.HTTPPort = v
}
if v, err := AppConfig.Bool("ListenTCP4"); err == nil {
ListenTCP4 = v
BConfig.Listen.ListenTCP4 = v
}
if v, err := AppConfig.Bool("EnableHTTPListen"); err == nil {
EnableHTTPListen = v
BConfig.Listen.HTTPEnable = v
}
if maxmemory, err := AppConfig.Int64("MaxMemory"); err == nil {
MaxMemory = maxmemory
BConfig.MaxMemory = maxmemory
}
if appname := AppConfig.String("AppName"); appname != "" {
AppName = appname
BConfig.AppName = appname
}
if autorender, err := AppConfig.Bool("AutoRender"); err == nil {
AutoRender = autorender
BConfig.WebConfig.AutoRender = autorender
}
if autorecover, err := AppConfig.Bool("RecoverPanic"); err == nil {
RecoverPanic = autorecover
BConfig.RecoverPanic = autorecover
}
if views := AppConfig.String("ViewsPath"); views != "" {
ViewsPath = views
BConfig.WebConfig.ViewsPath = views
}
if sessionon, err := AppConfig.Bool("SessionOn"); err == nil {
SessionOn = sessionon
BConfig.WebConfig.Session.SessionOn = sessionon
}
if sessProvider := AppConfig.String("SessionProvider"); sessProvider != "" {
SessionProvider = sessProvider
BConfig.WebConfig.Session.SessionProvider = sessProvider
}
if sessName := AppConfig.String("SessionName"); sessName != "" {
SessionName = sessName
BConfig.WebConfig.Session.SessionName = sessName
}
if sessProvConfig := AppConfig.String("SessionProviderConfig"); sessProvConfig != "" {
SessionProviderConfig = sessProvConfig
BConfig.WebConfig.Session.SessionProviderConfig = sessProvConfig
}
if sessMaxLifeTime, err := AppConfig.Int64("SessionGCMaxLifetime"); err == nil && sessMaxLifeTime != 0 {
SessionGCMaxLifetime = sessMaxLifeTime
BConfig.WebConfig.Session.SessionGCMaxLifetime = sessMaxLifeTime
}
if sesscookielifetime, err := AppConfig.Int("SessionCookieLifeTime"); err == nil && sesscookielifetime != 0 {
SessionCookieLifeTime = sesscookielifetime
BConfig.WebConfig.Session.SessionCookieLifeTime = sesscookielifetime
}
if enableFcgi, err := AppConfig.Bool("EnableFcgi"); err == nil {
EnableFcgi = enableFcgi
BConfig.Listen.EnableFcgi = enableFcgi
}
if enablegzip, err := AppConfig.Bool("EnableGzip"); err == nil {
EnableGzip = enablegzip
BConfig.EnableGzip = enablegzip
}
if directoryindex, err := AppConfig.Bool("DirectoryIndex"); err == nil {
DirectoryIndex = directoryindex
BConfig.WebConfig.DirectoryIndex = directoryindex
}
if timeout, err := AppConfig.Int64("HTTPServerTimeOut"); err == nil {
HTTPServerTimeOut = timeout
BConfig.Listen.ServerTimeOut = timeout
}
if errorsshow, err := AppConfig.Bool("EnableErrorsShow"); err == nil {
EnableErrorsShow = errorsshow
BConfig.EnableErrorsShow = errorsshow
}
if copyrequestbody, err := AppConfig.Bool("CopyRequestBody"); err == nil {
CopyRequestBody = copyrequestbody
BConfig.CopyRequestBody = copyrequestbody
}
if xsrfkey := AppConfig.String("XSRFKEY"); xsrfkey != "" {
XSRFKEY = xsrfkey
BConfig.WebConfig.XSRFKEY = xsrfkey
}
if enablexsrf, err := AppConfig.Bool("EnableXSRF"); err == nil {
EnableXSRF = enablexsrf
BConfig.WebConfig.EnableXSRF = enablexsrf
}
if expire, err := AppConfig.Int("XSRFExpire"); err == nil {
XSRFExpire = expire
BConfig.WebConfig.XSRFExpire = expire
}
if tplleft := AppConfig.String("TemplateLeft"); tplleft != "" {
TemplateLeft = tplleft
BConfig.WebConfig.TemplateLeft = tplleft
}
if tplright := AppConfig.String("TemplateRight"); tplright != "" {
TemplateRight = tplright
BConfig.WebConfig.TemplateRight = tplright
}
if httptls, err := AppConfig.Bool("EnableHTTPTLS"); err == nil {
EnableHTTPTLS = httptls
BConfig.Listen.HTTPSEnable = httptls
}
if httpsport, err := AppConfig.Int("HTTPSPort"); err == nil {
HTTPSPort = httpsport
BConfig.Listen.HTTPSPort = httpsport
}
if certfile := AppConfig.String("HTTPCertFile"); certfile != "" {
HTTPCertFile = certfile
BConfig.Listen.HTTPSCertFile = certfile
}
if keyfile := AppConfig.String("HTTPKeyFile"); keyfile != "" {
HTTPKeyFile = keyfile
BConfig.Listen.HTTPSKeyFile = keyfile
}
if serverName := AppConfig.String("BeegoServerName"); serverName != "" {
BeegoServerName = serverName
BConfig.ServerName = serverName
}
if flashname := AppConfig.String("FlashName"); flashname != "" {
FlashName = flashname
BConfig.WebConfig.FlashName = flashname
}
if flashseperator := AppConfig.String("FlashSeperator"); flashseperator != "" {
FlashSeperator = flashseperator
BConfig.WebConfig.FlashSeperator = flashseperator
}
if sd := AppConfig.String("StaticDir"); sd != "" {
for k := range StaticDir {
delete(StaticDir, k)
for k := range BConfig.WebConfig.StaticDir {
delete(BConfig.WebConfig.StaticDir, k)
}
sds := strings.Fields(sd)
for _, v := range sds {
if url2fsmap := strings.SplitN(v, ":", 2); len(url2fsmap) == 2 {
StaticDir["/"+strings.TrimRight(url2fsmap[0], "/")] = url2fsmap[1]
BConfig.WebConfig.StaticDir["/"+strings.TrimRight(url2fsmap[0], "/")] = url2fsmap[1]
} else {
StaticDir["/"+strings.TrimRight(url2fsmap[0], "/")] = url2fsmap[0]
BConfig.WebConfig.StaticDir["/"+strings.TrimRight(url2fsmap[0], "/")] = url2fsmap[0]
}
}
}
......@@ -537,31 +352,160 @@ func ParseConfig() (err error) {
fileExts = append(fileExts, ext)
}
if len(fileExts) > 0 {
StaticExtensionsToGzip = fileExts
BConfig.WebConfig.StaticExtensionsToGzip = fileExts
}
}
if enableadmin, err := AppConfig.Bool("EnableAdmin"); err == nil {
EnableAdmin = enableadmin
BConfig.Listen.AdminEnable = enableadmin
}
if adminhttpaddr := AppConfig.String("AdminHTTPAddr"); adminhttpaddr != "" {
AdminHTTPAddr = adminhttpaddr
BConfig.Listen.AdminAddr = adminhttpaddr
}
if adminhttpport, err := AppConfig.Int("AdminHTTPPort"); err == nil {
AdminHTTPPort = adminhttpport
BConfig.Listen.AdminPort = adminhttpport
}
if enabledocs, err := AppConfig.Bool("EnableDocs"); err == nil {
EnableDocs = enabledocs
BConfig.WebConfig.EnableDocs = enabledocs
}
if casesensitive, err := AppConfig.Bool("RouterCaseSensitive"); err == nil {
RouterCaseSensitive = casesensitive
BConfig.RouterCaseSensitive = casesensitive
}
if graceful, err := AppConfig.Bool("Graceful"); err == nil {
Graceful = graceful
BConfig.Listen.Graceful = graceful
}
return nil
}
type beegoAppConfig struct {
innerConfig config.Configer
}
func newAppConfig(AppConfigProvider, AppConfigPath string) (*beegoAppConfig, error) {
ac, err := config.NewConfig(AppConfigProvider, AppConfigPath)
if err != nil {
return nil, err
}
rac := &beegoAppConfig{ac}
return rac, nil
}
func (b *beegoAppConfig) Set(key, val string) error {
err := b.innerConfig.Set(BConfig.RunMode+"::"+key, val)
if err == nil {
return err
}
return b.innerConfig.Set(key, val)
}
func (b *beegoAppConfig) String(key string) string {
v := b.innerConfig.String(BConfig.RunMode + "::" + key)
if v == "" {
return b.innerConfig.String(key)
}
return v
}
func (b *beegoAppConfig) Strings(key string) []string {
v := b.innerConfig.Strings(BConfig.RunMode + "::" + key)
if v[0] == "" {
return b.innerConfig.Strings(key)
}
return v
}
func (b *beegoAppConfig) Int(key string) (int, error) {
v, err := b.innerConfig.Int(BConfig.RunMode + "::" + key)
if err != nil {
return b.innerConfig.Int(key)
}
return v, nil
}
func (b *beegoAppConfig) Int64(key string) (int64, error) {
v, err := b.innerConfig.Int64(BConfig.RunMode + "::" + key)
if err != nil {
return b.innerConfig.Int64(key)
}
return v, nil
}
func (b *beegoAppConfig) Bool(key string) (bool, error) {
v, err := b.innerConfig.Bool(BConfig.RunMode + "::" + key)
if err != nil {
return b.innerConfig.Bool(key)
}
return v, nil
}
func (b *beegoAppConfig) Float(key string) (float64, error) {
v, err := b.innerConfig.Float(BConfig.RunMode + "::" + key)
if err != nil {
return b.innerConfig.Float(key)
}
return v, nil
}
func (b *beegoAppConfig) DefaultString(key string, defaultval string) string {
v := b.String(key)
if v != "" {
return v
}
return defaultval
}
func (b *beegoAppConfig) DefaultStrings(key string, defaultval []string) []string {
v := b.Strings(key)
if len(v) != 0 {
return v
}
return defaultval
}
func (b *beegoAppConfig) DefaultInt(key string, defaultval int) int {
v, err := b.Int(key)
if err == nil {
return v
}
return defaultval
}
func (b *beegoAppConfig) DefaultInt64(key string, defaultval int64) int64 {
v, err := b.Int64(key)
if err == nil {
return v
}
return defaultval
}
func (b *beegoAppConfig) DefaultBool(key string, defaultval bool) bool {
v, err := b.Bool(key)
if err == nil {
return v
}
return defaultval
}
func (b *beegoAppConfig) DefaultFloat(key string, defaultval float64) float64 {
v, err := b.Float(key)
if err == nil {
return v
}
return defaultval
}
func (b *beegoAppConfig) DIY(key string) (interface{}, error) {
return b.innerConfig.DIY(key)
}
func (b *beegoAppConfig) GetSection(section string) (map[string]string, error) {
return b.innerConfig.GetSection(section)
}
func (b *beegoAppConfig) SaveConfigFile(filename string) error {
return b.innerConfig.SaveConfigFile(filename)
}
......@@ -19,11 +19,11 @@ import (
)
func TestDefaults(t *testing.T) {
if FlashName != "BEEGO_FLASH" {
if BConfig.WebConfig.FlashName != "BEEGO_FLASH" {
t.Errorf("FlashName was not set to default.")
}
if FlashSeperator != "BEEGOFLASH" {
if BConfig.WebConfig.FlashSeperator != "BEEGOFLASH" {
t.Errorf("FlashName was not set to default.")
}
}
......@@ -200,7 +200,7 @@ func (c *Controller) RenderBytes() ([]byte, error) {
c.TplNames = strings.ToLower(c.controllerName) + "/" + strings.ToLower(c.actionName) + "." + c.TplExt
}
if RunMode == "dev" {
if BConfig.RunMode == "dev" {
buildFiles := make([]string, 1)
buildFiles = append(buildFiles, c.TplNames)
if c.LayoutSections != nil {
......@@ -211,7 +211,7 @@ func (c *Controller) RenderBytes() ([]byte, error) {
buildFiles = append(buildFiles, sectionTpl)
}
}
BuildTemplate(ViewsPath, buildFiles...)
BuildTemplate(BConfig.WebConfig.ViewsPath, buildFiles...)
}
newbytes := bytes.NewBufferString("")
if _, ok := BeeTemplates[c.TplNames]; !ok {
......@@ -256,8 +256,8 @@ func (c *Controller) RenderBytes() ([]byte, error) {
if c.TplNames == "" {
c.TplNames = strings.ToLower(c.controllerName) + "/" + strings.ToLower(c.actionName) + "." + c.TplExt
}
if RunMode == "dev" {
BuildTemplate(ViewsPath, c.TplNames)
if BConfig.RunMode == "dev" {
BuildTemplate(BConfig.WebConfig.ViewsPath, c.TplNames)
}
ibytes := bytes.NewBufferString("")
if _, ok := BeeTemplates[c.TplNames]; !ok {
......@@ -319,7 +319,7 @@ func (c *Controller) URLFor(endpoint string, values ...interface{}) string {
func (c *Controller) ServeJSON(encoding ...bool) {
var hasIndent bool
var hasencoding bool
if RunMode == "prod" {
if BConfig.RunMode == "prod" {
hasIndent = false
} else {
hasIndent = true
......@@ -333,7 +333,7 @@ func (c *Controller) ServeJSON(encoding ...bool) {
// ServeJSONP sends a jsonp response.
func (c *Controller) ServeJSONP() {
var hasIndent bool
if RunMode == "prod" {
if BConfig.RunMode == "prod" {
hasIndent = false
} else {
hasIndent = true
......@@ -344,7 +344,7 @@ func (c *Controller) ServeJSONP() {
// ServeXML sends xml response.
func (c *Controller) ServeXML() {
var hasIndent bool
if RunMode == "prod" {
if BConfig.RunMode == "prod" {
hasIndent = false
} else {
hasIndent = true
......@@ -628,9 +628,9 @@ func (c *Controller) XSRFToken() string {
if c.XSRFExpire > 0 {
expire = int64(c.XSRFExpire)
} else {
expire = int64(XSRFExpire)
expire = int64(BConfig.WebConfig.XSRFExpire)
}
c._xsrfToken = c.Ctx.XSRFToken(XSRFKEY, expire)
c._xsrfToken = c.Ctx.XSRFToken(BConfig.WebConfig.XSRFKEY, expire)
}
return c._xsrfToken
}
......
......@@ -15,30 +15,25 @@
package beego
import (
"fmt"
"github.com/astaxie/beego/context"
"testing"
"github.com/astaxie/beego/context"
)
func TestGetInt(t *testing.T) {
i := &context.BeegoInput{Params: map[string]string{"age": "40"}}
ctx := &context.Context{Input: i}
ctrlr := Controller{Ctx: ctx}
val, _ := ctrlr.GetInt("age")
if (val != 40) {
if val != 40 {
t.Errorf("TestGetInt expect 40,get %T,%v", val, val)
}
}
func TestGetInt8(t *testing.T) {
i := &context.BeegoInput{Params: map[string]string{"age": "40"}}
ctx := &context.Context{Input: i}
ctrlr := Controller{Ctx: ctx}
val, _ := ctrlr.GetInt8("age")
if val != 40 {
t.Errorf("TestGetInt8 expect 40,get %T,%v", val, val)
......@@ -47,11 +42,9 @@ func TestGetInt8(t *testing.T) {
}
func TestGetInt16(t *testing.T) {
i := &context.BeegoInput{Params: map[string]string{"age": "40"}}
ctx := &context.Context{Input: i}
ctrlr := Controller{Ctx: ctx}
val, _ := ctrlr.GetInt16("age")
if val != 40 {
t.Errorf("TestGetInt16 expect 40,get %T,%v", val, val)
......@@ -59,24 +52,19 @@ func TestGetInt16(t *testing.T) {
}
func TestGetInt32(t *testing.T) {
i := &context.BeegoInput{Params: map[string]string{"age": "40"}}
ctx := &context.Context{Input: i}
ctrlr := Controller{Ctx: ctx}
val, _ := ctrlr.GetInt32("age")
fmt.Printf("%T", val)
if val != 40 {
t.Errorf("TestGetInt32 expect 40,get %T,%v", val, val)
}
}
func TestGetInt64(t *testing.T) {
i := &context.BeegoInput{Params: map[string]string{"age": "40"}}
ctx := &context.Context{Input: i}
ctrlr := Controller{Ctx: ctx}
val, _ := ctrlr.GetInt64("age")
if val != 40 {
t.Errorf("TestGeetInt64 expect 40,get %T,%v", val, val)
......
......@@ -24,7 +24,7 @@ import (
var GlobalDocAPI map[string]interface{}
func init() {
if EnableDocs {
if BConfig.WebConfig.EnableDocs {
GlobalDocAPI = make(map[string]interface{})
}
}
......
......@@ -85,7 +85,7 @@ var tpl = `
func showErr(err interface{}, ctx *context.Context, Stack string) {
t, _ := template.New("beegoerrortemp").Parse(tpl)
data := make(map[string]string)
data["AppError"] = AppName + ":" + fmt.Sprint(err)
data["AppError"] = BConfig.AppName + ":" + fmt.Sprint(err)
data["RequestMethod"] = ctx.Input.Method()
data["RequestURL"] = ctx.Input.URI()
data["RemoteAddr"] = ctx.Input.IP()
......@@ -437,7 +437,7 @@ func executeError(err *errorInfo, ctx *context.Context, code int) {
method.Call(in)
//render template
if AutoRender {
if BConfig.WebConfig.AutoRender {
if err := execController.Render(); err != nil {
panic(err)
}
......
......@@ -20,8 +20,14 @@ import (
"testing"
"github.com/astaxie/beego/context"
"github.com/astaxie/beego/logs"
)
func init() {
BeeLogger = logs.NewLogger(10000)
BeeLogger.SetLogger("console", "")
}
var FilterUser = func(ctx *context.Context) {
ctx.Output.Body([]byte("i am " + ctx.Input.Params[":last"] + ctx.Input.Params[":first"]))
}
......
......@@ -83,27 +83,27 @@ func (fd *FlashData) Store(c *Controller) {
c.Data["flash"] = fd.Data
var flashValue string
for key, value := range fd.Data {
flashValue += "\x00" + key + "\x23" + FlashSeperator + "\x23" + value + "\x00"
flashValue += "\x00" + key + "\x23" + BConfig.WebConfig.FlashSeperator + "\x23" + value + "\x00"
}
c.Ctx.SetCookie(FlashName, url.QueryEscape(flashValue), 0, "/")
c.Ctx.SetCookie(BConfig.WebConfig.FlashName, url.QueryEscape(flashValue), 0, "/")
}
// ReadFromRequest parsed flash data from encoded values in cookie.
func ReadFromRequest(c *Controller) *FlashData {
flash := NewFlash()
if cookie, err := c.Ctx.Request.Cookie(FlashName); err == nil {
if cookie, err := c.Ctx.Request.Cookie(BConfig.WebConfig.FlashName); err == nil {
v, _ := url.QueryUnescape(cookie.Value)
vals := strings.Split(v, "\x00")
for _, v := range vals {
if len(v) > 0 {
kv := strings.Split(v, "\x23"+FlashSeperator+"\x23")
kv := strings.Split(v, "\x23"+BConfig.WebConfig.FlashSeperator+"\x23")
if len(kv) == 2 {
flash.Data[kv[0]] = kv[1]
}
}
}
//read one time then delete it
c.Ctx.SetCookie(FlashName, "", -1, "/")
c.Ctx.SetCookie(BConfig.WebConfig.FlashName, "", -1, "/")
}
c.Data["flash"] = flash.Data
return flash
......
......@@ -41,19 +41,19 @@ func registerDefaultErrorHandler() error {
}
func registerSession() error {
if SessionOn {
if BConfig.WebConfig.Session.SessionOn {
var err error
sessionConfig := AppConfig.String("sessionConfig")
if sessionConfig == "" {
sessionConfig = `{"cookieName":"` + SessionName + `",` +
`"gclifetime":` + strconv.FormatInt(SessionGCMaxLifetime, 10) + `,` +
`"providerConfig":"` + filepath.ToSlash(SessionProviderConfig) + `",` +
`"secure":` + strconv.FormatBool(EnableHTTPTLS) + `,` +
`"enableSetCookie":` + strconv.FormatBool(SessionAutoSetCookie) + `,` +
`"domain":"` + SessionDomain + `",` +
`"cookieLifeTime":` + strconv.Itoa(SessionCookieLifeTime) + `}`
sessionConfig = `{"cookieName":"` + BConfig.WebConfig.Session.SessionName + `",` +
`"gclifetime":` + strconv.FormatInt(BConfig.WebConfig.Session.SessionGCMaxLifetime, 10) + `,` +
`"providerConfig":"` + filepath.ToSlash(BConfig.WebConfig.Session.SessionProviderConfig) + `",` +
`"secure":` + strconv.FormatBool(BConfig.Listen.HTTPSEnable) + `,` +
`"enableSetCookie":` + strconv.FormatBool(BConfig.WebConfig.Session.SessionAutoSetCookie) + `,` +
`"domain":"` + BConfig.WebConfig.Session.SessionDomain + `",` +
`"cookieLifeTime":` + strconv.Itoa(BConfig.WebConfig.Session.SessionCookieLifeTime) + `}`
}
GlobalSessions, err = session.NewManager(SessionProvider, sessionConfig)
GlobalSessions, err = session.NewManager(BConfig.WebConfig.Session.SessionProvider, sessionConfig)
if err != nil {
return err
}
......@@ -63,9 +63,9 @@ func registerSession() error {
}
func registerTemplate() error {
if AutoRender {
err := BuildTemplate(ViewsPath)
if err != nil && RunMode == "dev" {
if BConfig.WebConfig.AutoRender {
err := BuildTemplate(BConfig.WebConfig.ViewsPath)
if err != nil && BConfig.RunMode == "dev" {
Warn(err)
}
}
......@@ -73,7 +73,7 @@ func registerTemplate() error {
}
func registerDocs() error {
if EnableDocs {
if BConfig.WebConfig.EnableDocs {
Get("/docs", serverDocs)
Get("/docs/*", serverDocs)
}
......@@ -81,7 +81,7 @@ func registerDocs() error {
}
func registerAdmin() error {
if EnableAdmin {
if BConfig.Listen.AdminEnable {
go beeAdminApp.Run()
}
return nil
......
......@@ -130,7 +130,7 @@ func parserComments(comments *ast.CommentGroup, funcName, controllerName, pkgpat
}
func genRouterCode() {
os.Mkdir(path.Join(workPath, "routers"), 0755)
os.Mkdir("routers", 0755)
Info("generate router from comments")
var (
globalinfo string
......@@ -172,7 +172,7 @@ func genRouterCode() {
}
}
if globalinfo != "" {
f, err := os.Create(path.Join(workPath, "routers", commentFilename))
f, err := os.Create(path.Join("routers", commentFilename))
if err != nil {
panic(err)
}
......@@ -182,11 +182,11 @@ func genRouterCode() {
}
func compareFile(pkgRealpath string) bool {
if !utils.FileExists(path.Join(workPath, "routers", commentFilename)) {
if !utils.FileExists(path.Join("routers", commentFilename)) {
return true
}
if utils.FileExists(path.Join(workPath, lastupdateFilename)) {
content, err := ioutil.ReadFile(path.Join(workPath, lastupdateFilename))
if utils.FileExists(lastupdateFilename) {
content, err := ioutil.ReadFile(lastupdateFilename)
if err != nil {
return true
}
......@@ -214,7 +214,7 @@ func savetoFile(pkgRealpath string) {
if err != nil {
return
}
ioutil.WriteFile(path.Join(workPath, lastupdateFilename), d, os.ModePerm)
ioutil.WriteFile(lastupdateFilename, d, os.ModePerm)
}
func getpathTime(pkgRealpath string) (lastupdate int64, err error) {
......
......@@ -220,7 +220,7 @@ func Test_Preflight(t *testing.T) {
func Benchmark_WithoutCORS(b *testing.B) {
recorder := httptest.NewRecorder()
handler := beego.NewControllerRegister()
beego.RunMode = "prod"
beego.BConfig.RunMode = "prod"
handler.Any("/foo", func(ctx *context.Context) {
ctx.Output.SetStatus(500)
})
......@@ -234,7 +234,7 @@ func Benchmark_WithoutCORS(b *testing.B) {
func Benchmark_WithCORS(b *testing.B) {
recorder := httptest.NewRecorder()
handler := beego.NewControllerRegister()
beego.RunMode = "prod"
beego.BConfig.RunMode = "prod"
handler.InsertFilter("*", beego.BeforeRouter, Allow(&Options{
AllowAllOrigins: true,
AllowCredentials: true,
......
// 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 jwt provides JWT (Json Web Token) authentication
//
// Usage
// In file main.go
//
// import (
// "github.com/astaxie/beego"
// "github.com/astaxie/beego/plugins/jwt"
// )
//
// func main() {
// // JWT for Url matching /v1/*
// // PrivateKeyPath: The path for the private RSA key used by JWT
// // PublicKeyPath: The path for the public RSA key used by JWT
// // The list of Urls should be excluded from the JWT Auth
// beego.InsertFilter("/v1/*", beego.BeforeRouter, jwt.AuthRequest(&jwt.Options{
// PrivateKeyPath: "conf/beeblog.rsa",
// PublicKeyPath: "conf/beeblog.rsa.pub",
// WhiteList: []string{"/v1/jwt/issue-token", "/docs"},
// }))
// beego.Run()
// }
//
// In file routers/router.go
//
// import (
// "github.com/astaxie/beego"
// "github.com/astaxie/beego/plugins/jwt"
// )
// func init() {
// ns := beego.NSNamespace("/jwt",
// beego.NSInclude(
// &jwt.JwtController{},
// ),
// )
// beego.AddNamespace(ns)
// }
//
package jwt
import (
"io/ioutil"
"net/http"
"time"
"github.com/astaxie/beego"
"github.com/astaxie/beego/context"
"github.com/astaxie/beego/logs"
goJwt "github.com/dgrijalva/jwt-go"
)
// Options for the JWT Auth
type Options struct {
PrivateKeyPath string
PublicKeyPath string
WhiteList []string
}
// RSAKeys store PrivateKey and PublicKey
var RSAKeys struct {
PrivateKey []byte
PublicKey []byte
}
// AuthRequest retunn FilterFunc
func AuthRequest(o *Options) beego.FilterFunc {
RSAKeys.PrivateKey, _ = ioutil.ReadFile(o.PrivateKeyPath)
RSAKeys.PublicKey, _ = ioutil.ReadFile(o.PublicKeyPath)
return func(ctx *context.Context) {
// :TODO the url patterns should be considered here.
// Shouldn't only use the string equal
for _, method := range o.WhiteList {
if method == ctx.Request.URL.Path {
return
}
}
parsedToken, err := goJwt.ParseFromRequest(ctx.Request, func(t *goJwt.Token) (interface{}, error) {
return RSAKeys.PublicKey, nil
})
if err == nil && parsedToken.Valid {
ctx.Output.SetStatus(http.StatusOK)
} else {
ctx.Output.SetStatus(http.StatusUnauthorized)
}
}
}
// Controller oprations for Jwt
type Controller struct {
beego.Controller
}
// URLMapping is used to mapping the string to method
func (c *Controller) URLMapping() {
c.Mapping("IssueToken", c.IssueToken)
}
// IssueToken function
// @Title IssueToken
// @Description Issue a Json Web Token
// @Success 200 string
// @Failure 403 no privilege to access
// @Failure 500 server inner error
// @router /issue-token [get]
func (c *Controller) IssueToken() {
c.Data["json"] = CreateToken()
c.ServeJSON()
}
// CreateToken return the token
func CreateToken() map[string]string {
log := logs.NewLogger(10000)
log.SetLogger("console", "")
token := goJwt.New(goJwt.GetSigningMethod("RS256")) // Create a Token that will be signed with RSA 256.
token.Claims["ID"] = "This is my super fake ID"
token.Claims["exp"] = time.Now().Unix() + 36000
// The claims object allows you to store information in the actual token.
tokenString, _ := token.SignedString(RSAKeys.PrivateKey)
// tokenString Contains the actual token you should share with your client.
return map[string]string{"token": tokenString}
}
package jwt
import (
"github.com/astaxie/beego"
"net/http"
"net/http/httptest"
"testing"
)
func testRequest(method, path string) (*httptest.ResponseRecorder, *http.Request) {
request, _ := http.NewRequest(method, path, nil)
recorder := httptest.NewRecorder()
return recorder, request
}
func Test_IssueTokenAction(t *testing.T) {
url := "/v1/jwt/issue-token"
mux := beego.NewControllerRegister()
mux.InsertFilter("*", beego.BeforeRouter, AuthRequest(&Options{
PrivateKeyPath: "test/jwt.rsa",
PublicKeyPath: "test/jwt.rsa.pub",
WhiteList: []string{"/v1/jwt/issue-token", "/docs"},
}))
mux.Add("/v1/jwt/issue-token", &JwtController{}, "get:IssueToken")
rw, r := testRequest("GET", url)
mux.ServeHTTP(rw, r)
if rw.Code != http.StatusOK {
t.Errorf("Shoud return 200")
}
}
func (tc *JwtController) Foo() {
tc.Ctx.Output.Body([]byte("ok"))
}
func Test_AuthRequestWithAuthorizationHeader(t *testing.T) {
url := "/foo"
mux := beego.NewControllerRegister()
mux.InsertFilter("*", beego.BeforeRouter, AuthRequest(&Options{
PrivateKeyPath: "test/jwt.rsa",
PublicKeyPath: "test/jwt.rsa.pub",
WhiteList: []string{"/v1/jwt/issue-token", "/docs"},
}))
mux.Add("/foo", &JwtController{}, "get:Foo")
newToken := CreateToken()
rw, r := testRequest("GET", url)
r.Header.Add("Authorization", "Bearer "+newToken["token"])
mux.ServeHTTP(rw, r)
if rw.Code != http.StatusOK {
t.Errorf("Shoud return 200")
}
if rw.Body.String() != "ok" {
t.Errorf("Should output ok")
}
}
func Test_AuthRequestWithoutAuthorizationHeader(t *testing.T) {
url := "/foo"
mux := beego.NewControllerRegister()
mux.InsertFilter("*", beego.BeforeRouter, AuthRequest(&Options{
PrivateKeyPath: "test/jwt.rsa",
PublicKeyPath: "test/jwt.rsa.pub",
WhiteList: []string{"/v1/jwt/issue-token", "/docs"},
}))
mux.Add("/foo", &JwtController{}, "get:Foo")
rw, r := testRequest("GET", url)
mux.ServeHTTP(rw, r)
if rw.Code != http.StatusUnauthorized {
t.Errorf("Shoud return 401")
}
}
-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQCdu+23Y/0J/FTQKnIPnxupoOo9/OYCv90DPXN/KLLRAMjYzgcC
DsBST2xVR5jlimI/gyfCpVB62dwpSzzr0cA3MoDhbaGWuTdQUX9zmiLoQ4I7X6h0
dwyiihOz+CzOMlAg5+qBhiTGcKvIFlfEc1FUcn/tB3PVRG9j6B1Ibz5CnQIDAQAB
AoGAFGg+/i4ai9MwqeoD7c95Bb5C8BgrLgnir0uhCL+cOvwuABbPw01jRoLuEi58
Mp5vzaXLXByFSA+ts03/qMbvZkDGac5g5kLli5TjHIONMxVBrdfGQ1+OApnaPayN
N+HYjZKs6xao6J5iFqfA0FqzDR9kQhUoeosdQoo1GlxDckECQQDO/0LJrFiLzYWe
qS/DxfAnFu2BlClKZjxRJ3vIkRRaON6HPl8BeJW901bFKG5+WSfO+OwQ9egWaf3X
fFm/oEHRAkEAwxMor4fOkBZbL4KPW7sen169vwnXuYusqj0t3dIeiIVrCigkOMT4
OvX/63u4CTdXh1D5u/4Z/1HTYH92VCP7DQJAJPxbNKnE0IYSf/z++d4eQP3JxkNw
9Ug7Msz5QycZGd3bdRLh6uNe7iIa+PN2esD3afX0SDuIEqkxoBUp/CFoYQJAUmi3
mV+/7bLkFrALK+9iwmTdt+TKk4HkEY8C32CysW3biFDo7GqZix79XFfJqWsNuQaG
WdrA1NGWgH+YV3dTyQJAIWEZGAuUXRkQB20LfjGzpsKgQFbqjTisMS0qe3JjnDwu
0JR8sYXapgeEEEisH+OtkZKIfyeFOwoUyNC83bcvgw==
-----END RSA PRIVATE KEY-----
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCdu+23Y/0J/FTQKnIPnxupoOo9
/OYCv90DPXN/KLLRAMjYzgcCDsBST2xVR5jlimI/gyfCpVB62dwpSzzr0cA3MoDh
baGWuTdQUX9zmiLoQ4I7X6h0dwyiihOz+CzOMlAg5+qBhiTGcKvIFlfEc1FUcn/t
B3PVRG9j6B1Ibz5CnQIDAQAB
-----END PUBLIC KEY-----
......@@ -87,7 +87,7 @@ func (l *logFilter) Filter(ctx *beecontext.Context) bool {
if requestPath == "/favicon.ico" || requestPath == "/robots.txt" {
return true
}
for prefix := range StaticDir {
for prefix := range BConfig.WebConfig.StaticDir {
if strings.HasPrefix(requestPath, prefix) {
return true
}
......@@ -183,7 +183,7 @@ func (p *ControllerRegister) Add(pattern string, c ControllerInterface, mappingM
}
func (p *ControllerRegister) addToRouter(method, pattern string, r *controllerInfo) {
if !RouterCaseSensitive {
if !BConfig.RouterCaseSensitive {
pattern = strings.ToLower(pattern)
}
if t, ok := p.routers[method]; ok {
......@@ -198,7 +198,7 @@ func (p *ControllerRegister) addToRouter(method, pattern string, r *controllerIn
// Include only when the Runmode is dev will generate router file in the router/auto.go from the controller
// Include(&BankAccount{}, &OrderController{},&RefundController{},&ReceiptController{})
func (p *ControllerRegister) Include(cList ...ControllerInterface) {
if RunMode == "dev" {
if BConfig.RunMode == "dev" {
skip := make(map[string]bool, 10)
for _, c := range cList {
reflectVal := reflect.ValueOf(c)
......@@ -406,7 +406,7 @@ func (p *ControllerRegister) InsertFilter(pattern string, pos int, filter Filter
mr.tree = NewTree()
mr.pattern = pattern
mr.filterFunc = filter
if !RouterCaseSensitive {
if !BConfig.RouterCaseSensitive {
pattern = strings.ToLower(pattern)
}
if len(params) == 0 {
......@@ -580,8 +580,8 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request)
w := &responseWriter{rw, false, 0}
if RunMode == "dev" {
w.Header().Set("Server", BeegoServerName)
if BConfig.RunMode == "dev" {
w.Header().Set("Server", BConfig.ServerName)
}
// init context
......@@ -592,12 +592,12 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request)
Output: beecontext.NewOutput(),
}
context.Output.Context = context
context.Output.EnableGzip = EnableGzip
context.Output.EnableGzip = BConfig.EnableGzip
defer p.recoverPanic(context)
var urlPath string
if !RouterCaseSensitive {
if !BConfig.RouterCaseSensitive {
urlPath = strings.ToLower(r.URL.Path)
} else {
urlPath = r.URL.Path
......@@ -646,7 +646,7 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request)
}
// session init
if SessionOn {
if BConfig.WebConfig.Session.SessionOn {
var err error
context.Input.CruSession, err = GlobalSessions.SessionStart(w, r)
if err != nil {
......@@ -660,10 +660,10 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request)
}
if r.Method != "GET" && r.Method != "HEAD" {
if CopyRequestBody && !context.Input.IsUpload() {
if BConfig.CopyRequestBody && !context.Input.IsUpload() {
context.Input.CopyBody()
}
context.Input.ParseFormOrMulitForm(MaxMemory)
context.Input.ParseFormOrMulitForm(BConfig.MaxMemory)
}
if doFilter(BeforeRouter) {
......@@ -765,7 +765,7 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request)
execController.Prepare()
//if XSRF is Enable then check cookie where there has any cookie in the request's cookie _csrf
if EnableXSRF {
if BConfig.WebConfig.EnableXSRF {
execController.XSRFToken()
if r.Method == "POST" || r.Method == "DELETE" || r.Method == "PUT" ||
(r.Method == "POST" && (context.Input.Query("_method") == "DELETE" || context.Input.Query("_method") == "PUT")) {
......@@ -802,7 +802,7 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request)
//render template
if !w.started && context.Output.Status == 0 {
if AutoRender {
if BConfig.WebConfig.AutoRender {
if err := execController.Render(); err != nil {
panic(err)
}
......@@ -825,7 +825,7 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request)
Admin:
timeend := time.Since(starttime)
//admin module record QPS
if EnableAdmin {
if BConfig.Listen.AdminEnable {
if FilterMonitorFunc(r.Method, r.URL.Path, timeend) {
if runrouter != nil {
go toolbox.StatisticsMap.AddStatistics(r.Method, r.URL.Path, runrouter.Name(), timeend)
......@@ -835,7 +835,7 @@ Admin:
}
}
if RunMode == "dev" || AccessLogs {
if BConfig.RunMode == "dev" || BConfig.Log.AccessLogs {
var devinfo string
if findrouter {
if routerInfo != nil {
......@@ -862,10 +862,10 @@ func (p *ControllerRegister) recoverPanic(context *beecontext.Context) {
if err == ErrAbort {
return
}
if !RecoverPanic {
if !BConfig.RecoverPanic {
panic(err)
} else {
if EnableErrorsShow {
if BConfig.EnableErrorsShow {
if _, ok := ErrorMaps[fmt.Sprint(err)]; ok {
exception(fmt.Sprint(err), context)
return
......@@ -882,7 +882,7 @@ func (p *ControllerRegister) recoverPanic(context *beecontext.Context) {
Critical(fmt.Sprintf("%s:%d", file, line))
stack = stack + fmt.Sprintln(fmt.Sprintf("%s:%d", file, line))
}
if RunMode == "dev" {
if BConfig.RunMode == "dev" {
showErr(err, context, stack)
}
}
......
......@@ -49,7 +49,7 @@ func serverStaticRouter(ctx *context.Context) {
}
if filePath == "" || fileInfo == nil {
if RunMode == "dev" {
if BConfig.RunMode == "dev" {
Warn("Can't find/open the file:", filePath, err)
}
http.NotFound(ctx.ResponseWriter, ctx.Request)
......@@ -61,14 +61,14 @@ func serverStaticRouter(ctx *context.Context) {
return
}
var enableCompress = EnableGzip && isStaticCompress(filePath)
var enableCompress = BConfig.EnableGzip && isStaticCompress(filePath)
var acceptEncoding string
if enableCompress {
acceptEncoding = context.ParseEncoding(ctx.Request)
}
b, n, sch, err := openFile(filePath, fileInfo, acceptEncoding)
if err != nil {
if RunMode == "dev" {
if BConfig.RunMode == "dev" {
Warn("Can't compress the file:", filePath, err)
}
http.NotFound(ctx.ResponseWriter, ctx.Request)
......@@ -133,7 +133,7 @@ func isOk(s *serveContentHolder, fi os.FileInfo) bool {
// isStaticCompress detect static files
func isStaticCompress(filePath string) bool {
for _, statExtension := range StaticExtensionsToGzip {
for _, statExtension := range BConfig.WebConfig.StaticExtensionsToGzip {
if strings.HasSuffix(strings.ToLower(filePath), strings.ToLower(statExtension)) {
return true
}
......@@ -151,7 +151,7 @@ func searchFile(ctx *context.Context) (string, os.FileInfo, error) {
if fi, _ := os.Stat(file); fi != nil {
return file, fi, nil
}
for _, staticDir := range StaticDir {
for _, staticDir := range BConfig.WebConfig.StaticDir {
filePath := path.Join(staticDir, requestPath)
if fi, _ := os.Stat(filePath); fi != nil {
return filePath, fi, nil
......@@ -160,7 +160,7 @@ func searchFile(ctx *context.Context) (string, os.FileInfo, error) {
return "", nil, errors.New(requestPath + " file not find")
}
for prefix, staticDir := range StaticDir {
for prefix, staticDir := range BConfig.WebConfig.StaticDir {
if len(prefix) == 0 {
continue
}
......@@ -193,5 +193,5 @@ func lookupFile(ctx *context.Context) (bool, string, os.FileInfo, error) {
if ifi, _ := os.Stat(ifp); ifi != nil && ifi.Mode().IsRegular() {
return false, ifp, ifi, err
}
return !DirectoryIndex, fp, fi, err
return !BConfig.WebConfig.DirectoryIndex, fp, fi, err
}
......@@ -176,7 +176,7 @@ func getTplDeep(root, file, parent string, t *template.Template) (*template.Temp
if err != nil {
return nil, [][]string{}, err
}
reg := regexp.MustCompile(TemplateLeft + "[ ]*template[ ]+\"([^\"]+)\"")
reg := regexp.MustCompile(BConfig.WebConfig.TemplateLeft + "[ ]*template[ ]+\"([^\"]+)\"")
allsub := reg.FindAllStringSubmatch(string(data), -1)
for _, m := range allsub {
if len(m) == 2 {
......@@ -197,7 +197,7 @@ func getTplDeep(root, file, parent string, t *template.Template) (*template.Temp
}
func getTemplate(root, file string, others ...string) (t *template.Template, err error) {
t = template.New(file).Delims(TemplateLeft, TemplateRight).Funcs(beegoTplFuncMap)
t = template.New(file).Delims(BConfig.WebConfig.TemplateLeft, BConfig.WebConfig.TemplateRight).Funcs(beegoTplFuncMap)
var submods [][]string
t, submods, err = getTplDeep(root, file, "", t)
if err != nil {
......@@ -239,7 +239,7 @@ func _getTemplate(t0 *template.Template, root string, submods [][]string, others
if err != nil {
continue
}
reg := regexp.MustCompile(TemplateLeft + "[ ]*define[ ]+\"([^\"]+)\"")
reg := regexp.MustCompile(BConfig.WebConfig.TemplateLeft + "[ ]*define[ ]+\"([^\"]+)\"")
allsub := reg.FindAllStringSubmatch(string(data), -1)
for _, sub := range allsub {
if len(sub) == 2 && sub[1] == m[1] {
......@@ -262,7 +262,7 @@ func _getTemplate(t0 *template.Template, root string, submods [][]string, others
// SetViewsPath sets view directory path in beego application.
func SetViewsPath(path string) *App {
ViewsPath = path
BConfig.WebConfig.ViewsPath = path
return BeeApp
}
......@@ -273,7 +273,7 @@ func SetStaticPath(url string, path string) *App {
url = "/" + url
}
url = strings.TrimRight(url, "/")
StaticDir[url] = path
BConfig.WebConfig.StaticDir[url] = path
return BeeApp
}
......@@ -283,6 +283,6 @@ func DelStaticPath(url string) *App {
url = "/" + url
}
url = strings.TrimRight(url, "/")
delete(StaticDir, url)
delete(BConfig.WebConfig.StaticDir, url)
return BeeApp
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment