refact beego config

This commit is contained in:
astaxie 2015-12-09 23:35:04 +08:00
parent 3d4ad560f8
commit d1bba02958
21 changed files with 485 additions and 831 deletions

View File

@ -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)

50
app.go
View File

@ -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)

View File

@ -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()
}

762
config.go
View File

@ -15,131 +15,372 @@
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"
)
type BeegoConfig struct {
AppName string //Application name
RunMode string //Running Mode: dev | prod
RouterCaseSensitive bool
ServerName string
RecoverPanic bool
CopyRequestBody bool
EnableGzip bool
MaxMemory int64
EnableErrorsShow bool
Listen Listen
WebConfig WebConfig
Log LogConfig
}
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
}
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
}
type SessionConfig struct {
SessionOn bool
SessionProvider string
SessionName string
SessionGCMaxLifetime int64
SessionProviderConfig string
SessionCookieLifeTime int
SessionAutoSetCookie bool
SessionDomain string
}
type LogConfig struct {
AccessLogs bool
FileLineNum bool
Output map[string]string // Store Adaptor : config
}
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
// BConfig is the default config for Application
BConfig *BeegoConfig
// 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
AppConfigProvider = "ini"
// TemplateCache stores template caching
TemplateCache map[string]*template.Template
// 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
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
)
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": ""},
},
}
}
// 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 {
ac := config.NewFakeConfig()
AppConfig = &beegoAppConfig{ac}
return
}
}
AppConfig, err = newAppConfig(AppConfigProvider, AppConfigPath)
if err != nil {
return err
}
envRunMode := os.Getenv("BEEGO_RUNMODE")
// set the runmode first
if envRunMode != "" {
BConfig.RunMode = envRunMode
} else if runmode := AppConfig.String("RunMode"); runmode != "" {
BConfig.RunMode = runmode
}
BConfig.Listen.HTTPAddr = AppConfig.String("HTTPAddr")
if v, err := AppConfig.Int("HTTPPort"); err == nil {
BConfig.Listen.HTTPPort = v
}
if v, err := AppConfig.Bool("ListenTCP4"); err == nil {
BConfig.Listen.ListenTCP4 = v
}
if v, err := AppConfig.Bool("EnableHTTPListen"); err == nil {
BConfig.Listen.HTTPEnable = v
}
if maxmemory, err := AppConfig.Int64("MaxMemory"); err == nil {
BConfig.MaxMemory = maxmemory
}
if appname := AppConfig.String("AppName"); appname != "" {
BConfig.AppName = appname
}
if autorender, err := AppConfig.Bool("AutoRender"); err == nil {
BConfig.WebConfig.AutoRender = autorender
}
if autorecover, err := AppConfig.Bool("RecoverPanic"); err == nil {
BConfig.RecoverPanic = autorecover
}
if views := AppConfig.String("ViewsPath"); views != "" {
BConfig.WebConfig.ViewsPath = views
}
if sessionon, err := AppConfig.Bool("SessionOn"); err == nil {
BConfig.WebConfig.Session.SessionOn = sessionon
}
if sessProvider := AppConfig.String("SessionProvider"); sessProvider != "" {
BConfig.WebConfig.Session.SessionProvider = sessProvider
}
if sessName := AppConfig.String("SessionName"); sessName != "" {
BConfig.WebConfig.Session.SessionName = sessName
}
if sessProvConfig := AppConfig.String("SessionProviderConfig"); sessProvConfig != "" {
BConfig.WebConfig.Session.SessionProviderConfig = sessProvConfig
}
if sessMaxLifeTime, err := AppConfig.Int64("SessionGCMaxLifetime"); err == nil && sessMaxLifeTime != 0 {
BConfig.WebConfig.Session.SessionGCMaxLifetime = sessMaxLifeTime
}
if sesscookielifetime, err := AppConfig.Int("SessionCookieLifeTime"); err == nil && sesscookielifetime != 0 {
BConfig.WebConfig.Session.SessionCookieLifeTime = sesscookielifetime
}
if enableFcgi, err := AppConfig.Bool("EnableFcgi"); err == nil {
BConfig.Listen.EnableFcgi = enableFcgi
}
if enablegzip, err := AppConfig.Bool("EnableGzip"); err == nil {
BConfig.EnableGzip = enablegzip
}
if directoryindex, err := AppConfig.Bool("DirectoryIndex"); err == nil {
BConfig.WebConfig.DirectoryIndex = directoryindex
}
if timeout, err := AppConfig.Int64("HTTPServerTimeOut"); err == nil {
BConfig.Listen.ServerTimeOut = timeout
}
if errorsshow, err := AppConfig.Bool("EnableErrorsShow"); err == nil {
BConfig.EnableErrorsShow = errorsshow
}
if copyrequestbody, err := AppConfig.Bool("CopyRequestBody"); err == nil {
BConfig.CopyRequestBody = copyrequestbody
}
if xsrfkey := AppConfig.String("XSRFKEY"); xsrfkey != "" {
BConfig.WebConfig.XSRFKEY = xsrfkey
}
if enablexsrf, err := AppConfig.Bool("EnableXSRF"); err == nil {
BConfig.WebConfig.EnableXSRF = enablexsrf
}
if expire, err := AppConfig.Int("XSRFExpire"); err == nil {
BConfig.WebConfig.XSRFExpire = expire
}
if tplleft := AppConfig.String("TemplateLeft"); tplleft != "" {
BConfig.WebConfig.TemplateLeft = tplleft
}
if tplright := AppConfig.String("TemplateRight"); tplright != "" {
BConfig.WebConfig.TemplateRight = tplright
}
if httptls, err := AppConfig.Bool("EnableHTTPTLS"); err == nil {
BConfig.Listen.HTTPSEnable = httptls
}
if httpsport, err := AppConfig.Int("HTTPSPort"); err == nil {
BConfig.Listen.HTTPSPort = httpsport
}
if certfile := AppConfig.String("HTTPCertFile"); certfile != "" {
BConfig.Listen.HTTPSCertFile = certfile
}
if keyfile := AppConfig.String("HTTPKeyFile"); keyfile != "" {
BConfig.Listen.HTTPSKeyFile = keyfile
}
if serverName := AppConfig.String("BeegoServerName"); serverName != "" {
BConfig.ServerName = serverName
}
if flashname := AppConfig.String("FlashName"); flashname != "" {
BConfig.WebConfig.FlashName = flashname
}
if flashseperator := AppConfig.String("FlashSeperator"); flashseperator != "" {
BConfig.WebConfig.FlashSeperator = flashseperator
}
if sd := AppConfig.String("StaticDir"); sd != "" {
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 {
BConfig.WebConfig.StaticDir["/"+strings.TrimRight(url2fsmap[0], "/")] = url2fsmap[1]
} else {
BConfig.WebConfig.StaticDir["/"+strings.TrimRight(url2fsmap[0], "/")] = url2fsmap[0]
}
}
}
if sgz := AppConfig.String("StaticExtensionsToGzip"); sgz != "" {
extensions := strings.Split(sgz, ",")
fileExts := []string{}
for _, ext := range extensions {
ext = strings.TrimSpace(ext)
if ext == "" {
continue
}
if !strings.HasPrefix(ext, ".") {
ext = "." + ext
}
fileExts = append(fileExts, ext)
}
if len(fileExts) > 0 {
BConfig.WebConfig.StaticExtensionsToGzip = fileExts
}
}
if enableadmin, err := AppConfig.Bool("EnableAdmin"); err == nil {
BConfig.Listen.AdminEnable = enableadmin
}
if adminhttpaddr := AppConfig.String("AdminHTTPAddr"); adminhttpaddr != "" {
BConfig.Listen.AdminAddr = adminhttpaddr
}
if adminhttpport, err := AppConfig.Int("AdminHTTPPort"); err == nil {
BConfig.Listen.AdminPort = adminhttpport
}
if enabledocs, err := AppConfig.Bool("EnableDocs"); err == nil {
BConfig.WebConfig.EnableDocs = enabledocs
}
if casesensitive, err := AppConfig.Bool("RouterCaseSensitive"); err == nil {
BConfig.RouterCaseSensitive = casesensitive
}
if graceful, err := AppConfig.Bool("Graceful"); err == nil {
BConfig.Listen.Graceful = graceful
}
return nil
}
type beegoAppConfig struct {
innerConfig config.Configer
}
@ -154,7 +395,7 @@ func newAppConfig(AppConfigProvider, AppConfigPath string) (*beegoAppConfig, err
}
func (b *beegoAppConfig) Set(key, val string) error {
err := b.innerConfig.Set(RunMode+"::"+key, val)
err := b.innerConfig.Set(BConfig.RunMode+"::"+key, val)
if err == nil {
return err
}
@ -162,7 +403,7 @@ func (b *beegoAppConfig) Set(key, val string) error {
}
func (b *beegoAppConfig) String(key string) string {
v := b.innerConfig.String(RunMode + "::" + key)
v := b.innerConfig.String(BConfig.RunMode + "::" + key)
if v == "" {
return b.innerConfig.String(key)
}
@ -170,7 +411,7 @@ func (b *beegoAppConfig) String(key string) string {
}
func (b *beegoAppConfig) Strings(key string) []string {
v := b.innerConfig.Strings(RunMode + "::" + key)
v := b.innerConfig.Strings(BConfig.RunMode + "::" + key)
if v[0] == "" {
return b.innerConfig.Strings(key)
}
@ -178,7 +419,7 @@ func (b *beegoAppConfig) Strings(key string) []string {
}
func (b *beegoAppConfig) Int(key string) (int, error) {
v, err := b.innerConfig.Int(RunMode + "::" + key)
v, err := b.innerConfig.Int(BConfig.RunMode + "::" + key)
if err != nil {
return b.innerConfig.Int(key)
}
@ -186,7 +427,7 @@ func (b *beegoAppConfig) Int(key string) (int, error) {
}
func (b *beegoAppConfig) Int64(key string) (int64, error) {
v, err := b.innerConfig.Int64(RunMode + "::" + key)
v, err := b.innerConfig.Int64(BConfig.RunMode + "::" + key)
if err != nil {
return b.innerConfig.Int64(key)
}
@ -194,7 +435,7 @@ func (b *beegoAppConfig) Int64(key string) (int64, error) {
}
func (b *beegoAppConfig) Bool(key string) (bool, error) {
v, err := b.innerConfig.Bool(RunMode + "::" + key)
v, err := b.innerConfig.Bool(BConfig.RunMode + "::" + key)
if err != nil {
return b.innerConfig.Bool(key)
}
@ -202,7 +443,7 @@ func (b *beegoAppConfig) Bool(key string) (bool, error) {
}
func (b *beegoAppConfig) Float(key string) (float64, error) {
v, err := b.innerConfig.Float(RunMode + "::" + key)
v, err := b.innerConfig.Float(BConfig.RunMode + "::" + key)
if err != nil {
return b.innerConfig.Float(key)
}
@ -268,300 +509,3 @@ func (b *beegoAppConfig) GetSection(section string) (map[string]string, error) {
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)
} 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}
}
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
}
envRunMode := os.Getenv("BEEGO_RUNMODE")
// set the runmode first
if envRunMode != "" {
RunMode = envRunMode
} else if runmode := AppConfig.String("RunMode"); runmode != "" {
RunMode = runmode
}
HTTPAddr = AppConfig.String("HTTPAddr")
if v, err := AppConfig.Int("HTTPPort"); err == nil {
HTTPPort = v
}
if v, err := AppConfig.Bool("ListenTCP4"); err == nil {
ListenTCP4 = v
}
if v, err := AppConfig.Bool("EnableHTTPListen"); err == nil {
EnableHTTPListen = v
}
if maxmemory, err := AppConfig.Int64("MaxMemory"); err == nil {
MaxMemory = maxmemory
}
if appname := AppConfig.String("AppName"); appname != "" {
AppName = appname
}
if autorender, err := AppConfig.Bool("AutoRender"); err == nil {
AutoRender = autorender
}
if autorecover, err := AppConfig.Bool("RecoverPanic"); err == nil {
RecoverPanic = autorecover
}
if views := AppConfig.String("ViewsPath"); views != "" {
ViewsPath = views
}
if sessionon, err := AppConfig.Bool("SessionOn"); err == nil {
SessionOn = sessionon
}
if sessProvider := AppConfig.String("SessionProvider"); sessProvider != "" {
SessionProvider = sessProvider
}
if sessName := AppConfig.String("SessionName"); sessName != "" {
SessionName = sessName
}
if sessProvConfig := AppConfig.String("SessionProviderConfig"); sessProvConfig != "" {
SessionProviderConfig = sessProvConfig
}
if sessMaxLifeTime, err := AppConfig.Int64("SessionGCMaxLifetime"); err == nil && sessMaxLifeTime != 0 {
SessionGCMaxLifetime = sessMaxLifeTime
}
if sesscookielifetime, err := AppConfig.Int("SessionCookieLifeTime"); err == nil && sesscookielifetime != 0 {
SessionCookieLifeTime = sesscookielifetime
}
if enableFcgi, err := AppConfig.Bool("EnableFcgi"); err == nil {
EnableFcgi = enableFcgi
}
if enablegzip, err := AppConfig.Bool("EnableGzip"); err == nil {
EnableGzip = enablegzip
}
if directoryindex, err := AppConfig.Bool("DirectoryIndex"); err == nil {
DirectoryIndex = directoryindex
}
if timeout, err := AppConfig.Int64("HTTPServerTimeOut"); err == nil {
HTTPServerTimeOut = timeout
}
if errorsshow, err := AppConfig.Bool("EnableErrorsShow"); err == nil {
EnableErrorsShow = errorsshow
}
if copyrequestbody, err := AppConfig.Bool("CopyRequestBody"); err == nil {
CopyRequestBody = copyrequestbody
}
if xsrfkey := AppConfig.String("XSRFKEY"); xsrfkey != "" {
XSRFKEY = xsrfkey
}
if enablexsrf, err := AppConfig.Bool("EnableXSRF"); err == nil {
EnableXSRF = enablexsrf
}
if expire, err := AppConfig.Int("XSRFExpire"); err == nil {
XSRFExpire = expire
}
if tplleft := AppConfig.String("TemplateLeft"); tplleft != "" {
TemplateLeft = tplleft
}
if tplright := AppConfig.String("TemplateRight"); tplright != "" {
TemplateRight = tplright
}
if httptls, err := AppConfig.Bool("EnableHTTPTLS"); err == nil {
EnableHTTPTLS = httptls
}
if httpsport, err := AppConfig.Int("HTTPSPort"); err == nil {
HTTPSPort = httpsport
}
if certfile := AppConfig.String("HTTPCertFile"); certfile != "" {
HTTPCertFile = certfile
}
if keyfile := AppConfig.String("HTTPKeyFile"); keyfile != "" {
HTTPKeyFile = keyfile
}
if serverName := AppConfig.String("BeegoServerName"); serverName != "" {
BeegoServerName = serverName
}
if flashname := AppConfig.String("FlashName"); flashname != "" {
FlashName = flashname
}
if flashseperator := AppConfig.String("FlashSeperator"); flashseperator != "" {
FlashSeperator = flashseperator
}
if sd := AppConfig.String("StaticDir"); sd != "" {
for k := range StaticDir {
delete(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]
} else {
StaticDir["/"+strings.TrimRight(url2fsmap[0], "/")] = url2fsmap[0]
}
}
}
if sgz := AppConfig.String("StaticExtensionsToGzip"); sgz != "" {
extensions := strings.Split(sgz, ",")
fileExts := []string{}
for _, ext := range extensions {
ext = strings.TrimSpace(ext)
if ext == "" {
continue
}
if !strings.HasPrefix(ext, ".") {
ext = "." + ext
}
fileExts = append(fileExts, ext)
}
if len(fileExts) > 0 {
StaticExtensionsToGzip = fileExts
}
}
if enableadmin, err := AppConfig.Bool("EnableAdmin"); err == nil {
EnableAdmin = enableadmin
}
if adminhttpaddr := AppConfig.String("AdminHTTPAddr"); adminhttpaddr != "" {
AdminHTTPAddr = adminhttpaddr
}
if adminhttpport, err := AppConfig.Int("AdminHTTPPort"); err == nil {
AdminHTTPPort = adminhttpport
}
if enabledocs, err := AppConfig.Bool("EnableDocs"); err == nil {
EnableDocs = enabledocs
}
if casesensitive, err := AppConfig.Bool("RouterCaseSensitive"); err == nil {
RouterCaseSensitive = casesensitive
}
if graceful, err := AppConfig.Bool("Graceful"); err == nil {
Graceful = graceful
}
return nil
}

View File

@ -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.")
}
}

View File

@ -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
}

View File

@ -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)

View File

@ -24,7 +24,7 @@ import (
var GlobalDocAPI map[string]interface{}
func init() {
if EnableDocs {
if BConfig.WebConfig.EnableDocs {
GlobalDocAPI = make(map[string]interface{})
}
}

View File

@ -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)
}

View File

@ -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"]))
}

View File

@ -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

View File

@ -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

View File

@ -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) {

View File

@ -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,

View File

@ -1,140 +0,0 @@
// 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}
}

View File

@ -1,88 +0,0 @@
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")
}
}

View File

@ -1,15 +0,0 @@
-----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-----

View File

@ -1,6 +0,0 @@
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCdu+23Y/0J/FTQKnIPnxupoOo9
/OYCv90DPXN/KLLRAMjYzgcCDsBST2xVR5jlimI/gyfCpVB62dwpSzzr0cA3MoDh
baGWuTdQUX9zmiLoQ4I7X6h0dwyiihOz+CzOMlAg5+qBhiTGcKvIFlfEc1FUcn/t
B3PVRG9j6B1Ibz5CnQIDAQAB
-----END PUBLIC KEY-----

View File

@ -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)
}
}

View File

@ -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
}

View File

@ -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
}