config.go 15.0 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
package beego

import (
A
astaxie 已提交
18
	"fmt"
19 20
	"html/template"
	"os"
21
	"path/filepath"
22 23
	"runtime"
	"strings"
P
Pengfei Xue 已提交
24 25

	"github.com/astaxie/beego/config"
26
	"github.com/astaxie/beego/logs"
P
Pengfei Xue 已提交
27
	"github.com/astaxie/beego/session"
28
	"github.com/astaxie/beego/utils"
29 30 31
)

var (
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
	// 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
J
John Deng 已提交
63 64
	// EnableFcgi turn on the fcgi Listen, default is false
	EnableFcgi bool
65 66 67 68 69 70
	// 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
J
John Deng 已提交
71
	// EnableStdIo works with EnableFcgi Use FCGI via standard I/O
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
	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
	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
141 142
)

B
Bill Davis 已提交
143
type beegoAppConfig struct {
A
astaxie 已提交
144
	innerConfig config.Configer
B
Bill Davis 已提交
145
}
A
astaxie 已提交
146

A
astaxie 已提交
147
func newAppConfig(AppConfigProvider, AppConfigPath string) (*beegoAppConfig, error) {
A
astaxie 已提交
148 149
	ac, err := config.NewConfig(AppConfigProvider, AppConfigPath)
	if err != nil {
A
astaxie 已提交
150
		return nil, err
A
astaxie 已提交
151 152
	}
	rac := &beegoAppConfig{ac}
A
astaxie 已提交
153
	return rac, nil
A
astaxie 已提交
154 155 156
}

func (b *beegoAppConfig) Set(key, val string) error {
A
astaxie 已提交
157 158 159 160
	err := b.innerConfig.Set(RunMode+"::"+key, val)
	if err == nil {
		return err
	}
A
astaxie 已提交
161 162 163 164 165 166 167 168 169 170 171 172 173
	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)
G
git 已提交
174
	if v[0] == "" {
A
astaxie 已提交
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
		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
}

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
}

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 {
A
astaxie 已提交
213 214 215 216
	v := b.String(key)
	if v != "" {
		return v
	}
A
astaxie 已提交
217
	return defaultval
A
astaxie 已提交
218 219 220
}

func (b *beegoAppConfig) DefaultStrings(key string, defaultval []string) []string {
A
astaxie 已提交
221 222 223 224
	v := b.Strings(key)
	if len(v) != 0 {
		return v
	}
A
astaxie 已提交
225
	return defaultval
A
astaxie 已提交
226 227 228
}

func (b *beegoAppConfig) DefaultInt(key string, defaultval int) int {
A
astaxie 已提交
229 230 231 232
	v, err := b.Int(key)
	if err == nil {
		return v
	}
A
astaxie 已提交
233
	return defaultval
A
astaxie 已提交
234 235 236
}

func (b *beegoAppConfig) DefaultInt64(key string, defaultval int64) int64 {
A
astaxie 已提交
237 238 239 240
	v, err := b.Int64(key)
	if err == nil {
		return v
	}
A
astaxie 已提交
241
	return defaultval
A
astaxie 已提交
242 243 244
}

func (b *beegoAppConfig) DefaultBool(key string, defaultval bool) bool {
A
astaxie 已提交
245 246 247 248
	v, err := b.Bool(key)
	if err == nil {
		return v
	}
A
astaxie 已提交
249
	return defaultval
A
astaxie 已提交
250 251 252
}

func (b *beegoAppConfig) DefaultFloat(key string, defaultval float64) float64 {
A
astaxie 已提交
253 254 255 256
	v, err := b.Float(key)
	if err == nil {
		return v
	}
A
astaxie 已提交
257
	return defaultval
A
astaxie 已提交
258 259 260 261 262 263 264 265 266 267 268 269 270 271
}

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

A
astaxie 已提交
272
func init() {
273 274
	workPath, _ = os.Getwd()
	workPath, _ = filepath.Abs(workPath)
P
Pengfei Xue 已提交
275
	// initialize default configurations
276
	AppPath, _ = filepath.Abs(filepath.Dir(os.Args[0]))
277 278 279 280 281 282 283 284 285 286

	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")
		}
	}
