config.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. // Copyright 2014 beego Author. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package beego
  15. import (
  16. "fmt"
  17. "os"
  18. "path/filepath"
  19. "reflect"
  20. "runtime"
  21. "strings"
  22. "github.com/cnlh/nps/vender/github.com/astaxie/beego/config"
  23. "github.com/cnlh/nps/vender/github.com/astaxie/beego/context"
  24. "github.com/cnlh/nps/vender/github.com/astaxie/beego/logs"
  25. "github.com/cnlh/nps/vender/github.com/astaxie/beego/session"
  26. "github.com/cnlh/nps/vender/github.com/astaxie/beego/utils"
  27. )
  28. // Config is the main struct for BConfig
  29. type Config struct {
  30. AppName string //Application name
  31. RunMode string //Running Mode: dev | prod
  32. RouterCaseSensitive bool
  33. ServerName string
  34. RecoverPanic bool
  35. RecoverFunc func(*context.Context)
  36. CopyRequestBody bool
  37. EnableGzip bool
  38. MaxMemory int64
  39. EnableErrorsShow bool
  40. EnableErrorsRender bool
  41. Listen Listen
  42. WebConfig WebConfig
  43. Log LogConfig
  44. }
  45. // Listen holds for http and https related config
  46. type Listen struct {
  47. Graceful bool // Graceful means use graceful module to start the server
  48. ServerTimeOut int64
  49. ListenTCP4 bool
  50. EnableHTTP bool
  51. HTTPAddr string
  52. HTTPPort int
  53. AutoTLS bool
  54. Domains []string
  55. TLSCacheDir string
  56. EnableHTTPS bool
  57. EnableMutualHTTPS bool
  58. HTTPSAddr string
  59. HTTPSPort int
  60. HTTPSCertFile string
  61. HTTPSKeyFile string
  62. TrustCaFile string
  63. EnableAdmin bool
  64. AdminAddr string
  65. AdminPort int
  66. EnableFcgi bool
  67. EnableStdIo bool // EnableStdIo works with EnableFcgi Use FCGI via standard I/O
  68. }
  69. // WebConfig holds web related config
  70. type WebConfig struct {
  71. AutoRender bool
  72. EnableDocs bool
  73. FlashName string
  74. FlashSeparator string
  75. DirectoryIndex bool
  76. StaticDir map[string]string
  77. StaticExtensionsToGzip []string
  78. TemplateLeft string
  79. TemplateRight string
  80. ViewsPath string
  81. EnableXSRF bool
  82. XSRFKey string
  83. XSRFExpire int
  84. Session SessionConfig
  85. }
  86. // SessionConfig holds session related config
  87. type SessionConfig struct {
  88. SessionOn bool
  89. SessionProvider string
  90. SessionName string
  91. SessionGCMaxLifetime int64
  92. SessionProviderConfig string
  93. SessionCookieLifeTime int
  94. SessionAutoSetCookie bool
  95. SessionDomain string
  96. SessionDisableHTTPOnly bool // used to allow for cross domain cookies/javascript cookies.
  97. SessionEnableSidInHTTPHeader bool // enable store/get the sessionId into/from http headers
  98. SessionNameInHTTPHeader string
  99. SessionEnableSidInURLQuery bool // enable get the sessionId from Url Query params
  100. }
  101. // LogConfig holds Log related config
  102. type LogConfig struct {
  103. AccessLogs bool
  104. EnableStaticLogs bool //log static files requests default: false
  105. AccessLogsFormat string //access log format: JSON_FORMAT, APACHE_FORMAT or empty string
  106. FileLineNum bool
  107. Outputs map[string]string // Store Adaptor : config
  108. }
  109. var (
  110. // BConfig is the default config for Application
  111. BConfig *Config
  112. // AppConfig is the instance of Config, store the config information from file
  113. AppConfig *beegoAppConfig
  114. // AppPath is the absolute path to the app
  115. AppPath string
  116. // GlobalSessions is the instance for the session manager
  117. GlobalSessions *session.Manager
  118. // appConfigPath is the path to the config files
  119. appConfigPath string
  120. // appConfigProvider is the provider for the config, default is ini
  121. appConfigProvider = "ini"
  122. )
  123. func init() {
  124. BConfig = newBConfig()
  125. var err error
  126. if AppPath, err = filepath.Abs(filepath.Dir(os.Args[0])); err != nil {
  127. panic(err)
  128. }
  129. workPath, err := os.Getwd()
  130. if err != nil {
  131. panic(err)
  132. }
  133. var filename = "app.conf"
  134. if os.Getenv("BEEGO_RUNMODE") != "" {
  135. filename = os.Getenv("BEEGO_RUNMODE") + ".app.conf"
  136. }
  137. appConfigPath = filepath.Join(workPath, "conf", filename)
  138. if !utils.FileExists(appConfigPath) {
  139. appConfigPath = filepath.Join(AppPath, "conf", filename)
  140. if !utils.FileExists(appConfigPath) {
  141. AppConfig = &beegoAppConfig{innerConfig: config.NewFakeConfig()}
  142. return
  143. }
  144. }
  145. if err = parseConfig(appConfigPath); err != nil {
  146. panic(err)
  147. }
  148. }
  149. func recoverPanic(ctx *context.Context) {
  150. if err := recover(); err != nil {
  151. if err == ErrAbort {
  152. return
  153. }
  154. if !BConfig.RecoverPanic {
  155. panic(err)
  156. }
  157. if BConfig.EnableErrorsShow {
  158. if _, ok := ErrorMaps[fmt.Sprint(err)]; ok {
  159. exception(fmt.Sprint(err), ctx)
  160. return
  161. }
  162. }
  163. var stack string
  164. logs.Critical("the request url is ", ctx.Input.URL())
  165. logs.Critical("Handler crashed with error", err)
  166. for i := 1; ; i++ {
  167. _, file, line, ok := runtime.Caller(i)
  168. if !ok {
  169. break
  170. }
  171. logs.Critical(fmt.Sprintf("%s:%d", file, line))
  172. stack = stack + fmt.Sprintln(fmt.Sprintf("%s:%d", file, line))
  173. }
  174. if BConfig.RunMode == DEV && BConfig.EnableErrorsRender {
  175. showErr(err, ctx, stack)
  176. }
  177. if ctx.Output.Status != 0 {
  178. ctx.ResponseWriter.WriteHeader(ctx.Output.Status)
  179. } else {
  180. ctx.ResponseWriter.WriteHeader(500)
  181. }
  182. }
  183. }
  184. func newBConfig() *Config {
  185. return &Config{
  186. AppName: "beego",
  187. RunMode: PROD,
  188. RouterCaseSensitive: true,
  189. ServerName: "beegoServer:" + VERSION,
  190. RecoverPanic: true,
  191. RecoverFunc: recoverPanic,
  192. CopyRequestBody: false,
  193. EnableGzip: false,
  194. MaxMemory: 1 << 26, //64MB
  195. EnableErrorsShow: true,
  196. EnableErrorsRender: true,
  197. Listen: Listen{
  198. Graceful: false,
  199. ServerTimeOut: 0,
  200. ListenTCP4: false,
  201. EnableHTTP: true,
  202. AutoTLS: false,
  203. Domains: []string{},
  204. TLSCacheDir: ".",
  205. HTTPAddr: "",
  206. HTTPPort: 8080,
  207. EnableHTTPS: false,
  208. HTTPSAddr: "",
  209. HTTPSPort: 10443,
  210. HTTPSCertFile: "",
  211. HTTPSKeyFile: "",
  212. EnableAdmin: false,
  213. AdminAddr: "",
  214. AdminPort: 8088,
  215. EnableFcgi: false,
  216. EnableStdIo: false,
  217. },
  218. WebConfig: WebConfig{
  219. AutoRender: true,
  220. EnableDocs: false,
  221. FlashName: "BEEGO_FLASH",
  222. FlashSeparator: "BEEGOFLASH",
  223. DirectoryIndex: false,
  224. StaticDir: map[string]string{"/static": "static"},
  225. StaticExtensionsToGzip: []string{".css", ".js"},
  226. TemplateLeft: "{{",
  227. TemplateRight: "}}",
  228. ViewsPath: "views",
  229. EnableXSRF: false,
  230. XSRFKey: "beegoxsrf",
  231. XSRFExpire: 0,
  232. Session: SessionConfig{
  233. SessionOn: false,
  234. SessionProvider: "memory",
  235. SessionName: "beegosessionID",
  236. SessionGCMaxLifetime: 3600,
  237. SessionProviderConfig: "",
  238. SessionDisableHTTPOnly: false,
  239. SessionCookieLifeTime: 0, //set cookie default is the browser life
  240. SessionAutoSetCookie: true,
  241. SessionDomain: "",
  242. SessionEnableSidInHTTPHeader: false, // enable store/get the sessionId into/from http headers
  243. SessionNameInHTTPHeader: "Beegosessionid",
  244. SessionEnableSidInURLQuery: false, // enable get the sessionId from Url Query params
  245. },
  246. },
  247. Log: LogConfig{
  248. AccessLogs: false,
  249. EnableStaticLogs: false,
  250. AccessLogsFormat: "APACHE_FORMAT",
  251. FileLineNum: true,
  252. Outputs: map[string]string{"console": ""},
  253. },
  254. }
  255. }
  256. // now only support ini, next will support json.
  257. func parseConfig(appConfigPath string) (err error) {
  258. AppConfig, err = newAppConfig(appConfigProvider, appConfigPath)
  259. if err != nil {
  260. return err
  261. }
  262. return assignConfig(AppConfig)
  263. }
  264. func assignConfig(ac config.Configer) error {
  265. for _, i := range []interface{}{BConfig, &BConfig.Listen, &BConfig.WebConfig, &BConfig.Log, &BConfig.WebConfig.Session} {
  266. assignSingleConfig(i, ac)
  267. }
  268. // set the run mode first
  269. if envRunMode := os.Getenv("BEEGO_RUNMODE"); envRunMode != "" {
  270. BConfig.RunMode = envRunMode
  271. } else if runMode := ac.String("RunMode"); runMode != "" {
  272. BConfig.RunMode = runMode
  273. }
  274. if sd := ac.String("StaticDir"); sd != "" {
  275. BConfig.WebConfig.StaticDir = map[string]string{}
  276. sds := strings.Fields(sd)
  277. for _, v := range sds {
  278. if url2fsmap := strings.SplitN(v, ":", 2); len(url2fsmap) == 2 {
  279. BConfig.WebConfig.StaticDir["/"+strings.Trim(url2fsmap[0], "/")] = url2fsmap[1]
  280. } else {
  281. BConfig.WebConfig.StaticDir["/"+strings.Trim(url2fsmap[0], "/")] = url2fsmap[0]
  282. }
  283. }
  284. }
  285. if sgz := ac.String("StaticExtensionsToGzip"); sgz != "" {
  286. extensions := strings.Split(sgz, ",")
  287. fileExts := []string{}
  288. for _, ext := range extensions {
  289. ext = strings.TrimSpace(ext)
  290. if ext == "" {
  291. continue
  292. }
  293. if !strings.HasPrefix(ext, ".") {
  294. ext = "." + ext
  295. }
  296. fileExts = append(fileExts, ext)
  297. }
  298. if len(fileExts) > 0 {
  299. BConfig.WebConfig.StaticExtensionsToGzip = fileExts
  300. }
  301. }
  302. if lo := ac.String("LogOutputs"); lo != "" {
  303. // if lo is not nil or empty
  304. // means user has set his own LogOutputs
  305. // clear the default setting to BConfig.Log.Outputs
  306. BConfig.Log.Outputs = make(map[string]string)
  307. los := strings.Split(lo, ";")
  308. for _, v := range los {
  309. if logType2Config := strings.SplitN(v, ",", 2); len(logType2Config) == 2 {
  310. BConfig.Log.Outputs[logType2Config[0]] = logType2Config[1]
  311. } else {
  312. continue
  313. }
  314. }
  315. }
  316. //init log
  317. //logs.Reset()
  318. //for adaptor, config := range BConfig.Log.Outputs {
  319. // err := logs.SetLogger(adaptor, config)
  320. // if err != nil {
  321. // fmt.Fprintln(os.Stderr, fmt.Sprintf("%s with the config %q got err:%s", adaptor, config, err.Error()))
  322. // }
  323. //}
  324. //logs.SetLogFuncCall(BConfig.Log.FileLineNum)
  325. return nil
  326. }
  327. func assignSingleConfig(p interface{}, ac config.Configer) {
  328. pt := reflect.TypeOf(p)
  329. if pt.Kind() != reflect.Ptr {
  330. return
  331. }
  332. pt = pt.Elem()
  333. if pt.Kind() != reflect.Struct {
  334. return
  335. }
  336. pv := reflect.ValueOf(p).Elem()
  337. for i := 0; i < pt.NumField(); i++ {
  338. pf := pv.Field(i)
  339. if !pf.CanSet() {
  340. continue
  341. }
  342. name := pt.Field(i).Name
  343. switch pf.Kind() {
  344. case reflect.String:
  345. pf.SetString(ac.DefaultString(name, pf.String()))
  346. case reflect.Int, reflect.Int64:
  347. pf.SetInt(ac.DefaultInt64(name, pf.Int()))
  348. case reflect.Bool:
  349. pf.SetBool(ac.DefaultBool(name, pf.Bool()))
  350. case reflect.Struct:
  351. default:
  352. //do nothing here
  353. }
  354. }
  355. }
  356. // LoadAppConfig allow developer to apply a config file
  357. func LoadAppConfig(adapterName, configPath string) error {
  358. absConfigPath, err := filepath.Abs(configPath)
  359. if err != nil {
  360. return err
  361. }
  362. if !utils.FileExists(absConfigPath) {
  363. return fmt.Errorf("the target config file: %s don't exist", configPath)
  364. }
  365. appConfigPath = absConfigPath
  366. appConfigProvider = adapterName
  367. return parseConfig(appConfigPath)
  368. }
  369. type beegoAppConfig struct {
  370. innerConfig config.Configer
  371. }
  372. func newAppConfig(appConfigProvider, appConfigPath string) (*beegoAppConfig, error) {
  373. ac, err := config.NewConfig(appConfigProvider, appConfigPath)
  374. if err != nil {
  375. return nil, err
  376. }
  377. return &beegoAppConfig{ac}, nil
  378. }
  379. func (b *beegoAppConfig) Set(key, val string) error {
  380. if err := b.innerConfig.Set(BConfig.RunMode+"::"+key, val); err != nil {
  381. return err
  382. }
  383. return b.innerConfig.Set(key, val)
  384. }
  385. func (b *beegoAppConfig) String(key string) string {
  386. if v := b.innerConfig.String(BConfig.RunMode + "::" + key); v != "" {
  387. return v
  388. }
  389. return b.innerConfig.String(key)
  390. }
  391. func (b *beegoAppConfig) Strings(key string) []string {
  392. if v := b.innerConfig.Strings(BConfig.RunMode + "::" + key); len(v) > 0 {
  393. return v
  394. }
  395. return b.innerConfig.Strings(key)
  396. }
  397. func (b *beegoAppConfig) Int(key string) (int, error) {
  398. if v, err := b.innerConfig.Int(BConfig.RunMode + "::" + key); err == nil {
  399. return v, nil
  400. }
  401. return b.innerConfig.Int(key)
  402. }
  403. func (b *beegoAppConfig) Int64(key string) (int64, error) {
  404. if v, err := b.innerConfig.Int64(BConfig.RunMode + "::" + key); err == nil {
  405. return v, nil
  406. }
  407. return b.innerConfig.Int64(key)
  408. }
  409. func (b *beegoAppConfig) Bool(key string) (bool, error) {
  410. if v, err := b.innerConfig.Bool(BConfig.RunMode + "::" + key); err == nil {
  411. return v, nil
  412. }
  413. return b.innerConfig.Bool(key)
  414. }
  415. func (b *beegoAppConfig) Float(key string) (float64, error) {
  416. if v, err := b.innerConfig.Float(BConfig.RunMode + "::" + key); err == nil {
  417. return v, nil
  418. }
  419. return b.innerConfig.Float(key)
  420. }
  421. func (b *beegoAppConfig) DefaultString(key string, defaultVal string) string {
  422. if v := b.String(key); v != "" {
  423. return v
  424. }
  425. return defaultVal
  426. }
  427. func (b *beegoAppConfig) DefaultStrings(key string, defaultVal []string) []string {
  428. if v := b.Strings(key); len(v) != 0 {
  429. return v
  430. }
  431. return defaultVal
  432. }
  433. func (b *beegoAppConfig) DefaultInt(key string, defaultVal int) int {
  434. if v, err := b.Int(key); err == nil {
  435. return v
  436. }
  437. return defaultVal
  438. }
  439. func (b *beegoAppConfig) DefaultInt64(key string, defaultVal int64) int64 {
  440. if v, err := b.Int64(key); err == nil {
  441. return v
  442. }
  443. return defaultVal
  444. }
  445. func (b *beegoAppConfig) DefaultBool(key string, defaultVal bool) bool {
  446. if v, err := b.Bool(key); err == nil {
  447. return v
  448. }
  449. return defaultVal
  450. }
  451. func (b *beegoAppConfig) DefaultFloat(key string, defaultVal float64) float64 {
  452. if v, err := b.Float(key); err == nil {
  453. return v
  454. }
  455. return defaultVal
  456. }
  457. func (b *beegoAppConfig) DIY(key string) (interface{}, error) {
  458. return b.innerConfig.DIY(key)
  459. }
  460. func (b *beegoAppConfig) GetSection(section string) (map[string]string, error) {
  461. return b.innerConfig.GetSection(section)
  462. }
  463. func (b *beegoAppConfig) SaveConfigFile(filename string) error {
  464. return b.innerConfig.SaveConfigFile(filename)
  465. }