config.go 13.4 KB
Newer Older
A
astaxie 已提交
1
// Copyright 2014 beego Author. All Rights Reserved.
A
astaxie 已提交
2
//
A
astaxie 已提交
3 4 5
// 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
A
astaxie 已提交
6
//
A
astaxie 已提交
7
//      http://www.apache.org/licenses/LICENSE-2.0
A
astaxie 已提交
8
//
A
astaxie 已提交
9 10 11 12 13 14
// 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.

15 16 17 18 19
package beego

import (
	"html/template"
	"os"
20
	"path/filepath"
21
	"strings"
P
Pengfei Xue 已提交
22 23 24

	"github.com/astaxie/beego/config"
	"github.com/astaxie/beego/session"
25
	"github.com/astaxie/beego/utils"
26 27
)

A
astaxie 已提交
28 29
// BeegoConfig is the main struct for BConfig
type Config struct {
A
astaxie 已提交
30 31
	AppName             string //Application name
	RunMode             string //Running Mode: dev | prod
32
	RouterCaseSensitive bool
A
astaxie 已提交
33 34 35 36 37 38 39 40 41
	ServerName          string
	RecoverPanic        bool
	CopyRequestBody     bool
	EnableGzip          bool
	MaxMemory           int64
	EnableErrorsShow    bool
	Listen              Listen
	WebConfig           WebConfig
	Log                 LogConfig
A
astaxie 已提交
42 43
}

A
astaxie 已提交
44
// Listen holds for http and https related config
A
astaxie 已提交
45 46 47 48
type Listen struct {
	Graceful      bool // Graceful means use graceful module to start the server
	ServerTimeOut int64
	ListenTCP4    bool
A
astaxie 已提交
49
	EnableHTTP    bool
A
astaxie 已提交
50 51
	HTTPAddr      string
	HTTPPort      int
A
astaxie 已提交
52
	EnableHTTPS   bool
A
astaxie 已提交
53 54 55 56
	HTTPSAddr     string
	HTTPSPort     int
	HTTPSCertFile string
	HTTPSKeyFile  string
A
astaxie 已提交
57
	EnableAdmin   bool
A
astaxie 已提交
58 59 60 61
	AdminAddr     string
	AdminPort     int
	EnableFcgi    bool
	EnableStdIo   bool // EnableStdIo works with EnableFcgi Use FCGI via standard I/O
A
astaxie 已提交
62 63
}

A
astaxie 已提交
64
// WebConfig holds web related config
A
astaxie 已提交
65 66 67 68
type WebConfig struct {
	AutoRender             bool
	EnableDocs             bool
	FlashName              string
J
JessonChan 已提交
69
	FlashSeparator         string
A
astaxie 已提交
70 71 72 73 74 75 76
	DirectoryIndex         bool
	StaticDir              map[string]string
	StaticExtensionsToGzip []string
	TemplateLeft           string
	TemplateRight          string
	ViewsPath              string
	EnableXSRF             bool
J
JessonChan 已提交
77
	XSRFKey                string
A
astaxie 已提交
78 79
	XSRFExpire             int
	Session                SessionConfig
A
astaxie 已提交
80 81
}

A
astaxie 已提交
82
// SessionConfig holds session related config
A
astaxie 已提交
83 84 85 86 87 88 89 90 91
type SessionConfig struct {
	SessionOn             bool
	SessionProvider       string
	SessionName           string
	SessionGCMaxLifetime  int64
	SessionProviderConfig string
	SessionCookieLifeTime int
	SessionAutoSetCookie  bool
	SessionDomain         string
A
astaxie 已提交
92 93
}

A
astaxie 已提交
94
// LogConfig holds Log related config
A
astaxie 已提交
95 96 97
type LogConfig struct {
	AccessLogs  bool
	FileLineNum bool
A
astaxie 已提交
98
	Outputs     map[string]string // Store Adaptor : config
A
astaxie 已提交
99 100
}

A
astaxie 已提交
101 102
var (
	// BConfig is the default config for Application
A
astaxie 已提交
103
	BConfig *Config
A
astaxie 已提交
104 105 106 107 108 109 110 111 112 113 114
	// 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
)
A
astaxie 已提交
115

