1
0
mirror of https://github.com/astaxie/beego.git synced 2024-11-22 19:10:54 +00:00

Merge branch 'develop' of https://github.com/astaxie/beego into develop

This commit is contained in:
astaxie 2015-12-21 22:54:22 +08:00
commit 25337aec27
6 changed files with 94 additions and 123 deletions

View File

@ -177,8 +177,7 @@ func ParseConfig() (err error) {
if utils.FileExists(filepath.Join("conf", "app.conf")) { if utils.FileExists(filepath.Join("conf", "app.conf")) {
AppConfigPath = filepath.Join("conf", "app.conf") AppConfigPath = filepath.Join("conf", "app.conf")
} else { } else {
ac := config.NewFakeConfig() AppConfig = &beegoAppConfig{config.NewFakeConfig()}
AppConfig = &beegoAppConfig{ac}
return return
} }
} }
@ -186,9 +185,8 @@ func ParseConfig() (err error) {
if err != nil { if err != nil {
return err return err
} }
envRunMode := os.Getenv("BEEGO_RUNMODE")
// set the runmode first // set the runmode first
if envRunMode != "" { if envRunMode := os.Getenv("BEEGO_RUNMODE"); envRunMode != "" {
BConfig.RunMode = envRunMode BConfig.RunMode = envRunMode
} else if runmode := AppConfig.String("RunMode"); runmode != "" { } else if runmode := AppConfig.String("RunMode"); runmode != "" {
BConfig.RunMode = runmode BConfig.RunMode = runmode
@ -277,109 +275,95 @@ func newAppConfig(AppConfigProvider, AppConfigPath string) (*beegoAppConfig, err
if err != nil { if err != nil {
return nil, err return nil, err
} }
rac := &beegoAppConfig{ac} return &beegoAppConfig{ac}, nil
return rac, nil
} }
func (b *beegoAppConfig) Set(key, val string) error { func (b *beegoAppConfig) Set(key, val string) error {
err := b.innerConfig.Set(BConfig.RunMode+"::"+key, val) if err := b.innerConfig.Set(BConfig.RunMode+"::"+key, val); err != nil {
if err == nil {
return err return err
} }
return b.innerConfig.Set(key, val) return b.innerConfig.Set(key, val)
} }
func (b *beegoAppConfig) String(key string) string { func (b *beegoAppConfig) String(key string) string {
v := b.innerConfig.String(BConfig.RunMode + "::" + key) if v := b.innerConfig.String(BConfig.RunMode + "::" + key); v != "" {
if v == "" {
return b.innerConfig.String(key)
}
return v return v
}
return b.innerConfig.String(key)
} }
func (b *beegoAppConfig) Strings(key string) []string { func (b *beegoAppConfig) Strings(key string) []string {
v := b.innerConfig.Strings(BConfig.RunMode + "::" + key) if v := b.innerConfig.Strings(BConfig.RunMode + "::" + key); v[0] != "" {
if v[0] == "" {
return b.innerConfig.Strings(key)
}
return v return v
}
return b.innerConfig.Strings(key)
} }
func (b *beegoAppConfig) Int(key string) (int, error) { func (b *beegoAppConfig) Int(key string) (int, error) {
v, err := b.innerConfig.Int(BConfig.RunMode + "::" + key) if v, err := b.innerConfig.Int(BConfig.RunMode + "::" + key); err == nil {
if err != nil {
return b.innerConfig.Int(key)
}
return v, nil return v, nil
}
return b.innerConfig.Int(key)
} }
func (b *beegoAppConfig) Int64(key string) (int64, error) { func (b *beegoAppConfig) Int64(key string) (int64, error) {
v, err := b.innerConfig.Int64(BConfig.RunMode + "::" + key) if v, err := b.innerConfig.Int64(BConfig.RunMode + "::" + key); err == nil {
if err != nil {
return b.innerConfig.Int64(key)
}
return v, nil return v, nil
}
return b.innerConfig.Int64(key)
} }
func (b *beegoAppConfig) Bool(key string) (bool, error) { func (b *beegoAppConfig) Bool(key string) (bool, error) {
v, err := b.innerConfig.Bool(BConfig.RunMode + "::" + key) if v, err := b.innerConfig.Bool(BConfig.RunMode + "::" + key); err == nil {
if err != nil {
return b.innerConfig.Bool(key)
}
return v, nil return v, nil
}
return b.innerConfig.Bool(key)
} }
func (b *beegoAppConfig) Float(key string) (float64, error) { func (b *beegoAppConfig) Float(key string) (float64, error) {
v, err := b.innerConfig.Float(BConfig.RunMode + "::" + key) if v, err := b.innerConfig.Float(BConfig.RunMode + "::" + key); err == nil {
if err != nil {
return b.innerConfig.Float(key)
}
return v, nil return v, nil
}
return b.innerConfig.Float(key)
} }
func (b *beegoAppConfig) DefaultString(key string, defaultval string) string { func (b *beegoAppConfig) DefaultString(key string, defaultval string) string {
v := b.String(key) if v := b.String(key); v != "" {
if v != "" {
return v return v
} }
return defaultval return defaultval
} }
func (b *beegoAppConfig) DefaultStrings(key string, defaultval []string) []string { func (b *beegoAppConfig) DefaultStrings(key string, defaultval []string) []string {
v := b.Strings(key) if v := b.Strings(key); len(v) != 0 {
if len(v) != 0 {
return v return v
} }
return defaultval return defaultval
} }
func (b *beegoAppConfig) DefaultInt(key string, defaultval int) int { func (b *beegoAppConfig) DefaultInt(key string, defaultval int) int {
v, err := b.Int(key) if v, err := b.Int(key); err == nil {
if err == nil {
return v return v
} }
return defaultval return defaultval
} }
func (b *beegoAppConfig) DefaultInt64(key string, defaultval int64) int64 { func (b *beegoAppConfig) DefaultInt64(key string, defaultval int64) int64 {
v, err := b.Int64(key) if v, err := b.Int64(key); err == nil {
if err == nil {
return v return v
} }
return defaultval return defaultval
} }
func (b *beegoAppConfig) DefaultBool(key string, defaultval bool) bool { func (b *beegoAppConfig) DefaultBool(key string, defaultval bool) bool {
v, err := b.Bool(key) if v, err := b.Bool(key); err == nil {
if err == nil {
return v return v
} }
return defaultval return defaultval
} }
func (b *beegoAppConfig) DefaultFloat(key string, defaultval float64) float64 { func (b *beegoAppConfig) DefaultFloat(key string, defaultval float64) float64 {
v, err := b.Float(key) if v, err := b.Float(key); err == nil {
if err == nil {
return v return v
} }
return defaultval return defaultval

View File

@ -315,7 +315,7 @@ func (input *BeegoInput) Session(key interface{}) interface{} {
// CopyBody returns the raw request body data as bytes. // CopyBody returns the raw request body data as bytes.
func (input *BeegoInput) CopyBody(MaxMemory int64) []byte { func (input *BeegoInput) CopyBody(MaxMemory int64) []byte {
safe := &io.LimitedReader{R:input.Context.Request.Body, N:MaxMemory} safe := &io.LimitedReader{R: input.Context.Request.Body, N: MaxMemory}
requestbody, _ := ioutil.ReadAll(safe) requestbody, _ := ioutil.ReadAll(safe)
input.Context.Request.Body.Close() input.Context.Request.Body.Close()
bf := bytes.NewBuffer(requestbody) bf := bytes.NewBuffer(requestbody)

View File

@ -19,7 +19,6 @@ import (
"errors" "errors"
"html/template" "html/template"
"io" "io"
"io/ioutil"
"mime/multipart" "mime/multipart"
"net/http" "net/http"
"net/url" "net/url"
@ -57,22 +56,31 @@ type ControllerComments struct {
// Controller defines some basic http request handler operations, such as // Controller defines some basic http request handler operations, such as
// http context, template and view, session and xsrf. // http context, template and view, session and xsrf.
type Controller struct { type Controller struct {
// context data
Ctx *context.Context Ctx *context.Context
Data map[interface{}]interface{} Data map[interface{}]interface{}
// route controller info
controllerName string controllerName string
actionName string actionName string
methodMapping map[string]func() //method:routertree
gotofunc string
AppController interface{}
// template data
TplNames string TplNames string
Layout string Layout string
LayoutSections map[string]string // the key is the section name and the value is the template name LayoutSections map[string]string // the key is the section name and the value is the template name
TplExt string TplExt string
_xsrfToken string
gotofunc string
CruSession session.Store
XSRFExpire int
AppController interface{}
EnableRender bool EnableRender bool
// xsrf data
_xsrfToken string
XSRFExpire int
EnableXSRF bool EnableXSRF bool
methodMapping map[string]func() //method:routertree
// session
CruSession session.Store
} }
// ControllerInterface is an interface to uniform all controller handler. // ControllerInterface is an interface to uniform all controller handler.
@ -110,14 +118,10 @@ func (c *Controller) Init(ctx *context.Context, controllerName, actionName strin
} }
// Prepare runs after Init before request function execution. // Prepare runs after Init before request function execution.
func (c *Controller) Prepare() { func (c *Controller) Prepare() {}
}
// Finish runs after request function execution. // Finish runs after request function execution.
func (c *Controller) Finish() { func (c *Controller) Finish() {}
}
// Get adds a request function to handle GET request. // Get adds a request function to handle GET request.
func (c *Controller) Get() { func (c *Controller) Get() {
@ -164,8 +168,7 @@ func (c *Controller) HandlerFunc(fnname string) bool {
} }
// URLMapping register the internal Controller router. // URLMapping register the internal Controller router.
func (c *Controller) URLMapping() { func (c *Controller) URLMapping() {}
}
// Mapping the method to function // Mapping the method to function
func (c *Controller) Mapping(method string, fn func()) { func (c *Controller) Mapping(method string, fn func()) {
@ -195,14 +198,14 @@ func (c *Controller) RenderString() (string, error) {
// RenderBytes returns the bytes of rendered template string. Do not send out response. // RenderBytes returns the bytes of rendered template string. Do not send out response.
func (c *Controller) RenderBytes() ([]byte, error) { func (c *Controller) RenderBytes() ([]byte, error) {
//if the controller has set layout, then first get the tplname's content set the content to the layout //if the controller has set layout, then first get the tplname's content set the content to the layout
var buf bytes.Buffer
if c.Layout != "" { if c.Layout != "" {
if c.TplNames == "" { if c.TplNames == "" {
c.TplNames = strings.ToLower(c.controllerName) + "/" + strings.ToLower(c.actionName) + "." + c.TplExt c.TplNames = strings.ToLower(c.controllerName) + "/" + strings.ToLower(c.actionName) + "." + c.TplExt
} }
if BConfig.RunMode == "dev" { if BConfig.RunMode == "dev" {
buildFiles := make([]string, 1) buildFiles := []string{c.TplNames}
buildFiles = append(buildFiles, c.TplNames)
if c.LayoutSections != nil { if c.LayoutSections != nil {
for _, sectionTpl := range c.LayoutSections { for _, sectionTpl := range c.LayoutSections {
if sectionTpl == "" { if sectionTpl == "" {
@ -213,17 +216,15 @@ func (c *Controller) RenderBytes() ([]byte, error) {
} }
BuildTemplate(BConfig.WebConfig.ViewsPath, buildFiles...) BuildTemplate(BConfig.WebConfig.ViewsPath, buildFiles...)
} }
newbytes := bytes.NewBufferString("")
if _, ok := BeeTemplates[c.TplNames]; !ok { if _, ok := BeeTemplates[c.TplNames]; !ok {
panic("can't find templatefile in the path:" + c.TplNames) panic("can't find templatefile in the path:" + c.TplNames)
} }
err := BeeTemplates[c.TplNames].ExecuteTemplate(newbytes, c.TplNames, c.Data) err := BeeTemplates[c.TplNames].ExecuteTemplate(&buf, c.TplNames, c.Data)
if err != nil { if err != nil {
Trace("template Execute err:", err) Trace("template Execute err:", err)
return nil, err return nil, err
} }
tplcontent, _ := ioutil.ReadAll(newbytes) c.Data["LayoutContent"] = template.HTML(buf.String())
c.Data["LayoutContent"] = template.HTML(string(tplcontent))
if c.LayoutSections != nil { if c.LayoutSections != nil {
for sectionName, sectionTpl := range c.LayoutSections { for sectionName, sectionTpl := range c.LayoutSections {
@ -232,25 +233,23 @@ func (c *Controller) RenderBytes() ([]byte, error) {
continue continue
} }
sectionBytes := bytes.NewBufferString("") buf.Reset()
err = BeeTemplates[sectionTpl].ExecuteTemplate(sectionBytes, sectionTpl, c.Data) err = BeeTemplates[sectionTpl].ExecuteTemplate(&buf, sectionTpl, c.Data)
if err != nil { if err != nil {
Trace("template Execute err:", err) Trace("template Execute err:", err)
return nil, err return nil, err
} }
sectionContent, _ := ioutil.ReadAll(sectionBytes) c.Data[sectionName] = template.HTML(buf.String())
c.Data[sectionName] = template.HTML(string(sectionContent))
} }
} }
ibytes := bytes.NewBufferString("") buf.Reset()
err = BeeTemplates[c.Layout].ExecuteTemplate(ibytes, c.Layout, c.Data) err = BeeTemplates[c.Layout].ExecuteTemplate(&buf, c.Layout, c.Data)
if err != nil { if err != nil {
Trace("template Execute err:", err) Trace("template Execute err:", err)
return nil, err return nil, err
} }
icontent, _ := ioutil.ReadAll(ibytes) return buf.Bytes(), nil
return icontent, nil
} }
if c.TplNames == "" { if c.TplNames == "" {
@ -259,17 +258,16 @@ func (c *Controller) RenderBytes() ([]byte, error) {
if BConfig.RunMode == "dev" { if BConfig.RunMode == "dev" {
BuildTemplate(BConfig.WebConfig.ViewsPath, c.TplNames) BuildTemplate(BConfig.WebConfig.ViewsPath, c.TplNames)
} }
ibytes := bytes.NewBufferString("")
if _, ok := BeeTemplates[c.TplNames]; !ok { if _, ok := BeeTemplates[c.TplNames]; !ok {
panic("can't find templatefile in the path:" + c.TplNames) panic("can't find templatefile in the path:" + c.TplNames)
} }
err := BeeTemplates[c.TplNames].ExecuteTemplate(ibytes, c.TplNames, c.Data) buf.Reset()
err := BeeTemplates[c.TplNames].ExecuteTemplate(&buf, c.TplNames, c.Data)
if err != nil { if err != nil {
Trace("template Execute err:", err) Trace("template Execute err:", err)
return nil, err return nil, err
} }
icontent, _ := ioutil.ReadAll(ibytes) return buf.Bytes(), nil
return icontent, nil
} }
// Redirect sends the redirection response to url with status code. // Redirect sends the redirection response to url with status code.
@ -306,7 +304,7 @@ func (c *Controller) StopRun() {
// URLFor does another controller handler in this request function. // URLFor does another controller handler in this request function.
// it goes to this controller method if endpoint is not clear. // it goes to this controller method if endpoint is not clear.
func (c *Controller) URLFor(endpoint string, values ...interface{}) string { func (c *Controller) URLFor(endpoint string, values ...interface{}) string {
if len(endpoint) <= 0 { if len(endpoint) == 0 {
return "" return ""
} }
if endpoint[0] == '.' { if endpoint[0] == '.' {
@ -317,37 +315,33 @@ func (c *Controller) URLFor(endpoint string, values ...interface{}) string {
// ServeJSON sends a json response with encoding charset. // ServeJSON sends a json response with encoding charset.
func (c *Controller) ServeJSON(encoding ...bool) { func (c *Controller) ServeJSON(encoding ...bool) {
var hasIndent bool var (
var hasencoding bool hasIndent = true
hasEncoding = false
)
if BConfig.RunMode == "prod" { if BConfig.RunMode == "prod" {
hasIndent = false hasIndent = false
} else {
hasIndent = true
} }
if len(encoding) > 0 && encoding[0] == true { if len(encoding) > 0 && encoding[0] == true {
hasencoding = true hasEncoding = true
} }
c.Ctx.Output.JSON(c.Data["json"], hasIndent, hasencoding) c.Ctx.Output.JSON(c.Data["json"], hasIndent, hasEncoding)
} }
// ServeJSONP sends a jsonp response. // ServeJSONP sends a jsonp response.
func (c *Controller) ServeJSONP() { func (c *Controller) ServeJSONP() {
var hasIndent bool hasIndent := true
if BConfig.RunMode == "prod" { if BConfig.RunMode == "prod" {
hasIndent = false hasIndent = false
} else {
hasIndent = true
} }
c.Ctx.Output.JSONP(c.Data["jsonp"], hasIndent) c.Ctx.Output.JSONP(c.Data["jsonp"], hasIndent)
} }
// ServeXML sends xml response. // ServeXML sends xml response.
func (c *Controller) ServeXML() { func (c *Controller) ServeXML() {
var hasIndent bool hasIndent := true
if BConfig.RunMode == "prod" { if BConfig.RunMode == "prod" {
hasIndent = false hasIndent = false
} else {
hasIndent = true
} }
c.Ctx.Output.XML(c.Data["xml"], hasIndent) c.Ctx.Output.XML(c.Data["xml"], hasIndent)
} }
@ -380,15 +374,13 @@ func (c *Controller) ParseForm(obj interface{}) error {
// GetString returns the input value by key string or the default value while it's present and input is blank // GetString returns the input value by key string or the default value while it's present and input is blank
func (c *Controller) GetString(key string, def ...string) string { func (c *Controller) GetString(key string, def ...string) string {
var defv string
if len(def) > 0 {
defv = def[0]
}
if v := c.Ctx.Input.Query(key); v != "" { if v := c.Ctx.Input.Query(key); v != "" {
return v return v
} }
return defv if len(def) > 0 {
return def[0]
}
return ""
} }
// GetStrings returns the input string slice by key string or the default value while it's present and input is blank // GetStrings returns the input string slice by key string or the default value while it's present and input is blank
@ -399,15 +391,14 @@ func (c *Controller) GetStrings(key string, def ...[]string) []string {
defv = def[0] defv = def[0]
} }
f := c.Input() if f := c.Input(); f == nil {
if f == nil {
return defv return defv
} } else {
if vs := f[key]; len(vs) > 0 {
vs := f[key]
if len(vs) > 0 {
return vs return vs
} }
}
return defv return defv
} }
@ -511,8 +502,7 @@ func (c *Controller) GetFile(key string) (multipart.File, *multipart.FileHeader,
// } // }
// } // }
func (c *Controller) GetFiles(key string) ([]*multipart.FileHeader, error) { func (c *Controller) GetFiles(key string) ([]*multipart.FileHeader, error) {
files, ok := c.Ctx.Request.MultipartForm.File[key] if files, ok := c.Ctx.Request.MultipartForm.File[key]; ok {
if ok {
return files, nil return files, nil
} }
return nil, http.ErrMissingFile return nil, http.ErrMissingFile
@ -601,11 +591,9 @@ func (c *Controller) SetSecureCookie(Secret, name, value string, others ...inter
// XSRFToken creates a CSRF token string and returns. // XSRFToken creates a CSRF token string and returns.
func (c *Controller) XSRFToken() string { func (c *Controller) XSRFToken() string {
if c._xsrfToken == "" { if c._xsrfToken == "" {
var expire int64 expire := int64(BConfig.WebConfig.XSRFExpire)
if c.XSRFExpire > 0 { if c.XSRFExpire > 0 {
expire = int64(c.XSRFExpire) expire = int64(c.XSRFExpire)
} else {
expire = int64(BConfig.WebConfig.XSRFExpire)
} }
c._xsrfToken = c.Ctx.XSRFToken(BConfig.WebConfig.XSRFKEY, expire) c._xsrfToken = c.Ctx.XSRFToken(BConfig.WebConfig.XSRFKEY, expire)
} }
@ -629,6 +617,6 @@ func (c *Controller) XSRFFormHTML() string {
} }
// GetControllerAndAction gets the executing controller name and action name. // GetControllerAndAction gets the executing controller name and action name.
func (c *Controller) GetControllerAndAction() (controllerName, actionName string) { func (c *Controller) GetControllerAndAction() (string, string) {
return c.controllerName, c.actionName return c.controllerName, c.actionName
} }

View File

@ -275,7 +275,6 @@ type QueryM2Mer interface {
Count() (int64, error) Count() (int64, error)
} }
// RawPreparer raw query statement // RawPreparer raw query statement
type RawPreparer interface { type RawPreparer interface {
Exec(...interface{}) (sql.Result, error) Exec(...interface{}) (sql.Result, error)

View File

@ -225,8 +225,8 @@ func Benchmark_WithoutCORS(b *testing.B) {
ctx.Output.SetStatus(500) ctx.Output.SetStatus(500)
}) })
b.ResetTimer() b.ResetTimer()
for i := 0; i < 100; i++ {
r, _ := http.NewRequest("PUT", "/foo", nil) r, _ := http.NewRequest("PUT", "/foo", nil)
for i := 0; i < b.N; i++ {
handler.ServeHTTP(recorder, r) handler.ServeHTTP(recorder, r)
} }
} }
@ -246,8 +246,8 @@ func Benchmark_WithCORS(b *testing.B) {
ctx.Output.SetStatus(500) ctx.Output.SetStatus(500)
}) })
b.ResetTimer() b.ResetTimer()
for i := 0; i < 100; i++ {
r, _ := http.NewRequest("PUT", "/foo", nil) r, _ := http.NewRequest("PUT", "/foo", nil)
for i := 0; i < b.N; i++ {
handler.ServeHTTP(recorder, r) handler.ServeHTTP(recorder, r)
} }
} }