diff --git a/beego.go b/beego.go index ff89f2f5..7ebea8a2 100644 --- a/beego.go +++ b/beego.go @@ -23,7 +23,7 @@ import ( const ( // VERSION represent beego web framework version. - VERSION = "1.11.1" + VERSION = "1.11.2" // DEV is for develop DEV = "dev" diff --git a/cache/cache_test.go b/cache/cache_test.go index 9ceb606a..1e71d075 100644 --- a/cache/cache_test.go +++ b/cache/cache_test.go @@ -98,7 +98,7 @@ func TestCache(t *testing.T) { } func TestFileCache(t *testing.T) { - bm, err := NewCache("file", `{"CachePath":"cache","FileSuffix":".bin","DirectoryLevel":2,"EmbedExpiry":0}`) + bm, err := NewCache("file", `{"CachePath":"cache","FileSuffix":".bin","DirectoryLevel":"2","EmbedExpiry":"0"}`) if err != nil { t.Error("init err") } diff --git a/cache/file.go b/cache/file.go index 1926268a..6f12d3ee 100644 --- a/cache/file.go +++ b/cache/file.go @@ -62,11 +62,14 @@ func NewFileCache() Cache { } // StartAndGC will start and begin gc for file cache. -// the config need to be like {CachePath:"/cache","FileSuffix":".bin","DirectoryLevel":2,"EmbedExpiry":0} +// the config need to be like {CachePath:"/cache","FileSuffix":".bin","DirectoryLevel":"2","EmbedExpiry":"0"} func (fc *FileCache) StartAndGC(config string) error { cfg := make(map[string]string) - json.Unmarshal([]byte(config), &cfg) + err := json.Unmarshal([]byte(config), &cfg) + if err != nil { + return err + } if _, ok := cfg["CachePath"]; !ok { cfg["CachePath"] = FileCachePath } @@ -142,12 +145,12 @@ func (fc *FileCache) GetMulti(keys []string) []interface{} { // Put value into file cache. // timeout means how long to keep this file, unit of ms. -// if timeout equals FileCacheEmbedExpiry(default is 0), cache this item forever. +// if timeout equals fc.EmbedExpiry(default is 0), cache this item forever. func (fc *FileCache) Put(key string, val interface{}, timeout time.Duration) error { gob.Register(val) item := FileCacheItem{Data: val} - if timeout == FileCacheEmbedExpiry { + if timeout == time.Duration(fc.EmbedExpiry) { item.Expired = time.Now().Add((86400 * 365 * 10) * time.Second) // ten years } else { item.Expired = time.Now().Add(timeout) @@ -179,7 +182,7 @@ func (fc *FileCache) Incr(key string) error { } else { incr = data.(int) + 1 } - fc.Put(key, incr, FileCacheEmbedExpiry) + fc.Put(key, incr, time.Duration(fc.EmbedExpiry)) return nil } @@ -192,7 +195,7 @@ func (fc *FileCache) Decr(key string) error { } else { decr = data.(int) - 1 } - fc.Put(key, decr, FileCacheEmbedExpiry) + fc.Put(key, decr, time.Duration(fc.EmbedExpiry)) return nil } diff --git a/controller.go b/controller.go index 9c605760..0e8853b3 100644 --- a/controller.go +++ b/controller.go @@ -17,6 +17,7 @@ package beego import ( "bytes" "errors" + "fmt" "html/template" "io" "mime/multipart" @@ -124,6 +125,7 @@ type ControllerInterface interface { Head() Patch() Options() + Trace() Finish() Render() error XSRFToken() string @@ -188,6 +190,28 @@ func (c *Controller) Options() { http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", http.StatusMethodNotAllowed) } +// Trace adds a request function to handle Trace request. +// this method SHOULD NOT be overridden. +// https://tools.ietf.org/html/rfc7231#section-4.3.8 +// The TRACE method requests a remote, application-level loop-back of +// the request message. The final recipient of the request SHOULD +// reflect the message received, excluding some fields described below, +// back to the client as the message body of a 200 (OK) response with a +// Content-Type of "message/http" (Section 8.3.1 of [RFC7230]). +func (c *Controller) Trace() { + ts := func(h http.Header) (hs string) { + for k, v := range h { + hs += fmt.Sprintf("\r\n%s: %s", k, v) + } + return + } + hs := fmt.Sprintf("\r\nTRACE %s %s%s\r\n", c.Ctx.Request.RequestURI, c.Ctx.Request.Proto, ts(c.Ctx.Request.Header)) + c.Ctx.Output.Header("Content-Type", "message/http") + c.Ctx.Output.Header("Content-Length", fmt.Sprint(len(hs))) + c.Ctx.Output.Header("Cache-Control", "no-cache, no-store, must-revalidate") + c.Ctx.WriteString(hs) +} + // HandlerFunc call function with the name func (c *Controller) HandlerFunc(fnname string) bool { if v, ok := c.methodMapping[fnname]; ok { diff --git a/log.go b/log.go new file mode 100644 index 00000000..cc4c0f81 --- /dev/null +++ b/log.go @@ -0,0 +1,127 @@ +// Copyright 2014 beego Author. All Rights Reserved. +// +// 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. + +package beego + +import ( + "strings" + + "github.com/astaxie/beego/logs" +) + +// Log levels to control the logging output. +// Deprecated: use github.com/astaxie/beego/logs instead. +const ( + LevelEmergency = iota + LevelAlert + LevelCritical + LevelError + LevelWarning + LevelNotice + LevelInformational + LevelDebug +) + +// BeeLogger references the used application logger. +// Deprecated: use github.com/astaxie/beego/logs instead. +var BeeLogger = logs.GetBeeLogger() + +// SetLevel sets the global log level used by the simple logger. +// Deprecated: use github.com/astaxie/beego/logs instead. +func SetLevel(l int) { + logs.SetLevel(l) +} + +// SetLogFuncCall set the CallDepth, default is 3 +// Deprecated: use github.com/astaxie/beego/logs instead. +func SetLogFuncCall(b bool) { + logs.SetLogFuncCall(b) +} + +// SetLogger sets a new logger. +// Deprecated: use github.com/astaxie/beego/logs instead. +func SetLogger(adaptername string, config string) error { + return logs.SetLogger(adaptername, config) +} + +// Emergency logs a message at emergency level. +// Deprecated: use github.com/astaxie/beego/logs instead. +func Emergency(v ...interface{}) { + logs.Emergency(generateFmtStr(len(v)), v...) +} + +// Alert logs a message at alert level. +// Deprecated: use github.com/astaxie/beego/logs instead. +func Alert(v ...interface{}) { + logs.Alert(generateFmtStr(len(v)), v...) +} + +// Critical logs a message at critical level. +// Deprecated: use github.com/astaxie/beego/logs instead. +func Critical(v ...interface{}) { + logs.Critical(generateFmtStr(len(v)), v...) +} + +// Error logs a message at error level. +// Deprecated: use github.com/astaxie/beego/logs instead. +func Error(v ...interface{}) { + logs.Error(generateFmtStr(len(v)), v...) +} + +// Warning logs a message at warning level. +// Deprecated: use github.com/astaxie/beego/logs instead. +func Warning(v ...interface{}) { + logs.Warning(generateFmtStr(len(v)), v...) +} + +// Warn compatibility alias for Warning() +// Deprecated: use github.com/astaxie/beego/logs instead. +func Warn(v ...interface{}) { + logs.Warn(generateFmtStr(len(v)), v...) +} + +// Notice logs a message at notice level. +// Deprecated: use github.com/astaxie/beego/logs instead. +func Notice(v ...interface{}) { + logs.Notice(generateFmtStr(len(v)), v...) +} + +// Informational logs a message at info level. +// Deprecated: use github.com/astaxie/beego/logs instead. +func Informational(v ...interface{}) { + logs.Informational(generateFmtStr(len(v)), v...) +} + +// Info compatibility alias for Warning() +// Deprecated: use github.com/astaxie/beego/logs instead. +func Info(v ...interface{}) { + logs.Info(generateFmtStr(len(v)), v...) +} + +// Debug logs a message at debug level. +// Deprecated: use github.com/astaxie/beego/logs instead. +func Debug(v ...interface{}) { + logs.Debug(generateFmtStr(len(v)), v...) +} + +// Trace logs a message at trace level. +// compatibility alias for Warning() +// Deprecated: use github.com/astaxie/beego/logs instead. +func Trace(v ...interface{}) { + logs.Trace(generateFmtStr(len(v)), v...) +} + +func generateFmtStr(n int) string { + return strings.Repeat("%v ", n) +} diff --git a/orm/orm.go b/orm/orm.go index fc3cd400..d322881b 100644 --- a/orm/orm.go +++ b/orm/orm.go @@ -72,7 +72,7 @@ const ( var ( Debug = false DebugLog = NewLog(os.Stdout) - DefaultRowsLimit = 1000 + DefaultRowsLimit = -1 DefaultRelsDepth = 2 DefaultTimeLoc = time.Local ErrTxHasBegan = errors.New(" transaction already begin") diff --git a/parser.go b/parser.go index 81990a4a..5e6b9111 100644 --- a/parser.go +++ b/parser.go @@ -35,7 +35,7 @@ import ( "github.com/astaxie/beego/utils" ) -var globalRouterTemplate = `package routers +var globalRouterTemplate = `package {{.routersDir}} import ( "github.com/astaxie/beego" @@ -516,7 +516,9 @@ func genRouterCode(pkgRealpath string) { } defer f.Close() + routersDir := AppConfig.DefaultString("routersdir", "routers") content := strings.Replace(globalRouterTemplate, "{{.globalinfo}}", globalinfo, -1) + content = strings.Replace(content, "{{.routersDir}}", routersDir, -1) content = strings.Replace(content, "{{.globalimport}}", globalimport, -1) f.WriteString(content) } @@ -574,7 +576,8 @@ func getpathTime(pkgRealpath string) (lastupdate int64, err error) { func getRouterDir(pkgRealpath string) string { dir := filepath.Dir(pkgRealpath) for { - d := filepath.Join(dir, "routers") + routersDir := AppConfig.DefaultString("routersdir", "routers") + d := filepath.Join(dir, routersDir) if utils.FileExists(d) { return d } diff --git a/router.go b/router.go index a9b6f078..b30d2b17 100644 --- a/router.go +++ b/router.go @@ -778,7 +778,7 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) runRouter = routerInfo.controllerType methodParams = routerInfo.methodParams method := r.Method - if r.Method == http.MethodPost && context.Input.Query("_method") == http.MethodPost { + if r.Method == http.MethodPost && context.Input.Query("_method") == http.MethodPut { method = http.MethodPut } if r.Method == http.MethodPost && context.Input.Query("_method") == http.MethodDelete { @@ -843,6 +843,8 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) execController.Patch() case http.MethodOptions: execController.Options() + case http.MethodTrace: + execController.Trace() default: if !execController.HandlerFunc(runMethod) { vc := reflect.ValueOf(execController) diff --git a/templatefunc.go b/templatefunc.go index 5ef9a041..d62442ae 100644 --- a/templatefunc.go +++ b/templatefunc.go @@ -300,7 +300,12 @@ func parseFormToStruct(form url.Values, objT reflect.Type, objV reflect.Value) e formValues := form[tag] var value string if len(formValues) == 0 { - continue + defaultValue := fieldT.Tag.Get("default") + if defaultValue != "" { + value = defaultValue + } else { + continue + } } if len(formValues) == 1 { value = formValues[0]