A
astaxie 已提交
116
func init() {
A
astaxie 已提交
117
	BConfig = &Config{
A
astaxie 已提交
118
		AppName:             "beego",
119
		RunMode:             DEV,
A
astaxie 已提交
120 121 122 123 124 125 126 127 128 129 130
		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,
A
astaxie 已提交
131
			EnableHTTP:    true,
A
astaxie 已提交
132 133
			HTTPAddr:      "",
			HTTPPort:      8080,
A
astaxie 已提交
134
			EnableHTTPS:   false,
A
astaxie 已提交
135 136 137 138
			HTTPSAddr:     "",
			HTTPSPort:     10443,
			HTTPSCertFile: "",
			HTTPSKeyFile:  "",
A
astaxie 已提交
139
			EnableAdmin:   false,
A
astaxie 已提交
140 141 142 143 144 145 146 147 148
			AdminAddr:     "",
			AdminPort:     8088,
			EnableFcgi:    false,
			EnableStdIo:   false,
		},
		WebConfig: WebConfig{
			AutoRender:             true,
			EnableDocs:             false,
			FlashName:              "BEEGO_FLASH",
J
JessonChan 已提交
149
			FlashSeparator:         "BEEGOFLASH",
A
astaxie 已提交
150 151 152 153 154 155 156
			DirectoryIndex:         false,
			StaticDir:              map[string]string{"/static": "static"},
			StaticExtensionsToGzip: []string{".css", ".js"},
			TemplateLeft:           "{{",
			TemplateRight:          "}}",
			ViewsPath:              "views",
			EnableXSRF:             false,
J
JessonChan 已提交
157
			XSRFKey:                "beegoxsrf",
A
astaxie 已提交
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
			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,
A
astaxie 已提交
173
			Outputs:     map[string]string{"console": ""},
A
astaxie 已提交
174
		},
A
astaxie 已提交
175
	}
A
astaxie 已提交
176
	ParseConfig()
A
astaxie 已提交
177 178
}

A
astaxie 已提交
179 180 181 182 183 184
// 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")
185
		} else {
F
fuxiaohei 已提交
186
			AppConfig = &beegoAppConfig{config.NewFakeConfig()}
A
astaxie 已提交
187
			return
R
Ryan A. Chapman 已提交
188
		}
P
Pengfei Xue 已提交
189
	}
A
astaxie 已提交
190 191 192 193
	AppConfig, err = newAppConfig(AppConfigProvider, AppConfigPath)
	if err != nil {
		return err
	}
A
astaxie 已提交
194
	// set the runmode first
F
fuxiaohei 已提交
195
	if envRunMode := os.Getenv("BEEGO_RUNMODE"); envRunMode != "" {
A
astaxie 已提交
196
		BConfig.RunMode = envRunMode
197
	} else if runmode := AppConfig.String("RunMode"); runmode != "" {
A
astaxie 已提交
198
		BConfig.RunMode = runmode
A
astaxie 已提交
199
	}
200

A
astaxie 已提交
201 202 203
	BConfig.AppName = AppConfig.DefaultString("AppName", BConfig.AppName)
	BConfig.RecoverPanic = AppConfig.DefaultBool("RecoverPanic", BConfig.RecoverPanic)
	BConfig.RouterCaseSensitive = AppConfig.DefaultBool("RouterCaseSensitive", BConfig.RouterCaseSensitive)
A
astaxie 已提交
204
	BConfig.ServerName = AppConfig.DefaultString("ServerName", BConfig.ServerName)
A
astaxie 已提交
205 206 207 208 209
	BConfig.EnableGzip = AppConfig.DefaultBool("EnableGzip", BConfig.EnableGzip)
	BConfig.EnableErrorsShow = AppConfig.DefaultBool("EnableErrorsShow", BConfig.EnableErrorsShow)
	BConfig.CopyRequestBody = AppConfig.DefaultBool("CopyRequestBody", BConfig.CopyRequestBody)
	BConfig.MaxMemory = AppConfig.DefaultInt64("MaxMemory", BConfig.MaxMemory)
	BConfig.Listen.Graceful = AppConfig.DefaultBool("Graceful", BConfig.Listen.Graceful)