P
Pengfei Xue 已提交
287

A
astaxie 已提交
288 289
	AppConfigProvider = "ini"

290
	StaticDir = make(map[string]string)
P
Pengfei Xue 已提交
291
	StaticDir["/static"] = "static"
292

F
Francois 已提交
293
	StaticExtensionsToGzip = []string{".css", ".js"}
P
Pengfei Xue 已提交
294

A
typo  
astaxie 已提交
295
	TemplateCache = make(map[string]*template.Template)
P
Pengfei Xue 已提交
296 297

	// set this to 0.0.0.0 to make this app available to externally
298
	EnableHTTPListen = true //default enable http Listen
A
astaxie 已提交
299

300 301
	HTTPAddr = ""
	HTTPPort = 8080
P
Pengfei Xue 已提交
302

303
	HTTPSPort = 10443
A
astaxie 已提交
304

305
	AppName = "beego"
P
Pengfei Xue 已提交
306

307
	RunMode = "dev" //default runmod
P
Pengfei Xue 已提交
308

309
	AutoRender = true
P
Pengfei Xue 已提交
310

311
	RecoverPanic = true
P
Pengfei Xue 已提交
312

313
	ViewsPath = "views"
P
Pengfei Xue 已提交
314

315 316 317 318
	SessionOn = false
	SessionProvider = "memory"
	SessionName = "beegosessionID"
	SessionGCMaxLifetime = 3600
319
	SessionProviderConfig = ""
A
astaxie 已提交
320
	SessionCookieLifeTime = 0 //set cookie default is the brower life
A
astaxie 已提交
321
	SessionAutoSetCookie = true
P
Pengfei Xue 已提交
322

傅小黑 已提交
323
	MaxMemory = 1 << 26 //64MB
P
Pengfei Xue 已提交
324

325
	HTTPServerTimeOut = 0
P
Pengfei Xue 已提交
326

327
	EnableErrorsShow = true
P
Pengfei Xue 已提交
328

329 330
	XSRFKEY = "beegoxsrf"
	XSRFExpire = 0
P
Pengfei Xue 已提交
331

332 333
	TemplateLeft = "{{"
	TemplateRight = "}}"
P
Pengfei Xue 已提交
334

A
astaxie 已提交
335
	BeegoServerName = "beegoServer:" + VERSION
P
Pengfei Xue 已提交
336

337
	EnableAdmin = false
338 339
	AdminHTTPAddr = "127.0.0.1"
	AdminHTTPPort = 8088
P
Pengfei Xue 已提交
340

341 342 343
	FlashName = "BEEGO_FLASH"
	FlashSeperator = "BEEGOFLASH"

A
astaxie 已提交
344 345
	RouterCaseSensitive = true

346
	runtime.GOMAXPROCS(runtime.NumCPU())
P
Pengfei Xue 已提交
347

348 349
	// init BeeLogger
	BeeLogger = logs.NewLogger(10000)
A
astaxie 已提交
350 351 352 353
	err := BeeLogger.SetLogger("console", "")
	if err != nil {
		fmt.Println("init console log error:", err)
	}
A
astaxie 已提交
354
	SetLogFuncCall(true)
355

A
astaxie 已提交
356
	err = ParseConfig()
R
Ryan A. Chapman 已提交
357 358 359 360 361 362
	if err != nil {
		if os.IsNotExist(err) {
			// for init if doesn't have app.conf will not panic
			ac := config.NewFakeConfig()
			AppConfig = &beegoAppConfig{ac}
		}
A
astaxie 已提交
363
		Warning(err)
P
Pengfei Xue 已提交
364
	}
365 366
}

