func init() { BConfig = newBConfig() var err error if AppPath, err = filepath.Abs(filepath.Dir(os.Args[0])); err != nil { panic(err) } workPath, err := os.Getwd() if err != nil { panic(err) } appConfigPath = filepath.Join(workPath, "conf", "app.conf") if !utils.FileExists(appConfigPath) { appConfigPath = filepath.Join(AppPath, "conf", "app.conf") if !utils.FileExists(appConfigPath) { AppConfig = &beegoAppConfig{innerConfig: config.NewFakeConfig()} return } } if err = parseConfig(appConfigPath); err != nil { panic(err) } if err = os.Chdir(AppPath); err != nil { panic(err) } }
func needCheckUpdate() bool { // Does not have record for check update. stamp, err := beego.AppConfig.Int64("app::update_check_time") if err != nil { return true } if !utils.FileExists("conf/docTree.json") || !utils.FileExists("conf/blogTree.json") || !utils.FileExists("conf/productTree.json") { return true } return time.Unix(stamp, 0).Add(5 * time.Minute).Before(time.Now()) }
func initBlogMap() { os.Mkdir("blog", os.ModePerm) langs := strings.Split(beego.AppConfig.String("lang::types"), "|") for _, l := range langs { os.Mkdir("blog/"+l, os.ModePerm) } if !utils.FileExists("conf/blogTree.json") { beego.Error("models.initBlogMap -> conf/blogTree.json does not exist") return } f, err := os.Open("conf/blogTree.json") if err != nil { beego.Error("models.initBlogMap -> load data:", err.Error()) return } defer f.Close() d := json.NewDecoder(f) err = d.Decode(&blogTree) if err != nil { beego.Error("models.initBlogMap -> decode data:", err.Error()) return } blogLock.Lock() defer blogLock.Unlock() blogMap = make(map[string]*docFile) for _, v := range blogTree.Tree { blogMap[v.Path] = getFile("blog/" + v.Path) } }
func isSystemPackage(pkgpath string) bool { goroot := runtime.GOROOT() if goroot == "" { panic("goroot is empty, do you install Go right?") } wg, _ := filepath.EvalSymlinks(filepath.Join(goroot, "src", "pkg", pkgpath)) if utils.FileExists(wg) { return true } //TODO(zh):support go1.4 wg, _ = filepath.EvalSymlinks(filepath.Join(goroot, "src", pkgpath)) if utils.FileExists(wg) { return true } return false }
// Load return Configer // you can load the specific config file by run mode func Load(configFile string) (cf config.Configer, err error) { if c, ok := configFiles[configFile]; ok { cf = c return } fullPathFile := filepath.Join("conf", beego.BConfig.RunMode, configFile) if !utils.FileExists(fullPathFile) { fullPathFile = filepath.Join("conf", configFile) if !utils.FileExists(fullPathFile) { err = errors.New(fullPathFile + " not found") return } } adapter := strings.TrimLeft(filepath.Ext(fullPathFile), ".") cf, err = config.NewConfig(adapter, fullPathFile) if err != nil { configFiles[configFile] = cf } return }
func compareFile(pkgRealpath string) bool { if !utils.FileExists(path.Join(workPath, "routers", commentFilename)) { return true } if utils.FileExists(path.Join(workPath, lastupdateFilename)) { content, err := ioutil.ReadFile(path.Join(workPath, lastupdateFilename)) if err != nil { return true } json.Unmarshal(content, &pkgLastupdate) lastupdate, err := getpathTime(pkgRealpath) if err != nil { return true } if v, ok := pkgLastupdate[pkgRealpath]; ok { if lastupdate <= v { return false } } } return true }
func getRouterDir(pkgRealpath string) string { dir := filepath.Dir(pkgRealpath) for { d := filepath.Join(dir, "routers") if utils.FileExists(d) { return d } if r, _ := filepath.Rel(dir, AppPath); r == "." { return d } // Parent dir. dir = filepath.Dir(dir) } }
// LoadAppConfig allow developer to apply a config file func LoadAppConfig(adapterName, configPath string) error { absConfigPath, err := filepath.Abs(configPath) if err != nil { return err } if !utils.FileExists(absConfigPath) { return fmt.Errorf("the target config file: %s don't exist", configPath) } appConfigPath = absConfigPath appConfigProvider = adapterName return parseConfig(appConfigPath) }
func initDocMap() { // Documentation names. docNames := make([]string, 0, 20) docNames = append(docNames, strings.Split( beego.AppConfig.String("app::doc_names"), "|")...) isConfExist := utils.FileExists("conf/docTree.json") if isConfExist { f, err := os.Open("conf/docTree.json") if err != nil { beego.Error("models.initDocMap -> load data:", err.Error()) return } defer f.Close() d := json.NewDecoder(f) if err = d.Decode(&docTree); err != nil { beego.Error("models.initDocMap -> decode data:", err.Error()) return } } else { // Generate 'docTree'. for _, v := range docNames { docTree.Tree = append(docTree.Tree, oldDocNode{Path: v}) } } docLock.Lock() defer docLock.Unlock() docMap = make(map[string]*docFile) langs := strings.Split(beego.AppConfig.String("lang::types"), "|") os.Mkdir("docs", os.ModePerm) for _, l := range langs { os.Mkdir("docs/"+l, os.ModePerm) for _, v := range docTree.Tree { var fullName string if isConfExist { fullName = v.Path } else { fullName = l + "/" + v.Path } docMap[fullName] = getFile("docs/" + fullName) } } }
// download src func (b *Builder) get() (err error) { log.Debug("start get src to:", b.srcDir) exists := beeutils.FileExists(b.srcDir) b.sh.Command("go", "version").Run() if !exists { err = b.sh.Command("go", "get", "-v", "-d", b.project).Run() if err != nil { return } } b.sh.SetDir(b.srcDir) if b.ref == "-" { b.ref = "master" } // get code from remote if err = b.sh.Command("git", "fetch", "origin").Run(); err != nil { return } // change branch if err = b.sh.Command("git", "checkout", "-q", b.ref).Run(); err != nil { return } // update code if err = b.sh.Command("git", "merge", "origin/"+b.ref).Run(); err != nil { log.Warn("git merge error:", err) //return } // get sha out, err := sh.Command("git", "rev-parse", "HEAD", sh.Dir(b.srcDir)).Output() if err != nil { return } b.sha = strings.TrimSpace(string(out)) // parse .gobuild b.rc = new(Assembly) rcfile := "public/gobuildrc" if b.sh.Test("f", ".gobuild") { rcfile = filepath.Join(b.srcDir, ".gobuild") } data, err := ioutil.ReadFile(rcfile) if err != nil { return } err = goyaml.Unmarshal(data, b.rc) return }
func compareFile(pkgRealpath string) bool { if utils.FileExists(path.Join(AppPath, lastupdateFilename)) { content, err := ioutil.ReadFile(path.Join(AppPath, lastupdateFilename)) if err != nil { return true } json.Unmarshal(content, &pkgLastupdate) ft, err := os.Lstat(pkgRealpath) if err != nil { return true } if v, ok := pkgLastupdate[pkgRealpath]; ok { if ft.ModTime().UnixNano() >= v { return false } } } return true }
// download src func (b *Builder) get() (err error) { exists := beeutils.FileExists(b.srcDir) b.sh.Command("date") if !exists { err = b.sh.Command("go", "get", "-v", "-d", b.project).Run() if err != nil { return } } b.sh.SetDir(b.srcDir) if b.ref == "-" { b.ref = "master" } if err = b.sh.Command("git", "fetch", "origin").Run(); err != nil { return } if err = b.sh.Command("git", "checkout", "-q", b.ref).Run(); err != nil { return } if err = b.sh.Command("git", "merge", "origin/"+b.ref).Run(); err != nil { return } out, err := sh.Command("git", "rev-parse", "HEAD", sh.Dir(b.srcDir)).Output() if err != nil { return } b.sha = strings.TrimSpace(string(out)) // parse .gobuild b.rc = new(Assembly) rcfile := "public/gobuildrc" if b.sh.Test("f", ".gobuild") { rcfile = filepath.Join(b.srcDir, ".gobuild") } data, err := ioutil.ReadFile(rcfile) if err != nil { return } err = goyaml.Unmarshal(data, b.rc) return }
// 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 BConfig.RunMode == DEV { skip := make(map[string]bool, 10) for _, c := range cList { reflectVal := reflect.ValueOf(c) t := reflect.Indirect(reflectVal).Type() gopath := os.Getenv("GOPATH") if gopath == "" { panic("you are in dev mode. So please set gopath") } pkgpath := "" wgopath := filepath.SplitList(gopath) for _, wg := range wgopath { wg, _ = filepath.EvalSymlinks(filepath.Join(wg, "src", t.PkgPath())) if utils.FileExists(wg) { pkgpath = wg break } } if pkgpath != "" { if _, ok := skip[pkgpath]; !ok { skip[pkgpath] = true parserPkg(pkgpath, t.PkgPath()) } } } } for _, c := range cList { reflectVal := reflect.ValueOf(c) t := reflect.Indirect(reflectVal).Type() key := t.PkgPath() + ":" + t.Name() if comm, ok := GlobalControllerRouter[key]; ok { for _, a := range comm { p.Add(a.Router, c, strings.Join(a.AllowHTTPMethods, ",")+":"+a.Method) } } } }
func getTplDeep(root, file, parent string, t *template.Template) (*template.Template, [][]string, error) { var fileAbsPath string if filepath.HasPrefix(file, "../") { fileAbsPath = filepath.Join(root, filepath.Dir(parent), file) } else { fileAbsPath = filepath.Join(root, file) } if e := utils.FileExists(fileAbsPath); !e { panic("can't find template file:" + file) } data, err := ioutil.ReadFile(fileAbsPath) if err != nil { return nil, [][]string{}, err } t, err = t.New(file).Parse(string(data)) if err != nil { return nil, [][]string{}, err } reg := regexp.MustCompile(BConfig.WebConfig.TemplateLeft + "[ ]*template[ ]+\"([^\"]+)\"") allSub := reg.FindAllStringSubmatch(string(data), -1) for _, m := range allSub { if len(m) == 2 { tl := t.Lookup(m[1]) if tl != nil { continue } if !HasTemplateExt(m[1]) { continue } t, _, err = getTplDeep(root, m[1], file, t) if err != nil { return nil, [][]string{}, err } } } return t, allSub, nil }
func init() { // create beego application BeeApp = NewApp() 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 SessionSavePath = "" SessionCookieLifeTime = 0 //set cookie default is the brower life SessionAutoSetCookie = true UseFcgi = false UseStdIo = false MaxMemory = 1 << 26 //64MB EnableGzip = false HttpServerTimeOut = 0 ErrorsShow = 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 && 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) { if AppConfigPath == "" { if utils.FileExists(filepath.Join("conf", "app.conf")) { AppConfigPath = filepath.Join("conf", "app.conf") } else { AppConfig = &beegoAppConfig{config.NewFakeConfig()} return } } AppConfig, err = newAppConfig(AppConfigProvider, AppConfigPath) if err != nil { return err } // set the runmode first if envRunMode := os.Getenv("BEEGO_RUNMODE"); envRunMode != "" { BConfig.RunMode = envRunMode } else if runmode := AppConfig.String("RunMode"); runmode != "" { BConfig.RunMode = runmode } BConfig.AppName = AppConfig.DefaultString("AppName", BConfig.AppName) BConfig.RecoverPanic = AppConfig.DefaultBool("RecoverPanic", BConfig.RecoverPanic) BConfig.RouterCaseSensitive = AppConfig.DefaultBool("RouterCaseSensitive", BConfig.RouterCaseSensitive) BConfig.ServerName = AppConfig.DefaultString("ServerName", BConfig.ServerName) 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) BConfig.Listen.HTTPAddr = AppConfig.String("HTTPAddr") BConfig.Listen.HTTPPort = AppConfig.DefaultInt("HTTPPort", BConfig.Listen.HTTPPort) BConfig.Listen.ListenTCP4 = AppConfig.DefaultBool("ListenTCP4", BConfig.Listen.ListenTCP4) BConfig.Listen.EnableHTTP = AppConfig.DefaultBool("EnableHTTP", BConfig.Listen.EnableHTTP) BConfig.Listen.EnableHTTPS = AppConfig.DefaultBool("EnableHTTPS", BConfig.Listen.EnableHTTPS) BConfig.Listen.HTTPSAddr = AppConfig.DefaultString("HTTPSAddr", BConfig.Listen.HTTPSAddr) BConfig.Listen.HTTPSPort = AppConfig.DefaultInt("HTTPSPort", BConfig.Listen.HTTPSPort) 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) BConfig.Listen.EnableFcgi = AppConfig.DefaultBool("EnableFcgi", BConfig.Listen.EnableFcgi) BConfig.Listen.EnableStdIo = AppConfig.DefaultBool("EnableStdIo", BConfig.Listen.EnableStdIo) BConfig.Listen.ServerTimeOut = AppConfig.DefaultInt64("ServerTimeOut", BConfig.Listen.ServerTimeOut) 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) BConfig.WebConfig.FlashName = AppConfig.DefaultString("FlashName", BConfig.WebConfig.FlashName) BConfig.WebConfig.FlashSeparator = AppConfig.DefaultString("FlashSeparator", BConfig.WebConfig.FlashSeparator) BConfig.WebConfig.EnableDocs = AppConfig.DefaultBool("EnableDocs", BConfig.WebConfig.EnableDocs) BConfig.WebConfig.XSRFKey = AppConfig.DefaultString("XSRFKEY", BConfig.WebConfig.XSRFKey) 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) BConfig.WebConfig.Session.SessionAutoSetCookie = AppConfig.DefaultBool("SessionAutoSetCookie", BConfig.WebConfig.Session.SessionAutoSetCookie) BConfig.WebConfig.Session.SessionDomain = AppConfig.DefaultString("SessionDomain", BConfig.WebConfig.Session.SessionDomain) 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 } } return nil }
// Run beego application. func (app *App) Run() { addr := HttpAddr if HttpPort != 0 { addr = fmt.Sprintf("%s:%d", HttpAddr, HttpPort) } var ( err error l net.Listener ) endRunning := make(chan bool, 1) if UseFcgi { if UseStdIo { err = fcgi.Serve(nil, app.Handlers) // standard I/O if err == nil { BeeLogger.Info("Use FCGI via standard I/O") } else { BeeLogger.Info("Cannot use FCGI via standard I/O", err) } } else { if HttpPort == 0 { // remove the Socket file before start if utils.FileExists(addr) { os.Remove(addr) } l, err = net.Listen("unix", addr) } else { l, err = net.Listen("tcp", addr) } if err != nil { BeeLogger.Critical("Listen: ", err) } err = fcgi.Serve(l, app.Handlers) } } 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 if EnableHttpTLS { go func() { time.Sleep(20 * time.Microsecond) if HttpsPort != 0 { app.Server.Addr = fmt.Sprintf("%s:%d", HttpAddr, HttpsPort) } BeeLogger.Info("https server Running on %s", app.Server.Addr) err := app.Server.ListenAndServeTLS(HttpCertFile, HttpKeyFile) if err != nil { BeeLogger.Critical("ListenAndServeTLS: ", err) time.Sleep(100 * time.Microsecond) endRunning <- true } }() } if EnableHttpListen { go func() { app.Server.Addr = addr BeeLogger.Info("http server Running on %s", app.Server.Addr) if ListenTCP4 && HttpAddr == "" { ln, err := net.Listen("tcp4", app.Server.Addr) if err != nil { BeeLogger.Critical("ListenAndServe: ", err) time.Sleep(100 * time.Microsecond) endRunning <- true return } err = app.Server.Serve(ln) if err != nil { BeeLogger.Critical("ListenAndServe: ", err) time.Sleep(100 * time.Microsecond) endRunning <- true return } } else { err := app.Server.ListenAndServe() if err != nil { BeeLogger.Critical("ListenAndServe: ", err) time.Sleep(100 * time.Microsecond) endRunning <- true } } }() } } <-endRunning }
func serverStaticRouter(ctx *context.Context) { requestPath := path.Clean(ctx.Input.Request.URL.Path) for prefix, staticDir := range StaticDir { if len(prefix) == 0 { continue } if requestPath == "/favicon.ico" { file := path.Join(staticDir, requestPath) if utils.FileExists(file) { http.ServeFile(ctx.ResponseWriter, ctx.Request, file) return } } if strings.HasPrefix(requestPath, prefix) { if len(requestPath) > len(prefix) && requestPath[len(prefix)] != '/' { continue } file := path.Join(staticDir, requestPath[len(prefix):]) finfo, err := os.Stat(file) if err != nil { if RunMode == "dev" { Warn(err) } http.NotFound(ctx.ResponseWriter, ctx.Request) return } //if the request is dir and DirectoryIndex is false then if finfo.IsDir() && !DirectoryIndex { middleware.Exception("403", ctx.ResponseWriter, ctx.Request, "403 Forbidden") return } //This block obtained from (https://github.com/smithfox/beego) - it should probably get merged into astaxie/beego after a pull request isStaticFileToCompress := false if StaticExtensionsToGzip != nil && len(StaticExtensionsToGzip) > 0 { for _, statExtension := range StaticExtensionsToGzip { if strings.HasSuffix(strings.ToLower(file), strings.ToLower(statExtension)) { isStaticFileToCompress = true break } } } if isStaticFileToCompress { var contentEncoding string if EnableGzip { contentEncoding = getAcceptEncodingZip(ctx.Request) } memzipfile, err := openMemZipFile(file, contentEncoding) if err != nil { return } if contentEncoding == "gzip" { ctx.Output.Header("Content-Encoding", "gzip") } else if contentEncoding == "deflate" { ctx.Output.Header("Content-Encoding", "deflate") } else { ctx.Output.Header("Content-Length", strconv.FormatInt(finfo.Size(), 10)) } http.ServeContent(ctx.ResponseWriter, ctx.Request, file, finfo.ModTime(), memzipfile) } else { http.ServeFile(ctx.ResponseWriter, ctx.Request, file) } return } } }
func init() { AppPath, _ = filepath.Abs(filepath.Dir(os.Args[0])) os.Chdir(AppPath) BConfig = &Config{ 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, EnableHTTP: true, HTTPAddr: "", HTTPPort: 8080, EnableHTTPS: false, HTTPSAddr: "", HTTPSPort: 10443, HTTPSCertFile: "", HTTPSKeyFile: "", EnableAdmin: false, AdminAddr: "", AdminPort: 8088, EnableFcgi: false, EnableStdIo: false, }, WebConfig: WebConfig{ AutoRender: true, EnableDocs: false, FlashName: "BEEGO_FLASH", FlashSeparator: "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 browser life SessionAutoSetCookie: true, SessionDomain: "", }, }, Log: LogConfig{ AccessLogs: false, FileLineNum: true, Outputs: map[string]string{"console": ""}, }, } appConfigPath = filepath.Join(AppPath, "conf", "app.conf") if !utils.FileExists(appConfigPath) { AppConfig = &beegoAppConfig{innerConfig: config.NewFakeConfig()} return } if err := parseConfig(appConfigPath); err != nil { panic(err) } }
// Implement http.Handler interface. func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) { defer func() { if err := recover(); err != nil { if err == USERSTOPRUN { return } if _, ok := err.(middleware.HTTPException); ok { // catch intented errors, only for HTTP 4XX and 5XX } else { if RunMode == "dev" { if !RecoverPanic { panic(err) } else { if ErrorsShow { if handler, ok := middleware.ErrorMaps[fmt.Sprint(err)]; ok { handler(rw, r) return } } var stack string Critical("the request url is ", r.URL.Path) Critical("Handler crashed with error", err) for i := 1; ; i++ { _, file, line, ok := runtime.Caller(i) if !ok { break } Critical(file, line) stack = stack + fmt.Sprintln(file, line) } middleware.ShowErr(err, rw, r, stack) } } else { if !RecoverPanic { panic(err) } else { // in production model show all infomation if ErrorsShow { handler := p.getErrorHandler(fmt.Sprint(err)) handler(rw, r) return } else { Critical("the request url is ", r.URL.Path) Critical("Handler crashed with error", err) for i := 1; ; i++ { _, file, line, ok := runtime.Caller(i) if !ok { break } Critical(file, line) } } } } } } }() starttime := time.Now() requestPath := r.URL.Path var runrouter reflect.Type var findrouter bool var runMethod string params := make(map[string]string) w := &responseWriter{writer: rw} w.Header().Set("Server", BeegoServerName) // init context context := &beecontext.Context{ ResponseWriter: w, Request: r, Input: beecontext.NewInput(r), Output: beecontext.NewOutput(), } context.Output.Context = context context.Output.EnableGzip = EnableGzip if context.Input.IsWebsocket() { context.ResponseWriter = rw } // defined filter function do_filter := func(pos int) (started bool) { if p.enableFilter { if l, ok := p.filters[pos]; ok { for _, filterR := range l { if ok, p := filterR.ValidRouter(r.URL.Path); ok { context.Input.Params = p filterR.filterFunc(context) if w.started { return true } } } } } return false } // session init if SessionOn { context.Input.CruSession = GlobalSessions.SessionStart(w, r) defer func() { context.Input.CruSession.SessionRelease(w) }() } if !utils.InSlice(strings.ToLower(r.Method), HTTPMETHOD) { http.Error(w, "Method Not Allowed", 405) goto Admin } if do_filter(BeforeRouter) { goto Admin } //static file server for prefix, staticDir := range StaticDir { if len(prefix) == 0 { continue } if r.URL.Path == "/favicon.ico" { file := path.Join(staticDir, r.URL.Path) if utils.FileExists(file) { http.ServeFile(w, r, file) w.started = true goto Admin } } if strings.HasPrefix(r.URL.Path, prefix) { if len(r.URL.Path) > len(prefix) && r.URL.Path[len(prefix)] != '/' { continue } if r.URL.Path == prefix && prefix[len(prefix)-1] != '/' { http.Redirect(rw, r, r.URL.Path+"/", 302) goto Admin } file := path.Join(staticDir, r.URL.Path[len(prefix):]) finfo, err := os.Stat(file) if err != nil { if RunMode == "dev" { Warn(err) } http.NotFound(w, r) goto Admin } //if the request is dir and DirectoryIndex is false then if finfo.IsDir() && !DirectoryIndex { middleware.Exception("403", rw, r, "403 Forbidden") goto Admin } //This block obtained from (https://github.com/smithfox/beego) - it should probably get merged into astaxie/beego after a pull request isStaticFileToCompress := false if StaticExtensionsToGzip != nil && len(StaticExtensionsToGzip) > 0 { for _, statExtension := range StaticExtensionsToGzip { if strings.HasSuffix(strings.ToLower(file), strings.ToLower(statExtension)) { isStaticFileToCompress = true break } } } if isStaticFileToCompress { if EnableGzip { w.contentEncoding = GetAcceptEncodingZip(r) } memzipfile, err := OpenMemZipFile(file, w.contentEncoding) if err != nil { return } w.InitHeadContent(finfo.Size()) http.ServeContent(w, r, file, finfo.ModTime(), memzipfile) } else { http.ServeFile(w, r, file) } w.started = true goto Admin } } if do_filter(AfterStatic) { goto Admin } if CopyRequestBody { context.Input.Body() } //first find path from the fixrouters to Improve Performance for _, route := range p.fixrouters { n := len(requestPath) if requestPath == route.pattern { runMethod = p.getRunMethod(r.Method, context, route) if runMethod != "" { runrouter = route.controllerType findrouter = true break } } // pattern /admin url /admin 200 /admin/ 200 // pattern /admin/ url /admin 301 /admin/ 200 if requestPath[n-1] != '/' && requestPath+"/" == route.pattern { http.Redirect(w, r, requestPath+"/", 301) goto Admin } if requestPath[n-1] == '/' && route.pattern+"/" == requestPath { runMethod = p.getRunMethod(r.Method, context, route) if runMethod != "" { runrouter = route.controllerType findrouter = true break } } } //find regex's router if !findrouter { //find a matching Route for _, route := range p.routers { //check if Route pattern matches url if !route.regex.MatchString(requestPath) { continue } //get submatches (params) matches := route.regex.FindStringSubmatch(requestPath) //double check that the Route matches the URL pattern. if len(matches[0]) != len(requestPath) { continue } if len(route.params) > 0 { //add url parameters to the query param map values := r.URL.Query() for i, match := range matches[1:] { values.Add(route.params[i], match) params[route.params[i]] = match } //reassemble query params and add to RawQuery r.URL.RawQuery = url.Values(values).Encode() } runMethod = p.getRunMethod(r.Method, context, route) if runMethod != "" { runrouter = route.controllerType context.Input.Params = params findrouter = true break } } } if !findrouter && p.enableAuto { // deal with url with diffirent ext // /controller/simple // /controller/simple.html // /controller/simple.json // /controller/simple.rss lastindex := strings.LastIndex(requestPath, "/") lastsub := requestPath[lastindex+1:] if subindex := strings.LastIndex(lastsub, "."); subindex != -1 { context.Input.Params[":ext"] = lastsub[subindex+1:] r.URL.Query().Add(":ext", lastsub[subindex+1:]) r.URL.RawQuery = r.URL.Query().Encode() requestPath = requestPath[:len(requestPath)-len(lastsub[subindex:])] } for cName, methodmap := range p.autoRouter { // if prev already find the router break if findrouter { break } if strings.ToLower(requestPath) == "/"+cName { http.Redirect(w, r, requestPath+"/", 301) goto Admin } // if there's no action, set the default action to index if strings.ToLower(requestPath) == "/"+cName+"/" { requestPath = requestPath + "index" } // if the request path start with controllerName if strings.HasPrefix(strings.ToLower(requestPath), "/"+cName+"/") { for mName, controllerType := range methodmap { if strings.ToLower(requestPath) == "/"+cName+"/"+strings.ToLower(mName) || (strings.HasPrefix(strings.ToLower(requestPath), "/"+cName+"/"+strings.ToLower(mName)) && requestPath[len("/"+cName+"/"+strings.ToLower(mName)):len("/"+cName+"/"+strings.ToLower(mName))+1] == "/") { runrouter = controllerType runMethod = mName findrouter = true //parse params otherurl := requestPath[len("/"+cName+"/"+strings.ToLower(mName)):] if len(otherurl) > 1 { plist := strings.Split(otherurl, "/") for k, v := range plist[1:] { context.Input.Params[strconv.Itoa(k)] = v } } break } } } } } //if no matches to url, throw a not found exception if !findrouter { middleware.Exception("404", rw, r, "") goto Admin } if findrouter { if r.Method == "POST" { r.ParseMultipartForm(MaxMemory) } //execute middleware filters if do_filter(BeforeExec) { goto Admin } //Invoke the request handler vc := reflect.New(runrouter) execController, ok := vc.Interface().(ControllerInterface) if !ok { panic("controller is not ControllerInterface") } //call the controller init function execController.Init(context, runrouter.Name(), runMethod, vc.Interface()) //if XSRF is Enable then check cookie where there has any cookie in the request's cookie _csrf if EnableXSRF { execController.XsrfToken() if r.Method == "POST" || r.Method == "DELETE" || r.Method == "PUT" || (r.Method == "POST" && (r.Form.Get("_method") == "delete" || r.Form.Get("_method") == "put")) { execController.CheckXsrfCookie() } } //call prepare function execController.Prepare() if !w.started { //exec main logic switch runMethod { case "Get": execController.Get() case "Post": execController.Post() case "Delete": execController.Delete() case "Put": execController.Put() case "Head": execController.Head() case "Patch": execController.Patch() case "Options": execController.Options() default: in := make([]reflect.Value, 0) method := vc.MethodByName(runMethod) method.Call(in) } //render template if !w.started && !context.Input.IsWebsocket() { if AutoRender { if err := execController.Render(); err != nil { panic(err) } } } } // finish all runrouter. release resource execController.Finish() //execute middleware filters if do_filter(AfterExec) { goto Admin } } Admin: do_filter(FinishRouter) //admin module record QPS if EnableAdmin { timeend := time.Since(starttime) if FilterMonitorFunc(r.Method, requestPath, timeend) { if runrouter != nil { go toolbox.StatisticsMap.AddStatistics(r.Method, requestPath, runrouter.Name(), timeend) } else { go toolbox.StatisticsMap.AddStatistics(r.Method, requestPath, "", timeend) } } } }
func serverStaticRouter(ctx *context.Context) { ctx.SetState(context.SC_STATIC_ROUTING) if ctx.Input.Method() != "GET" && ctx.Input.Method() != "HEAD" { return } requestPath := path.Clean(ctx.Input.Request.URL.Path) if RunMode == "dev" { Warn("Request path: ", requestPath) } if len(requestPath) == 0 || requestPath == "/" { return } i := 0 for prefix, staticDir := range StaticDir { if RunMode == "dev" { Warn("Static prefix: ", prefix) } /* root path's prefix is "" if len(prefix) == 0 { continue } */ if requestPath == "/favicon.ico" || requestPath == "/robots.txt" { file := path.Join(staticDir, requestPath) if utils.FileExists(file) { http.ServeFile(ctx.ResponseWriter, ctx.Request, file) return } else { i++ if i == len(StaticDir) { http.NotFound(ctx.ResponseWriter, ctx.Request) return } else { continue } } } if strings.HasPrefix(requestPath, prefix) { Warn("HasPressfix") if len(requestPath) > len(prefix) && requestPath[len(prefix)] != '/' { continue } file := path.Join(staticDir, requestPath[len(prefix):]) finfo, err := os.Stat(file) if err != nil { if RunMode == "dev" { Warn("Can't find the file:", file, err) } http.NotFound(ctx.ResponseWriter, ctx.Request) return } //if the request is dir and DirectoryIndex is false then if finfo.IsDir() { if !DirectoryIndex { exception("403", ctx) return } else if ctx.Input.Request.URL.Path[len(ctx.Input.Request.URL.Path)-1] != '/' { http.Redirect(ctx.ResponseWriter, ctx.Request, ctx.Input.Request.URL.Path+"/", 302) return } } else if strings.HasSuffix(requestPath, "/index.html") { file := path.Join(staticDir, requestPath) if utils.FileExists(file) { http.ServeFile(ctx.ResponseWriter, ctx.Request, file) return } } //This block obtained from (https://github.com/smithfox/beego) - it should probably get merged into astaxie/beego after a pull request isStaticFileToCompress := false if StaticExtensionsToGzip != nil && len(StaticExtensionsToGzip) > 0 { for _, statExtension := range StaticExtensionsToGzip { if strings.HasSuffix(strings.ToLower(file), strings.ToLower(statExtension)) { isStaticFileToCompress = true break } } } if isStaticFileToCompress { var contentEncoding string if EnableGzip { contentEncoding = getAcceptEncodingZip(ctx.Request) } memzipfile, err := openMemZipFile(file, contentEncoding) if err != nil { return } if contentEncoding == "gzip" { ctx.Output.Header("Content-Encoding", "gzip") } else if contentEncoding == "deflate" { ctx.Output.Header("Content-Encoding", "deflate") } else { ctx.Output.Header("Content-Length", strconv.FormatInt(finfo.Size(), 10)) } http.ServeContent(ctx.ResponseWriter, ctx.Request, file, finfo.ModTime(), memzipfile) } else { http.ServeFile(ctx.ResponseWriter, ctx.Request, file) } return } } }
func analisyscontrollerPkg(pkgpath string) { pkgpath = strings.Trim(pkgpath, "\"") pps := strings.Split(pkgpath, "/") importlist[pps[len(pps)-1]] = pkgpath if pkgpath == "github.com/astaxie/beego" { return } gopath := os.Getenv("GOPATH") if gopath == "" { panic("please set gopath") } pkgRealpath := "" wgopath := filepath.SplitList(gopath) for _, wg := range wgopath { wg, _ = filepath.EvalSymlinks(filepath.Join(wg, "src", pkgpath)) if utils.FileExists(wg) { pkgRealpath = wg break } } if pkgRealpath != "" { if _, ok := pkgCache[pkgpath]; ok { return } } else { ColorLog("[ERRO] the %s pkg not exist in gopath\n", pkgpath) os.Exit(1) } fileSet := token.NewFileSet() astPkgs, err := parser.ParseDir(fileSet, pkgRealpath, func(info os.FileInfo) bool { name := info.Name() return !info.IsDir() && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".go") }, parser.ParseComments) if err != nil { ColorLog("[ERRO] the %s pkg parser.ParseDir error\n", pkgpath) os.Exit(1) } for _, pkg := range astPkgs { for _, fl := range pkg.Files { for _, d := range fl.Decls { switch specDecl := d.(type) { case *ast.FuncDecl: if specDecl.Recv != nil && len(specDecl.Recv.List) > 0 { if t, ok := specDecl.Recv.List[0].Type.(*ast.StarExpr); ok { parserComments(specDecl.Doc, specDecl.Name.String(), fmt.Sprint(t.X), pkgpath) } } case *ast.GenDecl: if specDecl.Tok.String() == "type" { for _, s := range specDecl.Specs { switch tp := s.(*ast.TypeSpec).Type.(type) { case *ast.StructType: _ = tp.Struct controllerComments[pkgpath+s.(*ast.TypeSpec).Name.String()] = specDecl.Doc.Text() } } } } } } } }
// Run beego application. func (app *App) Run() { addr := BConfig.Listen.HTTPAddr if BConfig.Listen.HTTPPort != 0 { addr = fmt.Sprintf("%s:%d", BConfig.Listen.HTTPAddr, BConfig.Listen.HTTPPort) } var ( err error l net.Listener endRunning = make(chan bool, 1) ) // run cgi server if BConfig.Listen.EnableFcgi { if BConfig.Listen.EnableStdIo { if err = fcgi.Serve(nil, app.Handlers); err == nil { // standard I/O logs.Info("Use FCGI via standard I/O") } else { logs.Critical("Cannot use FCGI via standard I/O", err) } return } if BConfig.Listen.HTTPPort == 0 { // remove the Socket file before start if utils.FileExists(addr) { os.Remove(addr) } l, err = net.Listen("unix", addr) } else { l, err = net.Listen("tcp", addr) } if err != nil { logs.Critical("Listen: ", err) } if err = fcgi.Serve(l, app.Handlers); err != nil { logs.Critical("fcgi.Serve: ", err) } return } app.Server.Handler = app.Handlers app.Server.ReadTimeout = time.Duration(BConfig.Listen.ServerTimeOut) * time.Second app.Server.WriteTimeout = time.Duration(BConfig.Listen.ServerTimeOut) * time.Second app.Server.ErrorLog = logs.GetLogger("HTTP") // run graceful mode if BConfig.Listen.Graceful { httpsAddr := BConfig.Listen.HTTPSAddr app.Server.Addr = httpsAddr if BConfig.Listen.EnableHTTPS { go func() { time.Sleep(20 * time.Microsecond) 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 if err := server.ListenAndServeTLS(BConfig.Listen.HTTPSCertFile, BConfig.Listen.HTTPSKeyFile); err != nil { logs.Critical("ListenAndServeTLS: ", err, fmt.Sprintf("%d", os.Getpid())) time.Sleep(100 * time.Microsecond) endRunning <- true } }() } if BConfig.Listen.EnableHTTP { go func() { server := grace.NewServer(addr, app.Handlers) server.Server.ReadTimeout = app.Server.ReadTimeout server.Server.WriteTimeout = app.Server.WriteTimeout if BConfig.Listen.ListenTCP4 { server.Network = "tcp4" } if err := server.ListenAndServe(); err != nil { logs.Critical("ListenAndServe: ", err, fmt.Sprintf("%d", os.Getpid())) time.Sleep(100 * time.Microsecond) endRunning <- true } }() } <-endRunning return } // run normal mode if BConfig.Listen.EnableHTTPS { go func() { time.Sleep(20 * time.Microsecond) if BConfig.Listen.HTTPSPort != 0 { app.Server.Addr = fmt.Sprintf("%s:%d", BConfig.Listen.HTTPSAddr, BConfig.Listen.HTTPSPort) } else if BConfig.Listen.EnableHTTP { BeeLogger.Info("Start https server error, confict with http.Please reset https port") return } logs.Info("https server Running on https://%s", app.Server.Addr) if err := app.Server.ListenAndServeTLS(BConfig.Listen.HTTPSCertFile, BConfig.Listen.HTTPSKeyFile); err != nil { logs.Critical("ListenAndServeTLS: ", err) time.Sleep(100 * time.Microsecond) endRunning <- true } }() } if BConfig.Listen.EnableHTTP { go func() { app.Server.Addr = addr logs.Info("http server Running on http://%s", app.Server.Addr) if BConfig.Listen.ListenTCP4 { ln, err := net.Listen("tcp4", app.Server.Addr) if err != nil { logs.Critical("ListenAndServe: ", err) time.Sleep(100 * time.Microsecond) endRunning <- true return } if err = app.Server.Serve(ln); err != nil { logs.Critical("ListenAndServe: ", err) time.Sleep(100 * time.Microsecond) endRunning <- true return } } else { if err := app.Server.ListenAndServe(); err != nil { logs.Critical("ListenAndServe: ", err) time.Sleep(100 * time.Microsecond) endRunning <- true } } }() } <-endRunning }