A
astaxie 已提交
210
	BConfig.Listen.HTTPAddr = AppConfig.String("HTTPAddr")
A
astaxie 已提交
211 212
	BConfig.Listen.HTTPPort = AppConfig.DefaultInt("HTTPPort", BConfig.Listen.HTTPPort)
	BConfig.Listen.ListenTCP4 = AppConfig.DefaultBool("ListenTCP4", BConfig.Listen.ListenTCP4)
A
astaxie 已提交
213 214
	BConfig.Listen.EnableHTTP = AppConfig.DefaultBool("EnableHTTP", BConfig.Listen.EnableHTTP)
	BConfig.Listen.EnableHTTPS = AppConfig.DefaultBool("EnableHTTPS", BConfig.Listen.EnableHTTPS)
A
astaxie 已提交
215
	BConfig.Listen.HTTPSAddr = AppConfig.DefaultString("HTTPSAddr", BConfig.Listen.HTTPSAddr)
A
astaxie 已提交
216
	BConfig.Listen.HTTPSPort = AppConfig.DefaultInt("HTTPSPort", BConfig.Listen.HTTPSPort)
A
astaxie 已提交
217 218 219 220 221
	BConfig.Listen.HTTPSCertFile = AppConfig.DefaultString("HTTPSCertFile", BConfig.Listen.HTTPSCertFile)
	BConfig.Listen.HTTPSKeyFile = AppConfig.DefaultString("HTTPSKeyFile", BConfig.Listen.HTTPSKeyFile)
	BConfig.Listen.EnableAdmin = AppConfig.DefaultBool("EnableAdmin", BConfig.Listen.EnableAdmin)
	BConfig.Listen.AdminAddr = AppConfig.DefaultString("AdminAddr", BConfig.Listen.AdminAddr)
	BConfig.Listen.AdminPort = AppConfig.DefaultInt("AdminPort", BConfig.Listen.AdminPort)
A
astaxie 已提交
222
	BConfig.Listen.EnableFcgi = AppConfig.DefaultBool("EnableFcgi", BConfig.Listen.EnableFcgi)
A
astaxie 已提交
223
	BConfig.Listen.EnableStdIo = AppConfig.DefaultBool("EnableStdIo", BConfig.Listen.EnableStdIo)
A
astaxie 已提交
224
	BConfig.Listen.ServerTimeOut = AppConfig.DefaultInt64("ServerTimeOut", BConfig.Listen.ServerTimeOut)
A
astaxie 已提交
225 226 227
	BConfig.WebConfig.AutoRender = AppConfig.DefaultBool("AutoRender", BConfig.WebConfig.AutoRender)
	BConfig.WebConfig.ViewsPath = AppConfig.DefaultString("ViewsPath", BConfig.WebConfig.ViewsPath)
	BConfig.WebConfig.DirectoryIndex = AppConfig.DefaultBool("DirectoryIndex", BConfig.WebConfig.DirectoryIndex)
A
astaxie 已提交
228
	BConfig.WebConfig.FlashName = AppConfig.DefaultString("FlashName", BConfig.WebConfig.FlashName)
J
JessonChan 已提交
229
	BConfig.WebConfig.FlashSeparator = AppConfig.DefaultString("FlashSeparator", BConfig.WebConfig.FlashSeparator)
A
astaxie 已提交
230
	BConfig.WebConfig.EnableDocs = AppConfig.DefaultBool("EnableDocs", BConfig.WebConfig.EnableDocs)
J
JessonChan 已提交
231
	BConfig.WebConfig.XSRFKey = AppConfig.DefaultString("XSRFKEY", BConfig.WebConfig.XSRFKey)