367 368
// ParseConfig parsed default config file.
// now only support ini, next will support json.
369
func ParseConfig() (err error) {
A
astaxie 已提交
370 371 372 373
	AppConfig, err = newAppConfig(AppConfigProvider, AppConfigPath)
	if err != nil {
		return err
	}
B
Bill Davis 已提交
374
	envRunMode := os.Getenv("BEEGO_RUNMODE")
A
astaxie 已提交
375
	// set the runmode first
B
Bill Davis 已提交
376 377
	if envRunMode != "" {
		RunMode = envRunMode
378
	} else if runmode := AppConfig.String("RunMode"); runmode != "" {
A
astaxie 已提交
379 380
		RunMode = runmode
	}
381

382
	HTTPAddr = AppConfig.String("HTTPAddr")
383

384 385
	if v, err := AppConfig.Int("HTTPPort"); err == nil {
		HTTPPort = v
A
astaxie 已提交
386
	}
A
astaxie 已提交
387

A
astaxie 已提交
388 389 390 391
	if v, err := AppConfig.Bool("ListenTCP4"); err == nil {
		ListenTCP4 = v
	}

392 393
	if v, err := AppConfig.Bool("EnableHTTPListen"); err == nil {
		EnableHTTPListen = v
A
astaxie 已提交
394
	}
395

A
astaxie 已提交
396 397 398
	if maxmemory, err := AppConfig.Int64("MaxMemory"); err == nil {
		MaxMemory = maxmemory
	}
399

A
astaxie 已提交
400 401 402
	if appname := AppConfig.String("AppName"); appname != "" {
		AppName = appname
	}
403

A
astaxie 已提交
404 405 406
	if autorender, err := AppConfig.Bool("AutoRender"); err == nil {
		AutoRender = autorender
	}
407

A
astaxie 已提交
408 409 410
	if autorecover, err := AppConfig.Bool("RecoverPanic"); err == nil {
		RecoverPanic = autorecover
	}
411

A
astaxie 已提交
412 413 414
	if views := AppConfig.String("ViewsPath"); views != "" {
		ViewsPath = views
	}
415

A
astaxie 已提交
416 417 418
	if sessionon, err := AppConfig.Bool("SessionOn"); err == nil {
		SessionOn = sessionon
	}
419

A
astaxie 已提交
420 421 422
	if sessProvider := AppConfig.String("SessionProvider"); sessProvider != "" {
		SessionProvider = sessProvider
	}
423

A
astaxie 已提交
424 425 426
	if sessName := AppConfig.String("SessionName"); sessName != "" {
		SessionName = sessName
	}
427

428 429
	if sessProvConfig := AppConfig.String("SessionProviderConfig"); sessProvConfig != "" {
		SessionProviderConfig = sessProvConfig
A
astaxie 已提交
430
	}
431

A
astaxie 已提交
432 433 434
	if sessMaxLifeTime, err := AppConfig.Int64("SessionGCMaxLifetime"); err == nil && sessMaxLifeTime != 0 {
		SessionGCMaxLifetime = sessMaxLifeTime
	}
435

A
astaxie 已提交
436 437 438
	if sesscookielifetime, err := AppConfig.Int("SessionCookieLifeTime"); err == nil && sesscookielifetime != 0 {
		SessionCookieLifeTime = sesscookielifetime
	}
439

J
John Deng 已提交
440 441
	if enableFcgi, err := AppConfig.Bool("EnableFcgi"); err == nil {
		EnableFcgi = enableFcgi
A
astaxie 已提交
442
	}
443

A
astaxie 已提交
444 445 446
	if enablegzip, err := AppConfig.Bool("EnableGzip"); err == nil {
		EnableGzip = enablegzip
	}
447

A
astaxie 已提交
448 449 450
	if directoryindex, err := AppConfig.Bool("DirectoryIndex"); err == nil {
		DirectoryIndex = directoryindex
	}
451

452 453
	if timeout, err := AppConfig.Int64("HTTPServerTimeOut"); err == nil {
		HTTPServerTimeOut = timeout
A
astaxie 已提交
454
	}
455

456 457
	if errorsshow, err := AppConfig.Bool("EnableErrorsShow"); err == nil {
		EnableErrorsShow = errorsshow
A
astaxie 已提交
458
	}
459

A
astaxie 已提交
460 461 462
	if copyrequestbody, err := AppConfig.Bool("CopyRequestBody"); err == nil {
		CopyRequestBody = copyrequestbody
	}
463

A
astaxie 已提交
464 465 466
	if xsrfkey := AppConfig.String("XSRFKEY"); xsrfkey != "" {
		XSRFKEY = xsrfkey
	}
467

A
astaxie 已提交
468 469 470
	if enablexsrf, err := AppConfig.Bool("EnableXSRF"); err == nil {
		EnableXSRF = enablexsrf
	}
471

A
astaxie 已提交
472 473 474
	if expire, err := AppConfig.Int("XSRFExpire"); err == nil {
		XSRFExpire = expire
	}
475

A
astaxie 已提交
476 477 478
	if tplleft := AppConfig.String("TemplateLeft"); tplleft != "" {
		TemplateLeft = tplleft
	}
479

A
astaxie 已提交
480 481 482
	if tplright := AppConfig.String("TemplateRight"); tplright != "" {
		TemplateRight = tplright
	}
483

484 485
	if httptls, err := AppConfig.Bool("EnableHTTPTLS"); err == nil {
		EnableHTTPTLS = httptls
A
astaxie 已提交
486
	}
A
astaxie 已提交
487

488 489
	if httpsport, err := AppConfig.Int("HTTPSPort"); err == nil {
		HTTPSPort = httpsport
A
astaxie 已提交
490
	}
491

492 493
	if certfile := AppConfig.String("HTTPCertFile"); certfile != "" {
		HTTPCertFile = certfile
A
astaxie 已提交
494
	}
495

496 497
	if keyfile := AppConfig.String("HTTPKeyFile"); keyfile != "" {
		HTTPKeyFile = keyfile
A
astaxie 已提交
498
	}
499

A
astaxie 已提交
500 501 502
	if serverName := AppConfig.String("BeegoServerName"); serverName != "" {
		BeegoServerName = serverName
	}
503

A
astaxie 已提交
504 505 506
	if flashname := AppConfig.String("FlashName"); flashname != "" {
		FlashName = flashname
	}
507

A
astaxie 已提交
508 509 510
	if flashseperator := AppConfig.String("FlashSeperator"); flashseperator != "" {
		FlashSeperator = flashseperator
	}
511

A
astaxie 已提交
512 513 514 515 516 517 518 519 520 521
	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]