A
astaxie 已提交
232 233 234 235 236 237 238 239 240 241
	BConfig.WebConfig.EnableXSRF = AppConfig.DefaultBool("EnableXSRF", BConfig.WebConfig.EnableXSRF)
	BConfig.WebConfig.XSRFExpire = AppConfig.DefaultInt("XSRFExpire", BConfig.WebConfig.XSRFExpire)
	BConfig.WebConfig.TemplateLeft = AppConfig.DefaultString("TemplateLeft", BConfig.WebConfig.TemplateLeft)
	BConfig.WebConfig.TemplateRight = AppConfig.DefaultString("TemplateRight", BConfig.WebConfig.TemplateRight)
	BConfig.WebConfig.Session.SessionOn = AppConfig.DefaultBool("SessionOn", BConfig.WebConfig.Session.SessionOn)
	BConfig.WebConfig.Session.SessionProvider = AppConfig.DefaultString("SessionProvider", BConfig.WebConfig.Session.SessionProvider)
	BConfig.WebConfig.Session.SessionName = AppConfig.DefaultString("SessionName", BConfig.WebConfig.Session.SessionName)
	BConfig.WebConfig.Session.SessionProviderConfig = AppConfig.DefaultString("SessionProviderConfig", BConfig.WebConfig.Session.SessionProviderConfig)
	BConfig.WebConfig.Session.SessionGCMaxLifetime = AppConfig.DefaultInt64("SessionGCMaxLifetime", BConfig.WebConfig.Session.SessionGCMaxLifetime)
	BConfig.WebConfig.Session.SessionCookieLifeTime = AppConfig.DefaultInt("SessionCookieLifeTime", BConfig.WebConfig.Session.SessionCookieLifeTime)
A
astaxie 已提交
242 243
	BConfig.WebConfig.Session.SessionAutoSetCookie = AppConfig.DefaultBool("SessionAutoSetCookie", BConfig.WebConfig.Session.SessionAutoSetCookie)
	BConfig.WebConfig.Session.SessionDomain = AppConfig.DefaultString("SessionDomain", BConfig.WebConfig.Session.SessionDomain)
A
astaxie 已提交
244

A
astaxie 已提交
245
	if sd := AppConfig.String("StaticDir"); sd != "" {
A
astaxie 已提交
246 247
		for k := range BConfig.WebConfig.StaticDir {
			delete(BConfig.WebConfig.StaticDir, k)
A
astaxie 已提交
248 249 250 251
		}
		sds := strings.Fields(sd)
		for _, v := range sds {
			if url2fsmap := strings.SplitN(v, ":", 2); len(url2fsmap) == 2 {
A
astaxie 已提交
252
				BConfig.WebConfig.StaticDir["/"+strings.TrimRight(url2fsmap[0], "/")] = url2fsmap[1]
A
astaxie 已提交
253
			} else {
A
astaxie 已提交
254
				BConfig.WebConfig.StaticDir["/"+strings.TrimRight(url2fsmap[0], "/")] = url2fsmap[0]
255 256
			}
		}
A
astaxie 已提交
257
	}
258

A
astaxie 已提交
259 260
	if sgz := AppConfig.String("StaticExtensionsToGzip"); sgz != "" {
		extensions := strings.Split(sgz, ",")
J
JessonChan 已提交
261
		fileExts := []string{}
J
JessonChan 已提交
262 263 264 265
		for _, ext := range extensions {
			ext = strings.TrimSpace(ext)
			if ext == "" {
				continue
F
Francois 已提交
266
			}
J
JessonChan 已提交
267 268 269
			if !strings.HasPrefix(ext, ".") {
				ext = "." + ext
			}
J
JessonChan 已提交
270 271 272
			fileExts = append(fileExts, ext)
		}
		if len(fileExts) > 0 {
A
astaxie 已提交
273
			BConfig.WebConfig.StaticExtensionsToGzip = fileExts
F
Francois 已提交
274
		}
A
astaxie 已提交
275 276
	}
	return nil
277
}
A
astaxie 已提交
278 279 280 281 282 283 284 285 286 287

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
	}
F
fuxiaohei 已提交
288
	return &beegoAppConfig{ac}, nil
A
astaxie 已提交
289 290 291
}

func (b *beegoAppConfig) Set(key, val string) error {
F
fuxiaohei 已提交
292
	if err := b.innerConfig.Set(BConfig.RunMode+"::"+key, val); err != nil {
A
astaxie 已提交
293 294 295 296 297 298
		return err
	}
	return b.innerConfig.Set(key, val)
}

func (b *beegoAppConfig) String(key string) string {
F
fuxiaohei 已提交
299 300
	if v := b.innerConfig.String(BConfig.RunMode + "::" + key); v != "" {
		return v
A
astaxie 已提交
301
	}
F
fuxiaohei 已提交
302
	return b.innerConfig.String(key)
A
astaxie 已提交
303 304 305
}

func (b *beegoAppConfig) Strings(key string) []string {
F
fuxiaohei 已提交
306
	if v := b.innerConfig.Strings(BConfig.RunMode + "::" + key); v[0] != "" {
F
fud 已提交
307
		return v
A
astaxie 已提交
308
	}
F
fuxiaohei 已提交
309
	return b.innerConfig.Strings(key)
A
astaxie 已提交
310 311 312
}

func (b *beegoAppConfig) Int(key string) (int, error) {
F
fuxiaohei 已提交
313 314
	if v, err := b.innerConfig.Int(BConfig.RunMode + "::" + key); err == nil {
		return v, nil
A
astaxie 已提交
315
	}
F
fuxiaohei 已提交
316
	return b.innerConfig.Int(key)
A
astaxie 已提交
317 318 319
}

func (b *beegoAppConfig) Int64(key string) (int64, error) {
F
fuxiaohei 已提交
320 321
	if v, err := b.innerConfig.Int64(BConfig.RunMode + "::" + key); err == nil {
		return v, nil
A
astaxie 已提交
322
	}
F
fuxiaohei 已提交
323
	return b.innerConfig.Int64(key)
A
astaxie 已提交
324 325 326
}

func (b *beegoAppConfig) Bool(key string) (bool, error) {
F
fuxiaohei 已提交
327 328
	if v, err := b.innerConfig.Bool(BConfig.RunMode + "::" + key); err == nil {
		return v, nil
A
astaxie 已提交
329
	}
F
fuxiaohei 已提交
330
	return b.innerConfig.Bool(key)
A
astaxie 已提交
331 332 333
}

func (b *beegoAppConfig) Float(key string) (float64, error) {
F
fuxiaohei 已提交
334 335
	if v, err := b.innerConfig.Float(BConfig.RunMode + "::" + key); err == nil {
		return v, nil
A
astaxie 已提交
336
	}
F
fuxiaohei 已提交
337
	return b.innerConfig.Float(key)
A
astaxie 已提交
338 339 340
}

func (b *beegoAppConfig) DefaultString(key string, defaultval string) string {
F
fuxiaohei 已提交
341
	if v := b.String(key); v != "" {
A
astaxie 已提交
342 343 344 345 346 347
		return v
	}
	return defaultval
}

func (b *beegoAppConfig) DefaultStrings(key string, defaultval []string) []string {
F
fuxiaohei 已提交
348
	if v := b.Strings(key); len(v) != 0 {
A
astaxie 已提交
349 350 351 352 353 354
		return v
	}
	return defaultval
}

func (b *beegoAppConfig) DefaultInt(key string, defaultval int) int {
F
fuxiaohei 已提交
355
	if v, err := b.Int(key); err == nil {
A
astaxie 已提交
356 357 358 359 360 361
		return v
	}
	return defaultval
}

func (b *beegoAppConfig) DefaultInt64(key string, defaultval int64) int64 {
F
fuxiaohei 已提交
362
	if v, err := b.Int64(key); err == nil {
A
astaxie 已提交
363 364 365 366 367 368
		return v
	}
	return defaultval
}

func (b *beegoAppConfig) DefaultBool(key string, defaultval bool) bool {
F
fuxiaohei 已提交
369
	if v, err := b.Bool(key); err == nil {
A
astaxie 已提交
370 371 372 373 374 375
		return v
	}
	return defaultval
}

func (b *beegoAppConfig) DefaultFloat(key string, defaultval float64) float64 {
F
fuxiaohei 已提交
376
	if v, err := b.Float(key); err == nil {
A
astaxie 已提交
377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392
		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)
}