522 523
			}
		}
A
astaxie 已提交
524
	}
525

A
astaxie 已提交
526 527
	if sgz := AppConfig.String("StaticExtensionsToGzip"); sgz != "" {
		extensions := strings.Split(sgz, ",")
J
JessonChan 已提交
528
		fileExts := []string{}
J
JessonChan 已提交
529 530 531 532
		for _, ext := range extensions {
			ext = strings.TrimSpace(ext)
			if ext == "" {
				continue
F
Francois 已提交
533
			}
J
JessonChan 已提交
534 535 536
			if !strings.HasPrefix(ext, ".") {
				ext = "." + ext
			}
J
JessonChan 已提交
537 538 539 540
			fileExts = append(fileExts, ext)
		}
		if len(fileExts) > 0 {
			StaticExtensionsToGzip = fileExts
F
Francois 已提交
541
		}
A
astaxie 已提交
542
	}
543

A
astaxie 已提交
544 545 546
	if enableadmin, err := AppConfig.Bool("EnableAdmin"); err == nil {
		EnableAdmin = enableadmin
	}
547

548 549
	if adminhttpaddr := AppConfig.String("AdminHTTPAddr"); adminhttpaddr != "" {
		AdminHTTPAddr = adminhttpaddr
A
astaxie 已提交
550
	}
A
astaxie 已提交
551

552 553
	if adminhttpport, err := AppConfig.Int("AdminHTTPPort"); err == nil {
		AdminHTTPPort = adminhttpport
A
astaxie 已提交
554
	}
A
astaxie 已提交
555

A
astaxie 已提交
556 557
	if enabledocs, err := AppConfig.Bool("EnableDocs"); err == nil {
		EnableDocs = enabledocs
558
	}
559

A
astaxie 已提交
560 561
	if casesensitive, err := AppConfig.Bool("RouterCaseSensitive"); err == nil {
		RouterCaseSensitive = casesensitive
562
	}
563 564 565
	if graceful, err := AppConfig.Bool("Graceful"); err == nil {
		Graceful = graceful
	}
A
astaxie 已提交
566
	return nil
567
}