diff --git a/controllers/base.go b/controllers/base.go index 48ea2b552..07c3c106c 100644 --- a/controllers/base.go +++ b/controllers/base.go @@ -167,10 +167,7 @@ func init() { configPath := os.Getenv("CONFIG_PATH") if len(configPath) != 0 { log.Infof("Config path: %s", configPath) - beego.AppConfigPath = configPath - if err := beego.ParseConfig(); err != nil { - log.Warningf("Failed to parse config file: %s, error: %v", configPath, err) - } + beego.LoadAppConfig("ini", configPath) } langs := strings.Split(beego.AppConfig.String("lang::types"), "|") diff --git a/vendor/github.com/astaxie/beego/.gitignore b/vendor/github.com/astaxie/beego/.gitignore deleted file mode 100644 index 9806457b9..000000000 --- a/vendor/github.com/astaxie/beego/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -.idea -.DS_Store -*.swp -*.swo -beego.iml diff --git a/vendor/github.com/astaxie/beego/.travis.yml b/vendor/github.com/astaxie/beego/.travis.yml deleted file mode 100644 index c59cef619..000000000 --- a/vendor/github.com/astaxie/beego/.travis.yml +++ /dev/null @@ -1,30 +0,0 @@ -language: go - -go: - - 1.5.1 - -services: - - redis-server - - mysql - - postgresql - - memcached -env: - - ORM_DRIVER=sqlite3 ORM_SOURCE=$TRAVIS_BUILD_DIR/orm_test.db - - ORM_DRIVER=mysql ORM_SOURCE="root:@/orm_test?charset=utf8" - - ORM_DRIVER=postgres ORM_SOURCE="user=postgres dbname=orm_test sslmode=disable" -install: - - go get github.com/lib/pq - - go get github.com/go-sql-driver/mysql - - go get github.com/mattn/go-sqlite3 - - go get github.com/bradfitz/gomemcache/memcache - - go get github.com/garyburd/redigo/redis - - go get github.com/beego/x2j - - go get github.com/beego/goyaml2 - - go get github.com/belogik/goes - - go get github.com/couchbase/go-couchbase - - go get github.com/siddontang/ledisdb/config - - go get github.com/siddontang/ledisdb/ledis -before_script: - - sh -c "if [ '$ORM_DRIVER' = 'postgres' ]; then psql -c 'create database orm_test;' -U postgres; fi" - - sh -c "if [ '$ORM_DRIVER' = 'mysql' ]; then mysql -u root -e 'create database orm_test;'; fi" - - sh -c "if [ '$ORM_DRIVER' = 'sqlite' ]; then touch $TRAVIS_BUILD_DIR/orm_test.db; fi" diff --git a/vendor/github.com/astaxie/beego/README.md b/vendor/github.com/astaxie/beego/README.md index fec6113f9..6c5895842 100644 --- a/vendor/github.com/astaxie/beego/README.md +++ b/vendor/github.com/astaxie/beego/README.md @@ -53,6 +53,7 @@ Please see [Documentation](http://beego.me/docs) for more. ## Community * [http://beego.me/community](http://beego.me/community) +* Welcome to join us in Slack: [https://beego.slack.com](https://beego.slack.com), you can get invited from [here](https://github.com/beego/beedoc/issues/232) ## LICENSE diff --git a/vendor/github.com/astaxie/beego/admin.go b/vendor/github.com/astaxie/beego/admin.go index 3effc5824..031e64215 100644 --- a/vendor/github.com/astaxie/beego/admin.go +++ b/vendor/github.com/astaxie/beego/admin.go @@ -90,8 +90,8 @@ func listConf(rw http.ResponseWriter, r *http.Request) { switch command { case "conf": m := make(map[string]interface{}) - m["AppConfigPath"] = AppConfigPath - m["AppConfigProvider"] = AppConfigProvider + m["AppConfigPath"] = appConfigPath + m["AppConfigProvider"] = appConfigProvider m["BConfig.AppName"] = BConfig.AppName m["BConfig.RunMode"] = BConfig.RunMode m["BConfig.RouterCaseSensitive"] = BConfig.RouterCaseSensitive diff --git a/vendor/github.com/astaxie/beego/beego.go b/vendor/github.com/astaxie/beego/beego.go index 04f020714..8f82cdcff 100644 --- a/vendor/github.com/astaxie/beego/beego.go +++ b/vendor/github.com/astaxie/beego/beego.go @@ -15,7 +15,6 @@ package beego import ( - "fmt" "os" "path/filepath" "strconv" @@ -24,7 +23,7 @@ import ( const ( // VERSION represent beego web framework version. - VERSION = "1.6.0" + VERSION = "1.6.1" // DEV is for develop DEV = "dev" @@ -68,21 +67,6 @@ func Run(params ...string) { } func initBeforeHTTPRun() { - // if AppConfigPath is setted or conf/app.conf exist - err := ParseConfig() - if err != nil { - panic(err) - } - //init log - for adaptor, config := range BConfig.Log.Outputs { - err = BeeLogger.SetLogger(adaptor, config) - if err != nil { - fmt.Printf("%s with the config `%s` got err:%s\n", adaptor, config, err) - } - } - - SetLogFuncCall(BConfig.Log.FileLineNum) - //init hooks AddAPPStartHook(registerMime) AddAPPStartHook(registerDefaultErrorHandler) @@ -101,7 +85,7 @@ func initBeforeHTTPRun() { // TestBeegoInit is for test package init func TestBeegoInit(ap string) { os.Setenv("BEEGO_RUNMODE", "test") - AppConfigPath = filepath.Join(ap, "conf", "app.conf") + appConfigPath = filepath.Join(ap, "conf", "app.conf") os.Chdir(ap) initBeforeHTTPRun() } diff --git a/vendor/github.com/astaxie/beego/cache/memcache/memcache.go b/vendor/github.com/astaxie/beego/cache/memcache/memcache.go deleted file mode 100644 index 3f0fe4111..000000000 --- a/vendor/github.com/astaxie/beego/cache/memcache/memcache.go +++ /dev/null @@ -1,190 +0,0 @@ -// 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 memcache for cache provider -// -// depend on github.com/bradfitz/gomemcache/memcache -// -// go install github.com/bradfitz/gomemcache/memcache -// -// Usage: -// import( -// _ "github.com/astaxie/beego/cache/memcache" -// "github.com/astaxie/beego/cache" -// ) -// -// bm, err := cache.NewCache("memcache", `{"conn":"127.0.0.1:11211"}`) -// -// more docs http://beego.me/docs/module/cache.md -package memcache - -import ( - "encoding/json" - "errors" - "strings" - - "github.com/bradfitz/gomemcache/memcache" - - "time" - - "github.com/astaxie/beego/cache" -) - -// Cache Memcache adapter. -type Cache struct { - conn *memcache.Client - conninfo []string -} - -// NewMemCache create new memcache adapter. -func NewMemCache() cache.Cache { - return &Cache{} -} - -// Get get value from memcache. -func (rc *Cache) Get(key string) interface{} { - if rc.conn == nil { - if err := rc.connectInit(); err != nil { - return err - } - } - if item, err := rc.conn.Get(key); err == nil { - return string(item.Value) - } - return nil -} - -// GetMulti get value from memcache. -func (rc *Cache) GetMulti(keys []string) []interface{} { - size := len(keys) - var rv []interface{} - if rc.conn == nil { - if err := rc.connectInit(); err != nil { - for i := 0; i < size; i++ { - rv = append(rv, err) - } - return rv - } - } - mv, err := rc.conn.GetMulti(keys) - if err == nil { - for _, v := range mv { - rv = append(rv, string(v.Value)) - } - return rv - } - for i := 0; i < size; i++ { - rv = append(rv, err) - } - return rv -} - -// Put put value to memcache. only support string. -func (rc *Cache) Put(key string, val interface{}, timeout time.Duration) error { - if rc.conn == nil { - if err := rc.connectInit(); err != nil { - return err - } - } - v, ok := val.(string) - if !ok { - return errors.New("val must string") - } - item := memcache.Item{Key: key, Value: []byte(v), Expiration: int32(timeout / time.Second)} - return rc.conn.Set(&item) -} - -// Delete delete value in memcache. -func (rc *Cache) Delete(key string) error { - if rc.conn == nil { - if err := rc.connectInit(); err != nil { - return err - } - } - return rc.conn.Delete(key) -} - -// Incr increase counter. -func (rc *Cache) Incr(key string) error { - if rc.conn == nil { - if err := rc.connectInit(); err != nil { - return err - } - } - _, err := rc.conn.Increment(key, 1) - return err -} - -// Decr decrease counter. -func (rc *Cache) Decr(key string) error { - if rc.conn == nil { - if err := rc.connectInit(); err != nil { - return err - } - } - _, err := rc.conn.Decrement(key, 1) - return err -} - -// IsExist check value exists in memcache. -func (rc *Cache) IsExist(key string) bool { - if rc.conn == nil { - if err := rc.connectInit(); err != nil { - return false - } - } - _, err := rc.conn.Get(key) - if err != nil { - return false - } - return true -} - -// ClearAll clear all cached in memcache. -func (rc *Cache) ClearAll() error { - if rc.conn == nil { - if err := rc.connectInit(); err != nil { - return err - } - } - return rc.conn.FlushAll() -} - -// StartAndGC start memcache adapter. -// config string is like {"conn":"connection info"}. -// if connecting error, return. -func (rc *Cache) StartAndGC(config string) error { - var cf map[string]string - json.Unmarshal([]byte(config), &cf) - if _, ok := cf["conn"]; !ok { - return errors.New("config has no conn key") - } - rc.conninfo = strings.Split(cf["conn"], ";") - if rc.conn == nil { - if err := rc.connectInit(); err != nil { - return err - } - } - return nil -} - -// connect to memcache and keep the connection. -func (rc *Cache) connectInit() error { - rc.conn = memcache.New(rc.conninfo...) - return nil -} - -func init() { - cache.Register("memcache", NewMemCache) -} diff --git a/vendor/github.com/astaxie/beego/cache/redis/redis.go b/vendor/github.com/astaxie/beego/cache/redis/redis.go deleted file mode 100644 index 781e38366..000000000 --- a/vendor/github.com/astaxie/beego/cache/redis/redis.go +++ /dev/null @@ -1,240 +0,0 @@ -// 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 redis for cache provider -// -// depend on github.com/garyburd/redigo/redis -// -// go install github.com/garyburd/redigo/redis -// -// Usage: -// import( -// _ "github.com/astaxie/beego/cache/redis" -// "github.com/astaxie/beego/cache" -// ) -// -// bm, err := cache.NewCache("redis", `{"conn":"127.0.0.1:11211"}`) -// -// more docs http://beego.me/docs/module/cache.md -package redis - -import ( - "encoding/json" - "errors" - "strconv" - "time" - - "github.com/garyburd/redigo/redis" - - "github.com/astaxie/beego/cache" -) - -var ( - // DefaultKey the collection name of redis for cache adapter. - DefaultKey = "beecacheRedis" -) - -// Cache is Redis cache adapter. -type Cache struct { - p *redis.Pool // redis connection pool - conninfo string - dbNum int - key string - password string -} - -// NewRedisCache create new redis cache with default collection name. -func NewRedisCache() cache.Cache { - return &Cache{key: DefaultKey} -} - -// actually do the redis cmds -func (rc *Cache) do(commandName string, args ...interface{}) (reply interface{}, err error) { - c := rc.p.Get() - defer c.Close() - - return c.Do(commandName, args...) -} - -// Get cache from redis. -func (rc *Cache) Get(key string) interface{} { - if v, err := rc.do("GET", key); err == nil { - return v - } - return nil -} - -// GetMulti get cache from redis. -func (rc *Cache) GetMulti(keys []string) []interface{} { - size := len(keys) - var rv []interface{} - c := rc.p.Get() - defer c.Close() - var err error - for _, key := range keys { - err = c.Send("GET", key) - if err != nil { - goto ERROR - } - } - if err = c.Flush(); err != nil { - goto ERROR - } - for i := 0; i < size; i++ { - if v, err := c.Receive(); err == nil { - rv = append(rv, v.([]byte)) - } else { - rv = append(rv, err) - } - } - return rv -ERROR: - rv = rv[0:0] - for i := 0; i < size; i++ { - rv = append(rv, nil) - } - - return rv -} - -// Put put cache to redis. -func (rc *Cache) Put(key string, val interface{}, timeout time.Duration) error { - var err error - if _, err = rc.do("SETEX", key, int64(timeout/time.Second), val); err != nil { - return err - } - - if _, err = rc.do("HSET", rc.key, key, true); err != nil { - return err - } - return err -} - -// Delete delete cache in redis. -func (rc *Cache) Delete(key string) error { - var err error - if _, err = rc.do("DEL", key); err != nil { - return err - } - _, err = rc.do("HDEL", rc.key, key) - return err -} - -// IsExist check cache's existence in redis. -func (rc *Cache) IsExist(key string) bool { - v, err := redis.Bool(rc.do("EXISTS", key)) - if err != nil { - return false - } - if v == false { - if _, err = rc.do("HDEL", rc.key, key); err != nil { - return false - } - } - return v -} - -// Incr increase counter in redis. -func (rc *Cache) Incr(key string) error { - _, err := redis.Bool(rc.do("INCRBY", key, 1)) - return err -} - -// Decr decrease counter in redis. -func (rc *Cache) Decr(key string) error { - _, err := redis.Bool(rc.do("INCRBY", key, -1)) - return err -} - -// ClearAll clean all cache in redis. delete this redis collection. -func (rc *Cache) ClearAll() error { - cachedKeys, err := redis.Strings(rc.do("HKEYS", rc.key)) - if err != nil { - return err - } - for _, str := range cachedKeys { - if _, err = rc.do("DEL", str); err != nil { - return err - } - } - _, err = rc.do("DEL", rc.key) - return err -} - -// StartAndGC start redis cache adapter. -// config is like {"key":"collection key","conn":"connection info","dbNum":"0"} -// the cache item in redis are stored forever, -// so no gc operation. -func (rc *Cache) StartAndGC(config string) error { - var cf map[string]string - json.Unmarshal([]byte(config), &cf) - - if _, ok := cf["key"]; !ok { - cf["key"] = DefaultKey - } - if _, ok := cf["conn"]; !ok { - return errors.New("config has no conn key") - } - if _, ok := cf["dbNum"]; !ok { - cf["dbNum"] = "0" - } - if _, ok := cf["password"]; !ok { - cf["password"] = "" - } - rc.key = cf["key"] - rc.conninfo = cf["conn"] - rc.dbNum, _ = strconv.Atoi(cf["dbNum"]) - rc.password = cf["password"] - - rc.connectInit() - - c := rc.p.Get() - defer c.Close() - - return c.Err() -} - -// connect to redis. -func (rc *Cache) connectInit() { - dialFunc := func() (c redis.Conn, err error) { - c, err = redis.Dial("tcp", rc.conninfo) - if err != nil { - return nil, err - } - - if rc.password != "" { - if _, err := c.Do("AUTH", rc.password); err != nil { - c.Close() - return nil, err - } - } - - _, selecterr := c.Do("SELECT", rc.dbNum) - if selecterr != nil { - c.Close() - return nil, selecterr - } - return - } - // initialize a new pool - rc.p = &redis.Pool{ - MaxIdle: 3, - IdleTimeout: 180 * time.Second, - Dial: dialFunc, - } -} - -func init() { - cache.Register("redis", NewRedisCache) -} diff --git a/vendor/github.com/astaxie/beego/config.go b/vendor/github.com/astaxie/beego/config.go index 8cf215309..2761e7cba 100644 --- a/vendor/github.com/astaxie/beego/config.go +++ b/vendor/github.com/astaxie/beego/config.go @@ -15,7 +15,7 @@ package beego import ( - "html/template" + "fmt" "os" "path/filepath" "strings" @@ -103,17 +103,22 @@ var ( BConfig *Config // AppConfig is the instance of Config, store the config information from file AppConfig *beegoAppConfig - // AppConfigPath is the path to the config files - AppConfigPath string - // AppConfigProvider is the provider for the config, default is ini - AppConfigProvider = "ini" - // TemplateCache stores template caching - TemplateCache map[string]*template.Template + // AppPath is the absolute path to the app + AppPath string // GlobalSessions is the instance for the session manager GlobalSessions *session.Manager + + // appConfigPath is the path to the config files + appConfigPath string + // appConfigProvider is the provider for the config, default is ini + appConfigProvider = "ini" ) func init() { + AppPath, _ = filepath.Abs(filepath.Dir(os.Args[0])) + + os.Chdir(AppPath) + BConfig = &Config{ AppName: "beego", RunMode: DEV, @@ -162,7 +167,7 @@ func init() { SessionName: "beegosessionID", SessionGCMaxLifetime: 3600, SessionProviderConfig: "", - SessionCookieLifeTime: 0, //set cookie default is the brower life + SessionCookieLifeTime: 0, //set cookie default is the browser life SessionAutoSetCookie: true, SessionDomain: "", }, @@ -173,29 +178,29 @@ func init() { Outputs: map[string]string{"console": ""}, }, } - ParseConfig() + + 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) + } } -// 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) +func parseConfig(appConfigPath string) (err error) { + AppConfig, err = newAppConfig(appConfigProvider, appConfigPath) if err != nil { return err } - // set the runmode first + // set the run mode first if envRunMode := os.Getenv("BEEGO_RUNMODE"); envRunMode != "" { BConfig.RunMode = envRunMode - } else if runmode := AppConfig.String("RunMode"); runmode != "" { - BConfig.RunMode = runmode + } else if runMode := AppConfig.String("RunMode"); runMode != "" { + BConfig.RunMode = runMode } BConfig.AppName = AppConfig.DefaultString("AppName", BConfig.AppName) @@ -241,6 +246,8 @@ func ParseConfig() (err error) { 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) + BConfig.Log.AccessLogs = AppConfig.DefaultBool("LogAccessLogs", BConfig.Log.AccessLogs) + BConfig.Log.FileLineNum = AppConfig.DefaultBool("LogFileLineNum", BConfig.Log.FileLineNum) if sd := AppConfig.String("StaticDir"); sd != "" { for k := range BConfig.WebConfig.StaticDir { @@ -273,15 +280,58 @@ func ParseConfig() (err error) { BConfig.WebConfig.StaticExtensionsToGzip = fileExts } } + + if lo := AppConfig.String("LogOutputs"); lo != "" { + los := strings.Split(lo, ";") + for _, v := range los { + if logType2Config := strings.SplitN(v, ",", 2); len(logType2Config) == 2 { + BConfig.Log.Outputs[logType2Config[0]] = logType2Config[1] + } else { + continue + } + } + } + + //init log + BeeLogger.Reset() + for adaptor, config := range BConfig.Log.Outputs { + err = BeeLogger.SetLogger(adaptor, config) + if err != nil { + fmt.Printf("%s with the config `%s` got err:%s\n", adaptor, config, err) + } + } + SetLogFuncCall(BConfig.Log.FileLineNum) + return nil } +// 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) + } + + if absConfigPath == appConfigPath { + return nil + } + + appConfigPath = absConfigPath + appConfigProvider = adapterName + + return parseConfig(appConfigPath) +} + type beegoAppConfig struct { innerConfig config.Configer } -func newAppConfig(AppConfigProvider, AppConfigPath string) (*beegoAppConfig, error) { - ac, err := config.NewConfig(AppConfigProvider, AppConfigPath) +func newAppConfig(appConfigProvider, appConfigPath string) (*beegoAppConfig, error) { + ac, err := config.NewConfig(appConfigProvider, appConfigPath) if err != nil { return nil, err } @@ -337,46 +387,46 @@ func (b *beegoAppConfig) Float(key string) (float64, error) { return b.innerConfig.Float(key) } -func (b *beegoAppConfig) DefaultString(key string, defaultval string) string { +func (b *beegoAppConfig) DefaultString(key string, defaultVal string) string { if v := b.String(key); 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 { if v := b.Strings(key); len(v) != 0 { return v } - return defaultval + return defaultVal } -func (b *beegoAppConfig) DefaultInt(key string, defaultval int) int { +func (b *beegoAppConfig) DefaultInt(key string, defaultVal int) int { if v, err := b.Int(key); err == nil { return v } - return defaultval + return defaultVal } -func (b *beegoAppConfig) DefaultInt64(key string, defaultval int64) int64 { +func (b *beegoAppConfig) DefaultInt64(key string, defaultVal int64) int64 { if v, err := b.Int64(key); err == nil { return v } - return defaultval + return defaultVal } -func (b *beegoAppConfig) DefaultBool(key string, defaultval bool) bool { +func (b *beegoAppConfig) DefaultBool(key string, defaultVal bool) bool { if v, err := b.Bool(key); err == nil { return v } - return defaultval + return defaultVal } -func (b *beegoAppConfig) DefaultFloat(key string, defaultval float64) float64 { +func (b *beegoAppConfig) DefaultFloat(key string, defaultVal float64) float64 { if v, err := b.Float(key); err == nil { return v } - return defaultval + return defaultVal } func (b *beegoAppConfig) DIY(key string) (interface{}, error) { diff --git a/vendor/github.com/astaxie/beego/config/config.go b/vendor/github.com/astaxie/beego/config/config.go index da5d358bd..c0afec058 100644 --- a/vendor/github.com/astaxie/beego/config/config.go +++ b/vendor/github.com/astaxie/beego/config/config.go @@ -106,3 +106,39 @@ func NewConfigData(adapterName string, data []byte) (Configer, error) { } return adapter.ParseData(data) } + +// ParseBool returns the boolean value represented by the string. +// +// It accepts 1, 1.0, t, T, TRUE, true, True, YES, yes, Yes,Y, y, ON, on, On, +// 0, 0.0, f, F, FALSE, false, False, NO, no, No, N,n, OFF, off, Off. +// Any other value returns an error. +func ParseBool(val interface{}) (value bool, err error) { + if val != nil { + switch v := val.(type) { + case bool: + return v, nil + case string: + switch v { + case "1", "t", "T", "true", "TRUE", "True", "YES", "yes", "Yes", "Y", "y", "ON", "on", "On": + return true, nil + case "0", "f", "F", "false", "FALSE", "False", "NO", "no", "No", "N", "n", "OFF", "off", "Off": + return false, nil + } + case int8, int32, int64: + strV := fmt.Sprintf("%s", v) + if strV == "1" { + return true, nil + } else if strV == "0" { + return false, nil + } + case float64: + if v == 1 { + return true, nil + } else if v == 0 { + return false, nil + } + } + return false, fmt.Errorf("parsing %q: invalid syntax", val) + } + return false, fmt.Errorf("parsing : invalid syntax") +} diff --git a/vendor/github.com/astaxie/beego/config/fake.go b/vendor/github.com/astaxie/beego/config/fake.go index 50aa5d4a4..7e3626087 100644 --- a/vendor/github.com/astaxie/beego/config/fake.go +++ b/vendor/github.com/astaxie/beego/config/fake.go @@ -46,12 +46,16 @@ func (c *fakeConfigContainer) DefaultString(key string, defaultval string) strin } func (c *fakeConfigContainer) Strings(key string) []string { - return strings.Split(c.getData(key), ";") + v := c.getData(key) + if v == "" { + return nil + } + return strings.Split(v, ";") } func (c *fakeConfigContainer) DefaultStrings(key string, defaultval []string) []string { v := c.Strings(key) - if len(v) == 0 { + if v == nil { return defaultval } return v @@ -82,7 +86,7 @@ func (c *fakeConfigContainer) DefaultInt64(key string, defaultval int64) int64 { } func (c *fakeConfigContainer) Bool(key string) (bool, error) { - return strconv.ParseBool(c.getData(key)) + return ParseBool(c.getData(key)) } func (c *fakeConfigContainer) DefaultBool(key string, defaultval bool) bool { diff --git a/vendor/github.com/astaxie/beego/config/ini.go b/vendor/github.com/astaxie/beego/config/ini.go index 59e84e1e5..9c19b9b1b 100644 --- a/vendor/github.com/astaxie/beego/config/ini.go +++ b/vendor/github.com/astaxie/beego/config/ini.go @@ -27,7 +27,6 @@ import ( "strings" "sync" "time" - "unicode" ) var ( @@ -97,9 +96,11 @@ func (ini *IniConfig) parseFile(name string) (*IniConfigContainer, error) { } if bComment != nil { line = bytes.TrimLeft(line, string(bComment)) - line = bytes.TrimLeftFunc(line, unicode.IsSpace) + // Need append to a new line if multi-line comments. + if comment.Len() > 0 { + comment.WriteByte('\n') + } comment.Write(line) - comment.WriteByte('\n') continue } @@ -194,7 +195,7 @@ type IniConfigContainer struct { // Bool returns the boolean value for a given key. func (c *IniConfigContainer) Bool(key string) (bool, error) { - return strconv.ParseBool(c.getdata(key)) + return ParseBool(c.getdata(key)) } // DefaultBool returns the boolean value for a given key. @@ -268,15 +269,20 @@ func (c *IniConfigContainer) DefaultString(key string, defaultval string) string } // Strings returns the []string value for a given key. +// Return nil if config value does not exist or is empty. func (c *IniConfigContainer) Strings(key string) []string { - return strings.Split(c.String(key), ";") + v := c.String(key) + if v == "" { + return nil + } + return strings.Split(v, ";") } // DefaultStrings returns the []string value for a given key. // if err != nil return defaltval func (c *IniConfigContainer) DefaultStrings(key string, defaultval []string) []string { v := c.Strings(key) - if len(v) == 0 { + if v == nil { return defaultval } return v @@ -299,14 +305,35 @@ func (c *IniConfigContainer) SaveConfigFile(filename string) (err error) { } defer f.Close() + // Get section or key comments. Fixed #1607 + getCommentStr := func(section, key string) string { + comment, ok := "", false + if len(key) == 0 { + comment, ok = c.sectionComment[section] + } else { + comment, ok = c.keyComment[section+"."+key] + } + + if ok { + // Empty comment + if len(comment) == 0 || len(strings.TrimSpace(comment)) == 0 { + return string(bNumComment) + } + prefix := string(bNumComment) + // Add the line head character "#" + return prefix + strings.Replace(comment, lineBreak, lineBreak+prefix, -1) + } + return "" + } + buf := bytes.NewBuffer(nil) // Save default section at first place if dt, ok := c.data[defaultSection]; ok { for key, val := range dt { if key != " " { // Write key comments. - if v, ok := c.keyComment[key]; ok { - if _, err = buf.WriteString(string(bNumComment) + v + lineBreak); err != nil { + if v := getCommentStr(defaultSection, key); len(v) > 0 { + if _, err = buf.WriteString(v + lineBreak); err != nil { return err } } @@ -327,8 +354,8 @@ func (c *IniConfigContainer) SaveConfigFile(filename string) (err error) { for section, dt := range c.data { if section != defaultSection { // Write section comments. - if v, ok := c.sectionComment[section]; ok { - if _, err = buf.WriteString(string(bNumComment) + v + lineBreak); err != nil { + if v := getCommentStr(section, ""); len(v) > 0 { + if _, err = buf.WriteString(v + lineBreak); err != nil { return err } } @@ -341,8 +368,8 @@ func (c *IniConfigContainer) SaveConfigFile(filename string) (err error) { for key, val := range dt { if key != " " { // Write key comments. - if v, ok := c.keyComment[key]; ok { - if _, err = buf.WriteString(string(bNumComment) + v + lineBreak); err != nil { + if v := getCommentStr(section, key); len(v) > 0 { + if _, err = buf.WriteString(v + lineBreak); err != nil { return err } } diff --git a/vendor/github.com/astaxie/beego/config/json.go b/vendor/github.com/astaxie/beego/config/json.go index 65b4ac48a..fce517eb8 100644 --- a/vendor/github.com/astaxie/beego/config/json.go +++ b/vendor/github.com/astaxie/beego/config/json.go @@ -17,6 +17,7 @@ package config import ( "encoding/json" "errors" + "fmt" "io/ioutil" "os" "strings" @@ -70,12 +71,9 @@ type JSONConfigContainer struct { func (c *JSONConfigContainer) Bool(key string) (bool, error) { val := c.getData(key) if val != nil { - if v, ok := val.(bool); ok { - return v, nil - } - return false, errors.New("not bool value") + return ParseBool(val) } - return false, errors.New("not exist key:" + key) + return false, fmt.Errorf("not exist key: %q", key) } // DefaultBool return the bool value if has no error @@ -175,7 +173,7 @@ func (c *JSONConfigContainer) DefaultString(key string, defaultval string) strin func (c *JSONConfigContainer) Strings(key string) []string { stringVal := c.String(key) if stringVal == "" { - return []string{} + return nil } return strings.Split(c.String(key), ";") } @@ -183,7 +181,7 @@ func (c *JSONConfigContainer) Strings(key string) []string { // DefaultStrings returns the []string value for a given key. // if err != nil return defaltval func (c *JSONConfigContainer) DefaultStrings(key string, defaultval []string) []string { - if v := c.Strings(key); len(v) > 0 { + if v := c.Strings(key); v != nil { return v } return defaultval diff --git a/vendor/github.com/astaxie/beego/config/xml/xml.go b/vendor/github.com/astaxie/beego/config/xml/xml.go deleted file mode 100644 index 4d48f7d2c..000000000 --- a/vendor/github.com/astaxie/beego/config/xml/xml.go +++ /dev/null @@ -1,229 +0,0 @@ -// 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 xml for config provider -// -// depend on github.com/beego/x2j -// -// go install github.com/beego/x2j -// -// Usage: -// import( -// _ "github.com/astaxie/beego/config/xml" -// "github.com/astaxie/beego/config" -// ) -// -// cnf, err := config.NewConfig("xml", "config.xml") -// -// more docs http://beego.me/docs/module/config.md -package xml - -import ( - "encoding/xml" - "errors" - "fmt" - "io/ioutil" - "os" - "path" - "strconv" - "strings" - "sync" - "time" - - "github.com/astaxie/beego/config" - "github.com/beego/x2j" -) - -// Config is a xml config parser and implements Config interface. -// xml configurations should be included in tag. -// only support key/value pair as value as each item. -type Config struct{} - -// Parse returns a ConfigContainer with parsed xml config map. -func (xc *Config) Parse(filename string) (config.Configer, error) { - file, err := os.Open(filename) - if err != nil { - return nil, err - } - defer file.Close() - - x := &ConfigContainer{data: make(map[string]interface{})} - content, err := ioutil.ReadAll(file) - if err != nil { - return nil, err - } - - d, err := x2j.DocToMap(string(content)) - if err != nil { - return nil, err - } - - x.data = d["config"].(map[string]interface{}) - return x, nil -} - -// ParseData xml data -func (xc *Config) ParseData(data []byte) (config.Configer, error) { - // Save memory data to temporary file - tmpName := path.Join(os.TempDir(), "beego", fmt.Sprintf("%d", time.Now().Nanosecond())) - os.MkdirAll(path.Dir(tmpName), os.ModePerm) - if err := ioutil.WriteFile(tmpName, data, 0655); err != nil { - return nil, err - } - return xc.Parse(tmpName) -} - -// ConfigContainer A Config represents the xml configuration. -type ConfigContainer struct { - data map[string]interface{} - sync.Mutex -} - -// Bool returns the boolean value for a given key. -func (c *ConfigContainer) Bool(key string) (bool, error) { - return strconv.ParseBool(c.data[key].(string)) -} - -// DefaultBool return the bool value if has no error -// otherwise return the defaultval -func (c *ConfigContainer) DefaultBool(key string, defaultval bool) bool { - v, err := c.Bool(key) - if err != nil { - return defaultval - } - return v -} - -// Int returns the integer value for a given key. -func (c *ConfigContainer) Int(key string) (int, error) { - return strconv.Atoi(c.data[key].(string)) -} - -// DefaultInt returns the integer value for a given key. -// if err != nil return defaltval -func (c *ConfigContainer) DefaultInt(key string, defaultval int) int { - v, err := c.Int(key) - if err != nil { - return defaultval - } - return v -} - -// Int64 returns the int64 value for a given key. -func (c *ConfigContainer) Int64(key string) (int64, error) { - return strconv.ParseInt(c.data[key].(string), 10, 64) -} - -// DefaultInt64 returns the int64 value for a given key. -// if err != nil return defaltval -func (c *ConfigContainer) DefaultInt64(key string, defaultval int64) int64 { - v, err := c.Int64(key) - if err != nil { - return defaultval - } - return v - -} - -// Float returns the float value for a given key. -func (c *ConfigContainer) Float(key string) (float64, error) { - return strconv.ParseFloat(c.data[key].(string), 64) -} - -// DefaultFloat returns the float64 value for a given key. -// if err != nil return defaltval -func (c *ConfigContainer) DefaultFloat(key string, defaultval float64) float64 { - v, err := c.Float(key) - if err != nil { - return defaultval - } - return v -} - -// String returns the string value for a given key. -func (c *ConfigContainer) String(key string) string { - if v, ok := c.data[key].(string); ok { - return v - } - return "" -} - -// DefaultString returns the string value for a given key. -// if err != nil return defaltval -func (c *ConfigContainer) DefaultString(key string, defaultval string) string { - v := c.String(key) - if v == "" { - return defaultval - } - return v -} - -// Strings returns the []string value for a given key. -func (c *ConfigContainer) Strings(key string) []string { - return strings.Split(c.String(key), ";") -} - -// DefaultStrings returns the []string value for a given key. -// if err != nil return defaltval -func (c *ConfigContainer) DefaultStrings(key string, defaultval []string) []string { - v := c.Strings(key) - if len(v) == 0 { - return defaultval - } - return v -} - -// GetSection returns map for the given section -func (c *ConfigContainer) GetSection(section string) (map[string]string, error) { - if v, ok := c.data[section]; ok { - return v.(map[string]string), nil - } - return nil, errors.New("not exist setction") -} - -// SaveConfigFile save the config into file -func (c *ConfigContainer) SaveConfigFile(filename string) (err error) { - // Write configuration file by filename. - f, err := os.Create(filename) - if err != nil { - return err - } - defer f.Close() - b, err := xml.MarshalIndent(c.data, " ", " ") - if err != nil { - return err - } - _, err = f.Write(b) - return err -} - -// Set writes a new value for key. -func (c *ConfigContainer) Set(key, val string) error { - c.Lock() - defer c.Unlock() - c.data[key] = val - return nil -} - -// DIY returns the raw value by a given key. -func (c *ConfigContainer) DIY(key string) (v interface{}, err error) { - if v, ok := c.data[key]; ok { - return v, nil - } - return nil, errors.New("not exist key") -} - -func init() { - config.Register("xml", &Config{}) -} diff --git a/vendor/github.com/astaxie/beego/config/yaml/yaml.go b/vendor/github.com/astaxie/beego/config/yaml/yaml.go deleted file mode 100644 index f034d3ba3..000000000 --- a/vendor/github.com/astaxie/beego/config/yaml/yaml.go +++ /dev/null @@ -1,266 +0,0 @@ -// 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 yaml for config provider -// -// depend on github.com/beego/goyaml2 -// -// go install github.com/beego/goyaml2 -// -// Usage: -// import( -// _ "github.com/astaxie/beego/config/yaml" -// "github.com/astaxie/beego/config" -// ) -// -// cnf, err := config.NewConfig("yaml", "config.yaml") -// -// more docs http://beego.me/docs/module/config.md -package yaml - -import ( - "bytes" - "encoding/json" - "errors" - "fmt" - "io/ioutil" - "log" - "os" - "path" - "strings" - "sync" - "time" - - "github.com/astaxie/beego/config" - "github.com/beego/goyaml2" -) - -// Config is a yaml config parser and implements Config interface. -type Config struct{} - -// Parse returns a ConfigContainer with parsed yaml config map. -func (yaml *Config) Parse(filename string) (y config.Configer, err error) { - cnf, err := ReadYmlReader(filename) - if err != nil { - return - } - y = &ConfigContainer{ - data: cnf, - } - return -} - -// ParseData parse yaml data -func (yaml *Config) ParseData(data []byte) (config.Configer, error) { - // Save memory data to temporary file - tmpName := path.Join(os.TempDir(), "beego", fmt.Sprintf("%d", time.Now().Nanosecond())) - os.MkdirAll(path.Dir(tmpName), os.ModePerm) - if err := ioutil.WriteFile(tmpName, data, 0655); err != nil { - return nil, err - } - return yaml.Parse(tmpName) -} - -// ReadYmlReader Read yaml file to map. -// if json like, use json package, unless goyaml2 package. -func ReadYmlReader(path string) (cnf map[string]interface{}, err error) { - f, err := os.Open(path) - if err != nil { - return - } - defer f.Close() - - buf, err := ioutil.ReadAll(f) - if err != nil || len(buf) < 3 { - return - } - - if string(buf[0:1]) == "{" { - log.Println("Look like a Json, try json umarshal") - err = json.Unmarshal(buf, &cnf) - if err == nil { - log.Println("It is Json Map") - return - } - } - - data, err := goyaml2.Read(bytes.NewBuffer(buf)) - if err != nil { - log.Println("Goyaml2 ERR>", string(buf), err) - return - } - - if data == nil { - log.Println("Goyaml2 output nil? Pls report bug\n" + string(buf)) - return - } - cnf, ok := data.(map[string]interface{}) - if !ok { - log.Println("Not a Map? >> ", string(buf), data) - cnf = nil - } - return -} - -// ConfigContainer A Config represents the yaml configuration. -type ConfigContainer struct { - data map[string]interface{} - sync.Mutex -} - -// Bool returns the boolean value for a given key. -func (c *ConfigContainer) Bool(key string) (bool, error) { - if v, ok := c.data[key].(bool); ok { - return v, nil - } - return false, errors.New("not bool value") -} - -// DefaultBool return the bool value if has no error -// otherwise return the defaultval -func (c *ConfigContainer) DefaultBool(key string, defaultval bool) bool { - v, err := c.Bool(key) - if err != nil { - return defaultval - } - return v -} - -// Int returns the integer value for a given key. -func (c *ConfigContainer) Int(key string) (int, error) { - if v, ok := c.data[key].(int64); ok { - return int(v), nil - } - return 0, errors.New("not int value") -} - -// DefaultInt returns the integer value for a given key. -// if err != nil return defaltval -func (c *ConfigContainer) DefaultInt(key string, defaultval int) int { - v, err := c.Int(key) - if err != nil { - return defaultval - } - return v -} - -// Int64 returns the int64 value for a given key. -func (c *ConfigContainer) Int64(key string) (int64, error) { - if v, ok := c.data[key].(int64); ok { - return v, nil - } - return 0, errors.New("not bool value") -} - -// DefaultInt64 returns the int64 value for a given key. -// if err != nil return defaltval -func (c *ConfigContainer) DefaultInt64(key string, defaultval int64) int64 { - v, err := c.Int64(key) - if err != nil { - return defaultval - } - return v -} - -// Float returns the float value for a given key. -func (c *ConfigContainer) Float(key string) (float64, error) { - if v, ok := c.data[key].(float64); ok { - return v, nil - } - return 0.0, errors.New("not float64 value") -} - -// DefaultFloat returns the float64 value for a given key. -// if err != nil return defaltval -func (c *ConfigContainer) DefaultFloat(key string, defaultval float64) float64 { - v, err := c.Float(key) - if err != nil { - return defaultval - } - return v -} - -// String returns the string value for a given key. -func (c *ConfigContainer) String(key string) string { - if v, ok := c.data[key].(string); ok { - return v - } - return "" -} - -// DefaultString returns the string value for a given key. -// if err != nil return defaltval -func (c *ConfigContainer) DefaultString(key string, defaultval string) string { - v := c.String(key) - if v == "" { - return defaultval - } - return v -} - -// Strings returns the []string value for a given key. -func (c *ConfigContainer) Strings(key string) []string { - return strings.Split(c.String(key), ";") -} - -// DefaultStrings returns the []string value for a given key. -// if err != nil return defaltval -func (c *ConfigContainer) DefaultStrings(key string, defaultval []string) []string { - v := c.Strings(key) - if len(v) == 0 { - return defaultval - } - return v -} - -// GetSection returns map for the given section -func (c *ConfigContainer) GetSection(section string) (map[string]string, error) { - v, ok := c.data[section] - if ok { - return v.(map[string]string), nil - } - return nil, errors.New("not exist setction") -} - -// SaveConfigFile save the config into file -func (c *ConfigContainer) SaveConfigFile(filename string) (err error) { - // Write configuration file by filename. - f, err := os.Create(filename) - if err != nil { - return err - } - defer f.Close() - err = goyaml2.Write(f, c.data) - return err -} - -// Set writes a new value for key. -func (c *ConfigContainer) Set(key, val string) error { - c.Lock() - defer c.Unlock() - c.data[key] = val - return nil -} - -// DIY returns the raw value by a given key. -func (c *ConfigContainer) DIY(key string) (v interface{}, err error) { - if v, ok := c.data[key]; ok { - return v, nil - } - return nil, errors.New("not exist key") -} - -func init() { - config.Register("yaml", &Config{}) -} diff --git a/vendor/github.com/astaxie/beego/context/context.go b/vendor/github.com/astaxie/beego/context/context.go index db790ff2f..63a1313d2 100644 --- a/vendor/github.com/astaxie/beego/context/context.go +++ b/vendor/github.com/astaxie/beego/context/context.go @@ -24,11 +24,13 @@ package context import ( "bufio" + "bytes" "crypto/hmac" "crypto/sha1" "encoding/base64" "errors" "fmt" + "io" "net" "net/http" "strconv" @@ -59,7 +61,10 @@ type Context struct { // Reset init Context, BeegoInput and BeegoOutput func (ctx *Context) Reset(rw http.ResponseWriter, r *http.Request) { ctx.Request = r - ctx.ResponseWriter = &Response{rw, false, 0} + if ctx.ResponseWriter == nil { + ctx.ResponseWriter = &Response{} + } + ctx.ResponseWriter.reset(rw) ctx.Input.Reset(ctx) ctx.Output.Reset(ctx) } @@ -176,25 +181,43 @@ type Response struct { Status int } +func (r *Response) reset(rw http.ResponseWriter) { + r.ResponseWriter = rw + r.Status = 0 + r.Started = false +} + // Write writes the data to the connection as part of an HTTP reply, // and sets `started` to true. // started means the response has sent out. -func (w *Response) Write(p []byte) (int, error) { - w.Started = true - return w.ResponseWriter.Write(p) +func (r *Response) Write(p []byte) (int, error) { + r.Started = true + return r.ResponseWriter.Write(p) +} + +// Copy writes the data to the connection as part of an HTTP reply, +// and sets `started` to true. +// started means the response has sent out. +func (r *Response) Copy(buf *bytes.Buffer) (int64, error) { + r.Started = true + return io.Copy(r.ResponseWriter, buf) } // WriteHeader sends an HTTP response header with status code, // and sets `started` to true. -func (w *Response) WriteHeader(code int) { - w.Status = code - w.Started = true - w.ResponseWriter.WriteHeader(code) +func (r *Response) WriteHeader(code int) { + if r.Status > 0 { + //prevent multiple response.WriteHeader calls + return + } + r.Status = code + r.Started = true + r.ResponseWriter.WriteHeader(code) } // Hijack hijacker for http -func (w *Response) Hijack() (net.Conn, *bufio.ReadWriter, error) { - hj, ok := w.ResponseWriter.(http.Hijacker) +func (r *Response) Hijack() (net.Conn, *bufio.ReadWriter, error) { + hj, ok := r.ResponseWriter.(http.Hijacker) if !ok { return nil, nil, errors.New("webserver doesn't support hijacking") } @@ -202,15 +225,15 @@ func (w *Response) Hijack() (net.Conn, *bufio.ReadWriter, error) { } // Flush http.Flusher -func (w *Response) Flush() { - if f, ok := w.ResponseWriter.(http.Flusher); ok { +func (r *Response) Flush() { + if f, ok := r.ResponseWriter.(http.Flusher); ok { f.Flush() } } // CloseNotify http.CloseNotifier -func (w *Response) CloseNotify() <-chan bool { - if cn, ok := w.ResponseWriter.(http.CloseNotifier); ok { +func (r *Response) CloseNotify() <-chan bool { + if cn, ok := r.ResponseWriter.(http.CloseNotifier); ok { return cn.CloseNotify() } return nil diff --git a/vendor/github.com/astaxie/beego/context/input.go b/vendor/github.com/astaxie/beego/context/input.go index c37204bdc..edfdf5302 100644 --- a/vendor/github.com/astaxie/beego/context/input.go +++ b/vendor/github.com/astaxie/beego/context/input.go @@ -287,6 +287,13 @@ func (input *BeegoInput) Params() map[string]string { // SetParam will set the param with key and value func (input *BeegoInput) SetParam(key, val string) { + // check if already exists + for i, v := range input.pnames { + if v == key && i <= len(input.pvalues) { + input.pvalues[i] = val + return + } + } input.pvalues = append(input.pvalues, val) input.pnames = append(input.pnames, key) } diff --git a/vendor/github.com/astaxie/beego/context/output.go b/vendor/github.com/astaxie/beego/context/output.go index 2d756e271..174047020 100644 --- a/vendor/github.com/astaxie/beego/context/output.go +++ b/vendor/github.com/astaxie/beego/context/output.go @@ -21,7 +21,6 @@ import ( "errors" "fmt" "html/template" - "io" "mime" "net/http" "path/filepath" @@ -57,7 +56,7 @@ func (output *BeegoOutput) Header(key, val string) { // Body sets response body content. // if EnableGzip, compress content string. // it sends out response body directly. -func (output *BeegoOutput) Body(content []byte) { +func (output *BeegoOutput) Body(content []byte) error { var encoding string var buf = &bytes.Buffer{} if output.EnableGzip { @@ -75,7 +74,8 @@ func (output *BeegoOutput) Body(content []byte) { output.Status = 0 } - io.Copy(output.Context.ResponseWriter, buf) + _, err := output.Context.ResponseWriter.Copy(buf) + return err } // Cookie sets cookie value via given key. @@ -97,9 +97,10 @@ func (output *BeegoOutput) Cookie(name string, value string, others ...interface maxAge = v } - if maxAge > 0 { + switch { + case maxAge > 0: fmt.Fprintf(&b, "; Expires=%s; Max-Age=%d", time.Now().Add(time.Duration(maxAge)*time.Second).UTC().Format(time.RFC1123), maxAge) - } else { + case maxAge < 0: fmt.Fprintf(&b, "; Max-Age=0") } } @@ -186,8 +187,7 @@ func (output *BeegoOutput) JSON(data interface{}, hasIndent bool, coding bool) e if coding { content = []byte(stringsToJSON(string(content))) } - output.Body(content) - return nil + return output.Body(content) } // JSONP writes jsonp to response body. @@ -212,8 +212,7 @@ func (output *BeegoOutput) JSONP(data interface{}, hasIndent bool) error { callbackContent.WriteString("(") callbackContent.Write(content) callbackContent.WriteString(");\r\n") - output.Body(callbackContent.Bytes()) - return nil + return output.Body(callbackContent.Bytes()) } // XML writes xml string to response body. @@ -230,8 +229,7 @@ func (output *BeegoOutput) XML(data interface{}, hasIndent bool) error { http.Error(output.Context.ResponseWriter, err.Error(), http.StatusInternalServerError) return err } - output.Body(content) - return nil + return output.Body(content) } // Download forces response for download file. diff --git a/vendor/github.com/astaxie/beego/controller.go b/vendor/github.com/astaxie/beego/controller.go index a2943d420..dc2758480 100644 --- a/vendor/github.com/astaxie/beego/controller.go +++ b/vendor/github.com/astaxie/beego/controller.go @@ -185,8 +185,7 @@ func (c *Controller) Render() error { return err } c.Ctx.Output.Header("Content-Type", "text/html; charset=utf-8") - c.Ctx.Output.Body(rb) - return nil + return c.Ctx.Output.Body(rb) } // RenderString returns the rendered template string. Do not send out response. @@ -197,33 +196,9 @@ func (c *Controller) RenderString() (string, error) { // RenderBytes returns the bytes of rendered template string. Do not send out response. 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 - var buf bytes.Buffer - if c.Layout != "" { - if c.TplName == "" { - c.TplName = strings.ToLower(c.controllerName) + "/" + strings.ToLower(c.actionName) + "." + c.TplExt - } - - if BConfig.RunMode == DEV { - buildFiles := []string{c.TplName} - if c.LayoutSections != nil { - for _, sectionTpl := range c.LayoutSections { - if sectionTpl == "" { - continue - } - buildFiles = append(buildFiles, sectionTpl) - } - } - BuildTemplate(BConfig.WebConfig.ViewsPath, buildFiles...) - } - if _, ok := BeeTemplates[c.TplName]; !ok { - panic("can't find templatefile in the path:" + c.TplName) - } - err := BeeTemplates[c.TplName].ExecuteTemplate(&buf, c.TplName, c.Data) - if err != nil { - Trace("template Execute err:", err) - return nil, err - } + buf, err := c.renderTemplate() + //if the controller has set layout, then first get the tplName's content set the content to the layout + if err == nil && c.Layout != "" { c.Data["LayoutContent"] = template.HTML(buf.String()) if c.LayoutSections != nil { @@ -232,11 +207,9 @@ func (c *Controller) RenderBytes() ([]byte, error) { c.Data[sectionName] = "" continue } - buf.Reset() - err = BeeTemplates[sectionTpl].ExecuteTemplate(&buf, sectionTpl, c.Data) + err = executeTemplate(&buf, sectionTpl, c.Data) if err != nil { - Trace("template Execute err:", err) return nil, err } c.Data[sectionName] = template.HTML(buf.String()) @@ -244,30 +217,32 @@ func (c *Controller) RenderBytes() ([]byte, error) { } buf.Reset() - err = BeeTemplates[c.Layout].ExecuteTemplate(&buf, c.Layout, c.Data) - if err != nil { - Trace("template Execute err:", err) - return nil, err - } - return buf.Bytes(), nil + executeTemplate(&buf, c.Layout, c.Data) } + return buf.Bytes(), err +} +func (c *Controller) renderTemplate() (bytes.Buffer, error) { + var buf bytes.Buffer if c.TplName == "" { c.TplName = strings.ToLower(c.controllerName) + "/" + strings.ToLower(c.actionName) + "." + c.TplExt } if BConfig.RunMode == DEV { - BuildTemplate(BConfig.WebConfig.ViewsPath, c.TplName) + buildFiles := []string{c.TplName} + if c.Layout != "" { + buildFiles = append(buildFiles, c.Layout) + if c.LayoutSections != nil { + for _, sectionTpl := range c.LayoutSections { + if sectionTpl == "" { + continue + } + buildFiles = append(buildFiles, sectionTpl) + } + } + } + BuildTemplate(BConfig.WebConfig.ViewsPath, buildFiles...) } - if _, ok := BeeTemplates[c.TplName]; !ok { - panic("can't find templatefile in the path:" + c.TplName) - } - buf.Reset() - err := BeeTemplates[c.TplName].ExecuteTemplate(&buf, c.TplName, c.Data) - if err != nil { - Trace("template Execute err:", err) - return nil, err - } - return buf.Bytes(), nil + return buf, executeTemplate(&buf, c.TplName, c.Data) } // Redirect sends the redirection response to url with status code. @@ -287,6 +262,7 @@ func (c *Controller) Abort(code string) { // CustomAbort stops controller handler and show the error data, it's similar Aborts, but support status code and body. func (c *Controller) CustomAbort(status int, body string) { c.Ctx.ResponseWriter.WriteHeader(status) + //c.Ctx.Output.Status = status // first panic from ErrorMaps, is is user defined error functions. if _, ok := ErrorMaps[body]; ok { panic(body) diff --git a/vendor/github.com/astaxie/beego/error.go b/vendor/github.com/astaxie/beego/error.go index 94151dd8b..4f48fab21 100644 --- a/vendor/github.com/astaxie/beego/error.go +++ b/vendor/github.com/astaxie/beego/error.go @@ -424,6 +424,7 @@ func exception(errCode string, ctx *context.Context) { func executeError(err *errorInfo, ctx *context.Context, code int) { if err.errorType == errorTypeHandler { + ctx.ResponseWriter.WriteHeader(code) err.handler(ctx.ResponseWriter, ctx.Request) return } diff --git a/vendor/github.com/astaxie/beego/grace/server.go b/vendor/github.com/astaxie/beego/grace/server.go index f4512ded5..101bda56d 100644 --- a/vendor/github.com/astaxie/beego/grace/server.go +++ b/vendor/github.com/astaxie/beego/grace/server.go @@ -90,16 +90,15 @@ func (srv *Server) ListenAndServeTLS(certFile, keyFile string) (err error) { addr = ":https" } - config := &tls.Config{} - if srv.TLSConfig != nil { - *config = *srv.TLSConfig + if srv.TLSConfig == nil { + srv.TLSConfig = &tls.Config{} } - if config.NextProtos == nil { - config.NextProtos = []string{"http/1.1"} + if srv.TLSConfig.NextProtos == nil { + srv.TLSConfig.NextProtos = []string{"http/1.1"} } - config.Certificates = make([]tls.Certificate, 1) - config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile) + srv.TLSConfig.Certificates = make([]tls.Certificate, 1) + srv.TLSConfig.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile) if err != nil { return } @@ -113,7 +112,7 @@ func (srv *Server) ListenAndServeTLS(certFile, keyFile string) (err error) { } srv.tlsInnerListener = newGraceListener(l, srv) - srv.GraceListener = tls.NewListener(srv.tlsInnerListener, config) + srv.GraceListener = tls.NewListener(srv.tlsInnerListener, srv.TLSConfig) if srv.isChild { process, err := os.FindProcess(os.Getppid()) diff --git a/vendor/github.com/astaxie/beego/hooks.go b/vendor/github.com/astaxie/beego/hooks.go index 78abf8ef9..59b10b32f 100644 --- a/vendor/github.com/astaxie/beego/hooks.go +++ b/vendor/github.com/astaxie/beego/hooks.go @@ -68,13 +68,11 @@ func registerSession() error { } func registerTemplate() error { - if BConfig.WebConfig.AutoRender { - if err := BuildTemplate(BConfig.WebConfig.ViewsPath); err != nil { - if BConfig.RunMode == DEV { - Warn(err) - } - return err + if err := BuildTemplate(BConfig.WebConfig.ViewsPath); err != nil { + if BConfig.RunMode == DEV { + Warn(err) } + return err } return nil } diff --git a/vendor/github.com/astaxie/beego/httplib/README.md b/vendor/github.com/astaxie/beego/httplib/README.md deleted file mode 100644 index 6a72cf7cf..000000000 --- a/vendor/github.com/astaxie/beego/httplib/README.md +++ /dev/null @@ -1,97 +0,0 @@ -# httplib -httplib is an libs help you to curl remote url. - -# How to use? - -## GET -you can use Get to crawl data. - - import "github.com/astaxie/beego/httplib" - - str, err := httplib.Get("http://beego.me/").String() - if err != nil { - // error - } - fmt.Println(str) - -## POST -POST data to remote url - - req := httplib.Post("http://beego.me/") - req.Param("username","astaxie") - req.Param("password","123456") - str, err := req.String() - if err != nil { - // error - } - fmt.Println(str) - -## Set timeout - -The default timeout is `60` seconds, function prototype: - - SetTimeout(connectTimeout, readWriteTimeout time.Duration) - -Exmaple: - - // GET - httplib.Get("http://beego.me/").SetTimeout(100 * time.Second, 30 * time.Second) - - // POST - httplib.Post("http://beego.me/").SetTimeout(100 * time.Second, 30 * time.Second) - - -## Debug - -If you want to debug the request info, set the debug on - - httplib.Get("http://beego.me/").Debug(true) - -## Set HTTP Basic Auth - - str, err := Get("http://beego.me/").SetBasicAuth("user", "passwd").String() - if err != nil { - // error - } - fmt.Println(str) - -## Set HTTPS - -If request url is https, You can set the client support TSL: - - httplib.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true}) - -More info about the `tls.Config` please visit http://golang.org/pkg/crypto/tls/#Config - -## Set HTTP Version - -some servers need to specify the protocol version of HTTP - - httplib.Get("http://beego.me/").SetProtocolVersion("HTTP/1.1") - -## Set Cookie - -some http request need setcookie. So set it like this: - - cookie := &http.Cookie{} - cookie.Name = "username" - cookie.Value = "astaxie" - httplib.Get("http://beego.me/").SetCookie(cookie) - -## Upload file - -httplib support mutil file upload, use `req.PostFile()` - - req := httplib.Post("http://beego.me/") - req.Param("username","astaxie") - req.PostFile("uploadfile1", "httplib.pdf") - str, err := req.String() - if err != nil { - // error - } - fmt.Println(str) - - -See godoc for further documentation and examples. - -* [godoc.org/github.com/astaxie/beego/httplib](https://godoc.org/github.com/astaxie/beego/httplib) diff --git a/vendor/github.com/astaxie/beego/httplib/httplib.go b/vendor/github.com/astaxie/beego/httplib/httplib.go deleted file mode 100644 index fb64a30a8..000000000 --- a/vendor/github.com/astaxie/beego/httplib/httplib.go +++ /dev/null @@ -1,552 +0,0 @@ -// 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 httplib is used as http.Client -// Usage: -// -// import "github.com/astaxie/beego/httplib" -// -// b := httplib.Post("http://beego.me/") -// b.Param("username","astaxie") -// b.Param("password","123456") -// b.PostFile("uploadfile1", "httplib.pdf") -// b.PostFile("uploadfile2", "httplib.txt") -// str, err := b.String() -// if err != nil { -// t.Fatal(err) -// } -// fmt.Println(str) -// -// more docs http://beego.me/docs/module/httplib.md -package httplib - -import ( - "bytes" - "compress/gzip" - "crypto/tls" - "encoding/json" - "encoding/xml" - "io" - "io/ioutil" - "log" - "mime/multipart" - "net" - "net/http" - "net/http/cookiejar" - "net/http/httputil" - "net/url" - "os" - "strings" - "sync" - "time" -) - -var defaultSetting = BeegoHTTPSettings{ - UserAgent: "beegoServer", - ConnectTimeout: 60 * time.Second, - ReadWriteTimeout: 60 * time.Second, - Gzip: true, - DumpBody: true, -} - -var defaultCookieJar http.CookieJar -var settingMutex sync.Mutex - -// createDefaultCookie creates a global cookiejar to store cookies. -func createDefaultCookie() { - settingMutex.Lock() - defer settingMutex.Unlock() - defaultCookieJar, _ = cookiejar.New(nil) -} - -// SetDefaultSetting Overwrite default settings -func SetDefaultSetting(setting BeegoHTTPSettings) { - settingMutex.Lock() - defer settingMutex.Unlock() - defaultSetting = setting -} - -// NewBeegoRequest return *BeegoHttpRequest with specific method -func NewBeegoRequest(rawurl, method string) *BeegoHTTPRequest { - var resp http.Response - u, err := url.Parse(rawurl) - if err != nil { - log.Println("Httplib:", err) - } - req := http.Request{ - URL: u, - Method: method, - Header: make(http.Header), - Proto: "HTTP/1.1", - ProtoMajor: 1, - ProtoMinor: 1, - } - return &BeegoHTTPRequest{ - url: rawurl, - req: &req, - params: map[string][]string{}, - files: map[string]string{}, - setting: defaultSetting, - resp: &resp, - } -} - -// Get returns *BeegoHttpRequest with GET method. -func Get(url string) *BeegoHTTPRequest { - return NewBeegoRequest(url, "GET") -} - -// Post returns *BeegoHttpRequest with POST method. -func Post(url string) *BeegoHTTPRequest { - return NewBeegoRequest(url, "POST") -} - -// Put returns *BeegoHttpRequest with PUT method. -func Put(url string) *BeegoHTTPRequest { - return NewBeegoRequest(url, "PUT") -} - -// Delete returns *BeegoHttpRequest DELETE method. -func Delete(url string) *BeegoHTTPRequest { - return NewBeegoRequest(url, "DELETE") -} - -// Head returns *BeegoHttpRequest with HEAD method. -func Head(url string) *BeegoHTTPRequest { - return NewBeegoRequest(url, "HEAD") -} - -// BeegoHTTPSettings is the http.Client setting -type BeegoHTTPSettings struct { - ShowDebug bool - UserAgent string - ConnectTimeout time.Duration - ReadWriteTimeout time.Duration - TLSClientConfig *tls.Config - Proxy func(*http.Request) (*url.URL, error) - Transport http.RoundTripper - EnableCookie bool - Gzip bool - DumpBody bool -} - -// BeegoHTTPRequest provides more useful methods for requesting one url than http.Request. -type BeegoHTTPRequest struct { - url string - req *http.Request - params map[string][]string - files map[string]string - setting BeegoHTTPSettings - resp *http.Response - body []byte - dump []byte -} - -// GetRequest return the request object -func (b *BeegoHTTPRequest) GetRequest() *http.Request { - return b.req -} - -// Setting Change request settings -func (b *BeegoHTTPRequest) Setting(setting BeegoHTTPSettings) *BeegoHTTPRequest { - b.setting = setting - return b -} - -// SetBasicAuth sets the request's Authorization header to use HTTP Basic Authentication with the provided username and password. -func (b *BeegoHTTPRequest) SetBasicAuth(username, password string) *BeegoHTTPRequest { - b.req.SetBasicAuth(username, password) - return b -} - -// SetEnableCookie sets enable/disable cookiejar -func (b *BeegoHTTPRequest) SetEnableCookie(enable bool) *BeegoHTTPRequest { - b.setting.EnableCookie = enable - return b -} - -// SetUserAgent sets User-Agent header field -func (b *BeegoHTTPRequest) SetUserAgent(useragent string) *BeegoHTTPRequest { - b.setting.UserAgent = useragent - return b -} - -// Debug sets show debug or not when executing request. -func (b *BeegoHTTPRequest) Debug(isdebug bool) *BeegoHTTPRequest { - b.setting.ShowDebug = isdebug - return b -} - -// DumpBody setting whether need to Dump the Body. -func (b *BeegoHTTPRequest) DumpBody(isdump bool) *BeegoHTTPRequest { - b.setting.DumpBody = isdump - return b -} - -// DumpRequest return the DumpRequest -func (b *BeegoHTTPRequest) DumpRequest() []byte { - return b.dump -} - -// SetTimeout sets connect time out and read-write time out for BeegoRequest. -func (b *BeegoHTTPRequest) SetTimeout(connectTimeout, readWriteTimeout time.Duration) *BeegoHTTPRequest { - b.setting.ConnectTimeout = connectTimeout - b.setting.ReadWriteTimeout = readWriteTimeout - return b -} - -// SetTLSClientConfig sets tls connection configurations if visiting https url. -func (b *BeegoHTTPRequest) SetTLSClientConfig(config *tls.Config) *BeegoHTTPRequest { - b.setting.TLSClientConfig = config - return b -} - -// Header add header item string in request. -func (b *BeegoHTTPRequest) Header(key, value string) *BeegoHTTPRequest { - b.req.Header.Set(key, value) - return b -} - -// SetHost set the request host -func (b *BeegoHTTPRequest) SetHost(host string) *BeegoHTTPRequest { - b.req.Host = host - return b -} - -// SetProtocolVersion Set the protocol version for incoming requests. -// Client requests always use HTTP/1.1. -func (b *BeegoHTTPRequest) SetProtocolVersion(vers string) *BeegoHTTPRequest { - if len(vers) == 0 { - vers = "HTTP/1.1" - } - - major, minor, ok := http.ParseHTTPVersion(vers) - if ok { - b.req.Proto = vers - b.req.ProtoMajor = major - b.req.ProtoMinor = minor - } - - return b -} - -// SetCookie add cookie into request. -func (b *BeegoHTTPRequest) SetCookie(cookie *http.Cookie) *BeegoHTTPRequest { - b.req.Header.Add("Cookie", cookie.String()) - return b -} - -// SetTransport set the setting transport -func (b *BeegoHTTPRequest) SetTransport(transport http.RoundTripper) *BeegoHTTPRequest { - b.setting.Transport = transport - return b -} - -// SetProxy set the http proxy -// example: -// -// func(req *http.Request) (*url.URL, error) { -// u, _ := url.ParseRequestURI("http://127.0.0.1:8118") -// return u, nil -// } -func (b *BeegoHTTPRequest) SetProxy(proxy func(*http.Request) (*url.URL, error)) *BeegoHTTPRequest { - b.setting.Proxy = proxy - return b -} - -// Param adds query param in to request. -// params build query string as ?key1=value1&key2=value2... -func (b *BeegoHTTPRequest) Param(key, value string) *BeegoHTTPRequest { - if param, ok := b.params[key]; ok { - b.params[key] = append(param, value) - } else { - b.params[key] = []string{value} - } - return b -} - -// PostFile add a post file to the request -func (b *BeegoHTTPRequest) PostFile(formname, filename string) *BeegoHTTPRequest { - b.files[formname] = filename - return b -} - -// Body adds request raw body. -// it supports string and []byte. -func (b *BeegoHTTPRequest) Body(data interface{}) *BeegoHTTPRequest { - switch t := data.(type) { - case string: - bf := bytes.NewBufferString(t) - b.req.Body = ioutil.NopCloser(bf) - b.req.ContentLength = int64(len(t)) - case []byte: - bf := bytes.NewBuffer(t) - b.req.Body = ioutil.NopCloser(bf) - b.req.ContentLength = int64(len(t)) - } - return b -} - -// JSONBody adds request raw body encoding by JSON. -func (b *BeegoHTTPRequest) JSONBody(obj interface{}) (*BeegoHTTPRequest, error) { - if b.req.Body == nil && obj != nil { - buf := bytes.NewBuffer(nil) - enc := json.NewEncoder(buf) - if err := enc.Encode(obj); err != nil { - return b, err - } - b.req.Body = ioutil.NopCloser(buf) - b.req.ContentLength = int64(buf.Len()) - b.req.Header.Set("Content-Type", "application/json") - } - return b, nil -} - -func (b *BeegoHTTPRequest) buildURL(paramBody string) { - // build GET url with query string - if b.req.Method == "GET" && len(paramBody) > 0 { - if strings.Index(b.url, "?") != -1 { - b.url += "&" + paramBody - } else { - b.url = b.url + "?" + paramBody - } - return - } - - // build POST/PUT/PATCH url and body - if (b.req.Method == "POST" || b.req.Method == "PUT" || b.req.Method == "PATCH") && b.req.Body == nil { - // with files - if len(b.files) > 0 { - pr, pw := io.Pipe() - bodyWriter := multipart.NewWriter(pw) - go func() { - for formname, filename := range b.files { - fileWriter, err := bodyWriter.CreateFormFile(formname, filename) - if err != nil { - log.Println("Httplib:", err) - } - fh, err := os.Open(filename) - if err != nil { - log.Println("Httplib:", err) - } - //iocopy - _, err = io.Copy(fileWriter, fh) - fh.Close() - if err != nil { - log.Println("Httplib:", err) - } - } - for k, v := range b.params { - for _, vv := range v { - bodyWriter.WriteField(k, vv) - } - } - bodyWriter.Close() - pw.Close() - }() - b.Header("Content-Type", bodyWriter.FormDataContentType()) - b.req.Body = ioutil.NopCloser(pr) - return - } - - // with params - if len(paramBody) > 0 { - b.Header("Content-Type", "application/x-www-form-urlencoded") - b.Body(paramBody) - } - } -} - -func (b *BeegoHTTPRequest) getResponse() (*http.Response, error) { - if b.resp.StatusCode != 0 { - return b.resp, nil - } - resp, err := b.DoRequest() - if err != nil { - return nil, err - } - b.resp = resp - return resp, nil -} - -// DoRequest will do the client.Do -func (b *BeegoHTTPRequest) DoRequest() (*http.Response, error) { - var paramBody string - if len(b.params) > 0 { - var buf bytes.Buffer - for k, v := range b.params { - for _, vv := range v { - buf.WriteString(url.QueryEscape(k)) - buf.WriteByte('=') - buf.WriteString(url.QueryEscape(vv)) - buf.WriteByte('&') - } - } - paramBody = buf.String() - paramBody = paramBody[0 : len(paramBody)-1] - } - - b.buildURL(paramBody) - url, err := url.Parse(b.url) - if err != nil { - return nil, err - } - - b.req.URL = url - - trans := b.setting.Transport - - if trans == nil { - // create default transport - trans = &http.Transport{ - TLSClientConfig: b.setting.TLSClientConfig, - Proxy: b.setting.Proxy, - Dial: TimeoutDialer(b.setting.ConnectTimeout, b.setting.ReadWriteTimeout), - } - } else { - // if b.transport is *http.Transport then set the settings. - if t, ok := trans.(*http.Transport); ok { - if t.TLSClientConfig == nil { - t.TLSClientConfig = b.setting.TLSClientConfig - } - if t.Proxy == nil { - t.Proxy = b.setting.Proxy - } - if t.Dial == nil { - t.Dial = TimeoutDialer(b.setting.ConnectTimeout, b.setting.ReadWriteTimeout) - } - } - } - - var jar http.CookieJar - if b.setting.EnableCookie { - if defaultCookieJar == nil { - createDefaultCookie() - } - jar = defaultCookieJar - } - - client := &http.Client{ - Transport: trans, - Jar: jar, - } - - if b.setting.UserAgent != "" && b.req.Header.Get("User-Agent") == "" { - b.req.Header.Set("User-Agent", b.setting.UserAgent) - } - - if b.setting.ShowDebug { - dump, err := httputil.DumpRequest(b.req, b.setting.DumpBody) - if err != nil { - log.Println(err.Error()) - } - b.dump = dump - } - return client.Do(b.req) -} - -// String returns the body string in response. -// it calls Response inner. -func (b *BeegoHTTPRequest) String() (string, error) { - data, err := b.Bytes() - if err != nil { - return "", err - } - - return string(data), nil -} - -// Bytes returns the body []byte in response. -// it calls Response inner. -func (b *BeegoHTTPRequest) Bytes() ([]byte, error) { - if b.body != nil { - return b.body, nil - } - resp, err := b.getResponse() - if err != nil { - return nil, err - } - if resp.Body == nil { - return nil, nil - } - defer resp.Body.Close() - if b.setting.Gzip && resp.Header.Get("Content-Encoding") == "gzip" { - reader, err := gzip.NewReader(resp.Body) - if err != nil { - return nil, err - } - b.body, err = ioutil.ReadAll(reader) - } else { - b.body, err = ioutil.ReadAll(resp.Body) - } - return b.body, err -} - -// ToFile saves the body data in response to one file. -// it calls Response inner. -func (b *BeegoHTTPRequest) ToFile(filename string) error { - f, err := os.Create(filename) - if err != nil { - return err - } - defer f.Close() - - resp, err := b.getResponse() - if err != nil { - return err - } - if resp.Body == nil { - return nil - } - defer resp.Body.Close() - _, err = io.Copy(f, resp.Body) - return err -} - -// ToJSON returns the map that marshals from the body bytes as json in response . -// it calls Response inner. -func (b *BeegoHTTPRequest) ToJSON(v interface{}) error { - data, err := b.Bytes() - if err != nil { - return err - } - return json.Unmarshal(data, v) -} - -// ToXML returns the map that marshals from the body bytes as xml in response . -// it calls Response inner. -func (b *BeegoHTTPRequest) ToXML(v interface{}) error { - data, err := b.Bytes() - if err != nil { - return err - } - return xml.Unmarshal(data, v) -} - -// Response executes request client gets response mannually. -func (b *BeegoHTTPRequest) Response() (*http.Response, error) { - return b.getResponse() -} - -// TimeoutDialer returns functions of connection dialer with timeout settings for http.Transport Dial field. -func TimeoutDialer(cTimeout time.Duration, rwTimeout time.Duration) func(net, addr string) (c net.Conn, err error) { - return func(netw, addr string) (net.Conn, error) { - conn, err := net.DialTimeout(netw, addr, cTimeout) - if err != nil { - return nil, err - } - err = conn.SetDeadline(time.Now().Add(rwTimeout)) - return conn, err - } -} diff --git a/vendor/github.com/astaxie/beego/logs/conn.go b/vendor/github.com/astaxie/beego/logs/conn.go index 3655bf514..1db1a427c 100644 --- a/vendor/github.com/astaxie/beego/logs/conn.go +++ b/vendor/github.com/astaxie/beego/logs/conn.go @@ -17,14 +17,14 @@ package logs import ( "encoding/json" "io" - "log" "net" + "time" ) // connWriter implements LoggerInterface. // it writes messages in keep-live tcp connection. type connWriter struct { - lg *log.Logger + lg *logWriter innerWriter io.WriteCloser ReconnectOnMsg bool `json:"reconnectOnMsg"` Reconnect bool `json:"reconnect"` @@ -42,17 +42,17 @@ func NewConn() Logger { // Init init connection writer with json config. // json config only need key "level". -func (c *connWriter) Init(jsonconfig string) error { - return json.Unmarshal([]byte(jsonconfig), c) +func (c *connWriter) Init(jsonConfig string) error { + return json.Unmarshal([]byte(jsonConfig), c) } // WriteMsg write message in connection. // if connection is down, try to re-connect. -func (c *connWriter) WriteMsg(msg string, level int) error { +func (c *connWriter) WriteMsg(when time.Time, msg string, level int) error { if level > c.Level { return nil } - if c.neddedConnectOnMsg() { + if c.needToConnectOnMsg() { err := c.connect() if err != nil { return err @@ -62,7 +62,8 @@ func (c *connWriter) WriteMsg(msg string, level int) error { if c.ReconnectOnMsg { defer c.innerWriter.Close() } - c.lg.Println(msg) + + c.lg.println(when, msg) return nil } @@ -94,11 +95,11 @@ func (c *connWriter) connect() error { } c.innerWriter = conn - c.lg = log.New(conn, "", log.Ldate|log.Ltime) + c.lg = newLogWriter(conn) return nil } -func (c *connWriter) neddedConnectOnMsg() bool { +func (c *connWriter) needToConnectOnMsg() bool { if c.Reconnect { c.Reconnect = false return true diff --git a/vendor/github.com/astaxie/beego/logs/console.go b/vendor/github.com/astaxie/beego/logs/console.go index 23e8ebcaf..05d08a42e 100644 --- a/vendor/github.com/astaxie/beego/logs/console.go +++ b/vendor/github.com/astaxie/beego/logs/console.go @@ -16,9 +16,9 @@ package logs import ( "encoding/json" - "log" "os" "runtime" + "time" ) // brush is a color join function @@ -34,51 +34,55 @@ func newBrush(color string) brush { } var colors = []brush{ - newBrush("1;37"), // Emergency white - newBrush("1;36"), // Alert cyan - newBrush("1;35"), // Critical magenta - newBrush("1;31"), // Error red - newBrush("1;33"), // Warning yellow - newBrush("1;32"), // Notice green - newBrush("1;34"), // Informational blue - newBrush("1;34"), // Debug blue + newBrush("1;37"), // Emergency white + newBrush("1;36"), // Alert cyan + newBrush("1;35"), // Critical magenta + newBrush("1;31"), // Error red + newBrush("1;33"), // Warning yellow + newBrush("1;32"), // Notice green + newBrush("1;34"), // Informational blue + newBrush("1;34"), // Debug blue } // consoleWriter implements LoggerInterface and writes messages to terminal. type consoleWriter struct { - lg *log.Logger - Level int `json:"level"` + lg *logWriter + Level int `json:"level"` + Colorful bool `json:"color"` //this filed is useful only when system's terminal supports color } // NewConsole create ConsoleWriter returning as LoggerInterface. func NewConsole() Logger { cw := &consoleWriter{ - lg: log.New(os.Stdout, "", log.Ldate|log.Ltime), - Level: LevelDebug, + lg: newLogWriter(os.Stdout), + Level: LevelDebug, + Colorful: true, } return cw } // Init init console logger. -// jsonconfig like '{"level":LevelTrace}'. -func (c *consoleWriter) Init(jsonconfig string) error { - if len(jsonconfig) == 0 { +// jsonConfig like '{"level":LevelTrace}'. +func (c *consoleWriter) Init(jsonConfig string) error { + if len(jsonConfig) == 0 { return nil } - return json.Unmarshal([]byte(jsonconfig), c) + err := json.Unmarshal([]byte(jsonConfig), c) + if runtime.GOOS == "windows" { + c.Colorful = false + } + return err } // WriteMsg write message in console. -func (c *consoleWriter) WriteMsg(msg string, level int) error { +func (c *consoleWriter) WriteMsg(when time.Time, msg string, level int) error { if level > c.Level { return nil } - if goos := runtime.GOOS; goos == "windows" { - c.lg.Println(msg) - return nil + if c.Colorful { + msg = colors[level](msg) } - c.lg.Println(colors[level](msg)) - + c.lg.println(when, msg) return nil } diff --git a/vendor/github.com/astaxie/beego/logs/es/es.go b/vendor/github.com/astaxie/beego/logs/es/es.go deleted file mode 100644 index f8dc5f65b..000000000 --- a/vendor/github.com/astaxie/beego/logs/es/es.go +++ /dev/null @@ -1,80 +0,0 @@ -package es - -import ( - "encoding/json" - "errors" - "fmt" - "net" - "net/url" - "time" - - "github.com/astaxie/beego/logs" - "github.com/belogik/goes" -) - -// NewES return a LoggerInterface -func NewES() logs.Logger { - cw := &esLogger{ - Level: logs.LevelDebug, - } - return cw -} - -type esLogger struct { - *goes.Connection - DSN string `json:"dsn"` - Level int `json:"level"` -} - -// {"dsn":"http://localhost:9200/","level":1} -func (el *esLogger) Init(jsonconfig string) error { - err := json.Unmarshal([]byte(jsonconfig), el) - if err != nil { - return err - } - if el.DSN == "" { - return errors.New("empty dsn") - } else if u, err := url.Parse(el.DSN); err != nil { - return err - } else if u.Path == "" { - return errors.New("missing prefix") - } else if host, port, err := net.SplitHostPort(u.Host); err != nil { - return err - } else { - conn := goes.NewConnection(host, port) - el.Connection = conn - } - return nil -} - -// WriteMsg will write the msg and level into es -func (el *esLogger) WriteMsg(msg string, level int) error { - if level > el.Level { - return nil - } - t := time.Now() - vals := make(map[string]interface{}) - vals["@timestamp"] = t.Format(time.RFC3339) - vals["@msg"] = msg - d := goes.Document{ - Index: fmt.Sprintf("%04d.%02d.%02d", t.Year(), t.Month(), t.Day()), - Type: "logs", - Fields: vals, - } - _, err := el.Index(d, nil) - return err -} - -// Destroy is a empty method -func (el *esLogger) Destroy() { - -} - -// Flush is a empty method -func (el *esLogger) Flush() { - -} - -func init() { - logs.Register("es", NewES) -} diff --git a/vendor/github.com/astaxie/beego/logs/file.go b/vendor/github.com/astaxie/beego/logs/file.go index 0eae734a0..9d3f78a05 100644 --- a/vendor/github.com/astaxie/beego/logs/file.go +++ b/vendor/github.com/astaxie/beego/logs/file.go @@ -53,9 +53,11 @@ type fileLogWriter struct { Level int `json:"level"` Perm os.FileMode `json:"perm"` + + fileNameOnly, suffix string // like "project.log", project is fileNameOnly and .log is suffix } -// NewFileWriter create a FileLogWriter returning as LoggerInterface. +// newFileWriter create a FileLogWriter returning as LoggerInterface. func newFileWriter() Logger { w := &fileLogWriter{ Filename: "", @@ -89,6 +91,11 @@ func (w *fileLogWriter) Init(jsonConfig string) error { if len(w.Filename) == 0 { return errors.New("jsonconfig must have filename") } + w.suffix = filepath.Ext(w.Filename) + w.fileNameOnly = strings.TrimSuffix(w.Filename, w.suffix) + if w.suffix == "" { + w.suffix = ".log" + } err = w.startLogger() return err } @@ -114,59 +121,19 @@ func (w *fileLogWriter) needRotate(size int, day int) bool { } // WriteMsg write logger message into file. -func (w *fileLogWriter) WriteMsg(msg string, level int) error { +func (w *fileLogWriter) WriteMsg(when time.Time, msg string, level int) error { if level > w.Level { return nil } - //2016/01/12 21:34:33 - now := time.Now() - y, mo, d := now.Date() - h, mi, s := now.Clock() - //len(2006/01/02 15:03:04)==19 - var buf [20]byte - t := 3 - for y >= 10 { - p := y / 10 - buf[t] = byte('0' + y - p*10) - y = p - t-- - } - buf[0] = byte('0' + y) - buf[4] = '/' - if mo > 9 { - buf[5] = '1' - buf[6] = byte('0' + mo - 9) - } else { - buf[5] = '0' - buf[6] = byte('0' + mo) - } - buf[7] = '/' - t = d / 10 - buf[8] = byte('0' + t) - buf[9] = byte('0' + d - t*10) - buf[10] = ' ' - t = h / 10 - buf[11] = byte('0' + t) - buf[12] = byte('0' + h - t*10) - buf[13] = ':' - t = mi / 10 - buf[14] = byte('0' + t) - buf[15] = byte('0' + mi - t*10) - buf[16] = ':' - t = s / 10 - buf[17] = byte('0' + t) - buf[18] = byte('0' + s - t*10) - buf[19] = ' ' - msg = string(buf[0:]) + msg + "\n" - + h, d := formatTimeHeader(when) + msg = string(h) + msg + "\n" if w.Rotate { if w.needRotate(len(msg), d) { w.Lock() if w.needRotate(len(msg), d) { - if err := w.doRotate(); err != nil { + if err := w.doRotate(when); err != nil { fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.Filename, err) } - } w.Unlock() } @@ -235,8 +202,8 @@ func (w *fileLogWriter) lines() (int, error) { } // DoRotate means it need to write file in new file. -// new file name like xx.2013-01-01.2.log -func (w *fileLogWriter) doRotate() error { +// new file name like xx.2013-01-01.log (daily) or xx.001.log (by line or size) +func (w *fileLogWriter) doRotate(logTime time.Time) error { _, err := os.Lstat(w.Filename) if err != nil { return err @@ -245,13 +212,13 @@ func (w *fileLogWriter) doRotate() error { // Find the next available number num := 1 fName := "" - suffix := filepath.Ext(w.Filename) - filenameOnly := strings.TrimSuffix(w.Filename, suffix) - if suffix == "" { - suffix = ".log" - } - for ; err == nil && num <= 999; num++ { - fName = filenameOnly + fmt.Sprintf(".%s.%03d%s", time.Now().Format("2006-01-02"), num, suffix) + if w.MaxLines > 0 || w.MaxSize > 0 { + for ; err == nil && num <= 999; num++ { + fName = w.fileNameOnly + fmt.Sprintf(".%s.%03d%s", logTime.Format("2006-01-02"), num, w.suffix) + _, err = os.Lstat(fName) + } + } else { + fName = fmt.Sprintf("%s.%s%s", w.fileNameOnly, logTime.Format("2006-01-02"), w.suffix) _, err = os.Lstat(fName) } // return error if the last file checked still existed @@ -289,7 +256,8 @@ func (w *fileLogWriter) deleteOldLog() { }() if !info.IsDir() && info.ModTime().Unix() < (time.Now().Unix()-60*60*24*w.MaxDays) { - if strings.HasPrefix(filepath.Base(path), filepath.Base(w.Filename)) { + if strings.HasPrefix(filepath.Base(path), w.fileNameOnly) && + strings.HasSuffix(filepath.Base(path), w.suffix) { os.Remove(path) } } diff --git a/vendor/github.com/astaxie/beego/logs/log.go b/vendor/github.com/astaxie/beego/logs/log.go index ccaaa3ad7..3b3e22081 100644 --- a/vendor/github.com/astaxie/beego/logs/log.go +++ b/vendor/github.com/astaxie/beego/logs/log.go @@ -40,6 +40,7 @@ import ( "runtime" "strconv" "sync" + "time" ) // RFC5424 log message levels. @@ -68,7 +69,7 @@ type loggerType func() Logger // Logger defines the behavior of a log provider. type Logger interface { Init(config string) error - WriteMsg(msg string, level int) error + WriteMsg(when time.Time, msg string, level int) error Destroy() Flush() } @@ -97,6 +98,8 @@ type BeeLogger struct { loggerFuncCallDepth int asynchronous bool msgChan chan *logMsg + signalChan chan string + wg sync.WaitGroup outputs []*nameLogger } @@ -108,6 +111,7 @@ type nameLogger struct { type logMsg struct { level int msg string + when time.Time } var logMsgPool *sync.Pool @@ -120,6 +124,7 @@ func NewLogger(channelLen int64) *BeeLogger { bl.level = LevelDebug bl.loggerFuncCallDepth = 2 bl.msgChan = make(chan *logMsg, channelLen) + bl.signalChan = make(chan string, 1) return bl } @@ -131,6 +136,7 @@ func (bl *BeeLogger) Async() *BeeLogger { return &logMsg{} }, } + bl.wg.Add(1) go bl.startLogger() return bl } @@ -140,17 +146,25 @@ func (bl *BeeLogger) Async() *BeeLogger { func (bl *BeeLogger) SetLogger(adapterName string, config string) error { bl.lock.Lock() defer bl.lock.Unlock() - if log, ok := adapters[adapterName]; ok { - lg := log() - err := lg.Init(config) - if err != nil { - fmt.Fprintln(os.Stderr, "logs.BeeLogger.SetLogger: "+err.Error()) - return err + + for _, l := range bl.outputs { + if l.name == adapterName { + return fmt.Errorf("logs: duplicate adaptername %q (you have set this logger before)", adapterName) } - bl.outputs = append(bl.outputs, &nameLogger{name: adapterName, Logger: lg}) - } else { + } + + log, ok := adapters[adapterName] + if !ok { return fmt.Errorf("logs: unknown adaptername %q (forgotten Register?)", adapterName) } + + lg := log() + err := lg.Init(config) + if err != nil { + fmt.Fprintln(os.Stderr, "logs.BeeLogger.SetLogger: "+err.Error()) + return err + } + bl.outputs = append(bl.outputs, &nameLogger{name: adapterName, Logger: lg}) return nil } @@ -173,9 +187,9 @@ func (bl *BeeLogger) DelLogger(adapterName string) error { return nil } -func (bl *BeeLogger) writeToLoggers(msg string, level int) { +func (bl *BeeLogger) writeToLoggers(when time.Time, msg string, level int) { for _, l := range bl.outputs { - err := l.WriteMsg(msg, level) + err := l.WriteMsg(when, msg, level) if err != nil { fmt.Fprintf(os.Stderr, "unable to WriteMsg to adapter:%v,error:%v\n", l.name, err) } @@ -183,6 +197,7 @@ func (bl *BeeLogger) writeToLoggers(msg string, level int) { } func (bl *BeeLogger) writeMsg(logLevel int, msg string) error { + when := time.Now() if bl.enableFuncCallDepth { _, file, line, ok := runtime.Caller(bl.loggerFuncCallDepth) if !ok { @@ -196,9 +211,10 @@ func (bl *BeeLogger) writeMsg(logLevel int, msg string) error { lm := logMsgPool.Get().(*logMsg) lm.level = logLevel lm.msg = msg + lm.when = when bl.msgChan <- lm } else { - bl.writeToLoggers(msg, logLevel) + bl.writeToLoggers(when, msg, logLevel) } return nil } @@ -228,11 +244,26 @@ func (bl *BeeLogger) EnableFuncCallDepth(b bool) { // start logger chan reading. // when chan is not empty, write logs. func (bl *BeeLogger) startLogger() { + gameOver := false for { select { case bm := <-bl.msgChan: - bl.writeToLoggers(bm.msg, bm.level) + bl.writeToLoggers(bm.when, bm.msg, bm.level) logMsgPool.Put(bm) + case sg := <-bl.signalChan: + // Now should only send "flush" or "close" to bl.signalChan + bl.flush() + if sg == "close" { + for _, l := range bl.outputs { + l.Destroy() + } + bl.outputs = nil + gameOver = true + } + bl.wg.Done() + } + if gameOver { + break } } } @@ -341,17 +372,45 @@ func (bl *BeeLogger) Trace(format string, v ...interface{}) { // Flush flush all chan data. func (bl *BeeLogger) Flush() { - for _, l := range bl.outputs { - l.Flush() + if bl.asynchronous { + bl.signalChan <- "flush" + bl.wg.Wait() + bl.wg.Add(1) + return } + bl.flush() } // Close close logger, flush all chan data and destroy all adapters in BeeLogger. func (bl *BeeLogger) Close() { + if bl.asynchronous { + bl.signalChan <- "close" + bl.wg.Wait() + } else { + bl.flush() + for _, l := range bl.outputs { + l.Destroy() + } + bl.outputs = nil + } + close(bl.msgChan) + close(bl.signalChan) +} + +// Reset close all outputs, and set bl.outputs to nil +func (bl *BeeLogger) Reset() { + bl.Flush() + for _, l := range bl.outputs { + l.Destroy() + } + bl.outputs = nil +} + +func (bl *BeeLogger) flush() { for { if len(bl.msgChan) > 0 { bm := <-bl.msgChan - bl.writeToLoggers(bm.msg, bm.level) + bl.writeToLoggers(bm.when, bm.msg, bm.level) logMsgPool.Put(bm) continue } @@ -359,6 +418,5 @@ func (bl *BeeLogger) Close() { } for _, l := range bl.outputs { l.Flush() - l.Destroy() } } diff --git a/vendor/github.com/astaxie/beego/logs/logger.go b/vendor/github.com/astaxie/beego/logs/logger.go new file mode 100644 index 000000000..323c41c56 --- /dev/null +++ b/vendor/github.com/astaxie/beego/logs/logger.go @@ -0,0 +1,80 @@ +// 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 logs + +import ( + "io" + "sync" + "time" +) + +type logWriter struct { + sync.Mutex + writer io.Writer +} + +func newLogWriter(wr io.Writer) *logWriter { + return &logWriter{writer: wr} +} + +func (lg *logWriter) println(when time.Time, msg string) { + lg.Lock() + h, _ := formatTimeHeader(when) + lg.writer.Write(append(append(h, msg...), '\n')) + lg.Unlock() +} + +func formatTimeHeader(when time.Time) ([]byte, int) { + y, mo, d := when.Date() + h, mi, s := when.Clock() + //len(2006/01/02 15:03:04)==19 + var buf [20]byte + t := 3 + for y >= 10 { + p := y / 10 + buf[t] = byte('0' + y - p*10) + y = p + t-- + } + buf[0] = byte('0' + y) + buf[4] = '/' + if mo > 9 { + buf[5] = '1' + buf[6] = byte('0' + mo - 9) + } else { + buf[5] = '0' + buf[6] = byte('0' + mo) + } + buf[7] = '/' + t = d / 10 + buf[8] = byte('0' + t) + buf[9] = byte('0' + d - t*10) + buf[10] = ' ' + t = h / 10 + buf[11] = byte('0' + t) + buf[12] = byte('0' + h - t*10) + buf[13] = ':' + t = mi / 10 + buf[14] = byte('0' + t) + buf[15] = byte('0' + mi - t*10) + buf[16] = ':' + t = s / 10 + buf[17] = byte('0' + t) + buf[18] = byte('0' + s - t*10) + buf[19] = ' ' + + return buf[0:], d +} diff --git a/vendor/github.com/astaxie/beego/logs/multifile.go b/vendor/github.com/astaxie/beego/logs/multifile.go new file mode 100644 index 000000000..b82ba2741 --- /dev/null +++ b/vendor/github.com/astaxie/beego/logs/multifile.go @@ -0,0 +1,116 @@ +// 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 logs + +import ( + "encoding/json" + "time" +) + +// A filesLogWriter manages several fileLogWriter +// filesLogWriter will write logs to the file in json configuration and write the same level log to correspond file +// means if the file name in configuration is project.log filesLogWriter will create project.error.log/project.debug.log +// and write the error-level logs to project.error.log and write the debug-level logs to project.debug.log +// the rotate attribute also acts like fileLogWriter +type multiFileLogWriter struct { + writers [LevelDebug + 1 + 1]*fileLogWriter // the last one for fullLogWriter + fullLogWriter *fileLogWriter + Separate []string `json:"separate"` +} + +var levelNames = [...]string{"emergency", "alert", "critical", "error", "warning", "notice", "info", "debug"} + +// Init file logger with json config. +// jsonConfig like: +// { +// "filename":"logs/beego.log", +// "maxLines":0, +// "maxsize":0, +// "daily":true, +// "maxDays":15, +// "rotate":true, +// "perm":0600, +// "separate":["emergency", "alert", "critical", "error", "warning", "notice", "info", "debug"], +// } + +func (f *multiFileLogWriter) Init(config string) error { + writer := newFileWriter().(*fileLogWriter) + err := writer.Init(config) + if err != nil { + return err + } + f.fullLogWriter = writer + f.writers[LevelDebug+1] = writer + + //unmarshal "separate" field to f.Separate + json.Unmarshal([]byte(config), f) + + jsonMap := map[string]interface{}{} + json.Unmarshal([]byte(config), &jsonMap) + + for i := LevelEmergency; i < LevelDebug+1; i++ { + for _, v := range f.Separate { + if v == levelNames[i] { + jsonMap["filename"] = f.fullLogWriter.fileNameOnly + "." + levelNames[i] + f.fullLogWriter.suffix + jsonMap["level"] = i + bs, _ := json.Marshal(jsonMap) + writer = newFileWriter().(*fileLogWriter) + writer.Init(string(bs)) + f.writers[i] = writer + } + } + } + + return nil +} + +func (f *multiFileLogWriter) Destroy() { + for i := 0; i < len(f.writers); i++ { + if f.writers[i] != nil { + f.writers[i].Destroy() + } + } +} + +func (f *multiFileLogWriter) WriteMsg(when time.Time, msg string, level int) error { + if f.fullLogWriter != nil { + f.fullLogWriter.WriteMsg(when, msg, level) + } + for i := 0; i < len(f.writers)-1; i++ { + if f.writers[i] != nil { + if level == f.writers[i].Level { + f.writers[i].WriteMsg(when, msg, level) + } + } + } + return nil +} + +func (f *multiFileLogWriter) Flush() { + for i := 0; i < len(f.writers); i++ { + if f.writers[i] != nil { + f.writers[i].Flush() + } + } +} + +// newFilesWriter create a FileLogWriter returning as LoggerInterface. +func newFilesWriter() Logger { + return &multiFileLogWriter{} +} + +func init() { + Register("multifile", newFilesWriter) +} diff --git a/vendor/github.com/astaxie/beego/logs/smtp.go b/vendor/github.com/astaxie/beego/logs/smtp.go index 748462f9d..47f5a0c69 100644 --- a/vendor/github.com/astaxie/beego/logs/smtp.go +++ b/vendor/github.com/astaxie/beego/logs/smtp.go @@ -126,7 +126,7 @@ func (s *SMTPWriter) sendMail(hostAddressWithPort string, auth smtp.Auth, fromAd // WriteMsg write message in smtp writer. // it will send an email with subject and only this message. -func (s *SMTPWriter) WriteMsg(msg string, level int) error { +func (s *SMTPWriter) WriteMsg(when time.Time, msg string, level int) error { if level > s.Level { return nil } @@ -140,7 +140,7 @@ func (s *SMTPWriter) WriteMsg(msg string, level int) error { // and send the email all in one step. contentType := "Content-Type: text/plain" + "; charset=UTF-8" mailmsg := []byte("To: " + strings.Join(s.RecipientAddresses, ";") + "\r\nFrom: " + s.FromAddress + "<" + s.FromAddress + - ">\r\nSubject: " + s.Subject + "\r\n" + contentType + "\r\n\r\n" + fmt.Sprintf(".%s", time.Now().Format("2006-01-02 15:04:05")) + msg) + ">\r\nSubject: " + s.Subject + "\r\n" + contentType + "\r\n\r\n" + fmt.Sprintf(".%s", when.Format("2006-01-02 15:04:05")) + msg) return s.sendMail(s.Host, auth, s.FromAddress, s.RecipientAddresses, mailmsg) } diff --git a/vendor/github.com/astaxie/beego/migration/ddl.go b/vendor/github.com/astaxie/beego/migration/ddl.go deleted file mode 100644 index 51243337f..000000000 --- a/vendor/github.com/astaxie/beego/migration/ddl.go +++ /dev/null @@ -1,53 +0,0 @@ -// 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 migration - -// Table store the tablename and Column -type Table struct { - TableName string - Columns []*Column -} - -// Create return the create sql -func (t *Table) Create() string { - return "" -} - -// Drop return the drop sql -func (t *Table) Drop() string { - return "" -} - -// Column define the columns name type and Default -type Column struct { - Name string - Type string - Default interface{} -} - -// Create return create sql with the provided tbname and columns -func Create(tbname string, columns ...Column) string { - return "" -} - -// Drop return the drop sql with the provided tbname and columns -func Drop(tbname string, columns ...Column) string { - return "" -} - -// TableDDL is still in think -func TableDDL(tbname string, columns ...Column) string { - return "" -} diff --git a/vendor/github.com/astaxie/beego/migration/migration.go b/vendor/github.com/astaxie/beego/migration/migration.go deleted file mode 100644 index 1591bc50d..000000000 --- a/vendor/github.com/astaxie/beego/migration/migration.go +++ /dev/null @@ -1,278 +0,0 @@ -// 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 migration is used for migration -// -// The table structure is as follow: -// -// CREATE TABLE `migrations` ( -// `id_migration` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'surrogate key', -// `name` varchar(255) DEFAULT NULL COMMENT 'migration name, unique', -// `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'date migrated or rolled back', -// `statements` longtext COMMENT 'SQL statements for this migration', -// `rollback_statements` longtext, -// `status` enum('update','rollback') DEFAULT NULL COMMENT 'update indicates it is a normal migration while rollback means this migration is rolled back', -// PRIMARY KEY (`id_migration`) -// ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -package migration - -import ( - "errors" - "sort" - "strings" - "time" - - "github.com/astaxie/beego" - "github.com/astaxie/beego/orm" -) - -// const the data format for the bee generate migration datatype -const ( - DateFormat = "20060102_150405" - DBDateFormat = "2006-01-02 15:04:05" -) - -// Migrationer is an interface for all Migration struct -type Migrationer interface { - Up() - Down() - Reset() - Exec(name, status string) error - GetCreated() int64 -} - -var ( - migrationMap map[string]Migrationer -) - -func init() { - migrationMap = make(map[string]Migrationer) -} - -// Migration the basic type which will implement the basic type -type Migration struct { - sqls []string - Created string -} - -// Up implement in the Inheritance struct for upgrade -func (m *Migration) Up() { - -} - -// Down implement in the Inheritance struct for down -func (m *Migration) Down() { - -} - -// SQL add sql want to execute -func (m *Migration) SQL(sql string) { - m.sqls = append(m.sqls, sql) -} - -// Reset the sqls -func (m *Migration) Reset() { - m.sqls = make([]string, 0) -} - -// Exec execute the sql already add in the sql -func (m *Migration) Exec(name, status string) error { - o := orm.NewOrm() - for _, s := range m.sqls { - beego.Info("exec sql:", s) - r := o.Raw(s) - _, err := r.Exec() - if err != nil { - return err - } - } - return m.addOrUpdateRecord(name, status) -} - -func (m *Migration) addOrUpdateRecord(name, status string) error { - o := orm.NewOrm() - if status == "down" { - status = "rollback" - p, err := o.Raw("update migrations set status = ?, rollback_statements = ?, created_at = ? where name = ?").Prepare() - if err != nil { - return nil - } - _, err = p.Exec(status, strings.Join(m.sqls, "; "), time.Now().Format(DBDateFormat), name) - return err - } - status = "update" - p, err := o.Raw("insert into migrations(name, created_at, statements, status) values(?,?,?,?)").Prepare() - if err != nil { - return err - } - _, err = p.Exec(name, time.Now().Format(DBDateFormat), strings.Join(m.sqls, "; "), status) - return err -} - -// GetCreated get the unixtime from the Created -func (m *Migration) GetCreated() int64 { - t, err := time.Parse(DateFormat, m.Created) - if err != nil { - return 0 - } - return t.Unix() -} - -// Register register the Migration in the map -func Register(name string, m Migrationer) error { - if _, ok := migrationMap[name]; ok { - return errors.New("already exist name:" + name) - } - migrationMap[name] = m - return nil -} - -// Upgrade upgrate the migration from lasttime -func Upgrade(lasttime int64) error { - sm := sortMap(migrationMap) - i := 0 - for _, v := range sm { - if v.created > lasttime { - beego.Info("start upgrade", v.name) - v.m.Reset() - v.m.Up() - err := v.m.Exec(v.name, "up") - if err != nil { - beego.Error("execute error:", err) - time.Sleep(2 * time.Second) - return err - } - beego.Info("end upgrade:", v.name) - i++ - } - } - beego.Info("total success upgrade:", i, " migration") - time.Sleep(2 * time.Second) - return nil -} - -// Rollback rollback the migration by the name -func Rollback(name string) error { - if v, ok := migrationMap[name]; ok { - beego.Info("start rollback") - v.Reset() - v.Down() - err := v.Exec(name, "down") - if err != nil { - beego.Error("execute error:", err) - time.Sleep(2 * time.Second) - return err - } - beego.Info("end rollback") - time.Sleep(2 * time.Second) - return nil - } - beego.Error("not exist the migrationMap name:" + name) - time.Sleep(2 * time.Second) - return errors.New("not exist the migrationMap name:" + name) -} - -// Reset reset all migration -// run all migration's down function -func Reset() error { - sm := sortMap(migrationMap) - i := 0 - for j := len(sm) - 1; j >= 0; j-- { - v := sm[j] - if isRollBack(v.name) { - beego.Info("skip the", v.name) - time.Sleep(1 * time.Second) - continue - } - beego.Info("start reset:", v.name) - v.m.Reset() - v.m.Down() - err := v.m.Exec(v.name, "down") - if err != nil { - beego.Error("execute error:", err) - time.Sleep(2 * time.Second) - return err - } - i++ - beego.Info("end reset:", v.name) - } - beego.Info("total success reset:", i, " migration") - time.Sleep(2 * time.Second) - return nil -} - -// Refresh first Reset, then Upgrade -func Refresh() error { - err := Reset() - if err != nil { - beego.Error("execute error:", err) - time.Sleep(2 * time.Second) - return err - } - err = Upgrade(0) - return err -} - -type dataSlice []data - -type data struct { - created int64 - name string - m Migrationer -} - -// Len is part of sort.Interface. -func (d dataSlice) Len() int { - return len(d) -} - -// Swap is part of sort.Interface. -func (d dataSlice) Swap(i, j int) { - d[i], d[j] = d[j], d[i] -} - -// Less is part of sort.Interface. We use count as the value to sort by -func (d dataSlice) Less(i, j int) bool { - return d[i].created < d[j].created -} - -func sortMap(m map[string]Migrationer) dataSlice { - s := make(dataSlice, 0, len(m)) - for k, v := range m { - d := data{} - d.created = v.GetCreated() - d.name = k - d.m = v - s = append(s, d) - } - sort.Sort(s) - return s -} - -func isRollBack(name string) bool { - o := orm.NewOrm() - var maps []orm.Params - num, err := o.Raw("select * from migrations where `name` = ? order by id_migration desc", name).Values(&maps) - if err != nil { - beego.Info("get name has error", err) - return false - } - if num <= 0 { - return false - } - if maps[0]["status"] == "rollback" { - return true - } - return false -} diff --git a/vendor/github.com/astaxie/beego/namespace.go b/vendor/github.com/astaxie/beego/namespace.go index 0dfdd7afd..4007d44cc 100644 --- a/vendor/github.com/astaxie/beego/namespace.go +++ b/vendor/github.com/astaxie/beego/namespace.go @@ -388,3 +388,10 @@ func NSNamespace(prefix string, params ...LinkNamespace) LinkNamespace { ns.Namespace(n) } } + +// NSHandler add handler +func NSHandler(rootpath string, h http.Handler) LinkNamespace { + return func(ns *Namespace) { + ns.Handler(rootpath, h) + } +} diff --git a/vendor/github.com/astaxie/beego/orm/db.go b/vendor/github.com/astaxie/beego/orm/db.go index b62c165bc..314c3535e 100644 --- a/vendor/github.com/astaxie/beego/orm/db.go +++ b/vendor/github.com/astaxie/beego/orm/db.go @@ -113,7 +113,7 @@ func (d *dbBase) collectFieldValue(mi *modelInfo, fi *fieldInfo, ind reflect.Val if fi.pk { _, value, _ = getExistPk(mi, ind) } else { - field := ind.Field(fi.fieldIndex) + field := ind.FieldByIndex(fi.fieldIndex) if fi.isFielder { f := field.Addr().Interface().(Fielder) value = f.RawValue() @@ -517,9 +517,9 @@ func (d *dbBase) Delete(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time. if num > 0 { if mi.fields.pk.auto { if mi.fields.pk.fieldType&IsPostiveIntegerField > 0 { - ind.Field(mi.fields.pk.fieldIndex).SetUint(0) + ind.FieldByIndex(mi.fields.pk.fieldIndex).SetUint(0) } else { - ind.Field(mi.fields.pk.fieldIndex).SetInt(0) + ind.FieldByIndex(mi.fields.pk.fieldIndex).SetInt(0) } } err := d.deleteRels(q, mi, []interface{}{pkValue}, tz) @@ -859,13 +859,13 @@ func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condi mmi = fi.relModelInfo field := last if last.Kind() != reflect.Invalid { - field = reflect.Indirect(last.Field(fi.fieldIndex)) + field = reflect.Indirect(last.FieldByIndex(fi.fieldIndex)) if field.IsValid() { d.setColsValues(mmi, &field, mmi.fields.dbcols, trefs[:len(mmi.fields.dbcols)], tz) for _, fi := range mmi.fields.fieldsReverse { if fi.inModel && fi.reverseFieldInfo.mi == lastm { if fi.reverseFieldInfo != nil { - f := field.Field(fi.fieldIndex) + f := field.FieldByIndex(fi.fieldIndex) if f.Kind() == reflect.Ptr { f.Set(last.Addr()) } @@ -1014,7 +1014,7 @@ func (d *dbBase) setColsValues(mi *modelInfo, ind *reflect.Value, cols []string, fi := mi.fields.GetByColumn(column) - field := ind.Field(fi.fieldIndex) + field := ind.FieldByIndex(fi.fieldIndex) value, err := d.convertValueFromDB(fi, val, tz) if err != nil { @@ -1350,7 +1350,7 @@ setValue: fieldType = fi.relModelInfo.fields.pk.fieldType mf := reflect.New(fi.relModelInfo.addrField.Elem().Type()) field.Set(mf) - f := mf.Elem().Field(fi.relModelInfo.fields.pk.fieldIndex) + f := mf.Elem().FieldByIndex(fi.relModelInfo.fields.pk.fieldIndex) field = f goto setValue } diff --git a/vendor/github.com/astaxie/beego/orm/db_alias.go b/vendor/github.com/astaxie/beego/orm/db_alias.go index 79576b8e5..b6c833a71 100644 --- a/vendor/github.com/astaxie/beego/orm/db_alias.go +++ b/vendor/github.com/astaxie/beego/orm/db_alias.go @@ -59,6 +59,7 @@ var ( "postgres": DRPostgres, "sqlite3": DRSqlite, "tidb": DRTiDB, + "oracle": DROracle, } dbBasers = map[DriverType]dbBaser{ DRMySQL: newdbBaseMysql(), @@ -151,7 +152,7 @@ func detectTZ(al *alias) { al.Engine = "INNODB" } - case DRSqlite: + case DRSqlite, DROracle: al.TZ = time.UTC case DRPostgres: diff --git a/vendor/github.com/astaxie/beego/orm/db_oracle.go b/vendor/github.com/astaxie/beego/orm/db_oracle.go index 1e385c9a4..deca36ad6 100644 --- a/vendor/github.com/astaxie/beego/orm/db_oracle.go +++ b/vendor/github.com/astaxie/beego/orm/db_oracle.go @@ -14,6 +14,41 @@ package orm +import ( + "fmt" + "strings" +) + +// oracle operators. +var oracleOperators = map[string]string{ + "exact": "= ?", + "gt": "> ?", + "gte": ">= ?", + "lt": "< ?", + "lte": "<= ?", + "//iendswith": "LIKE ?", +} + +// oracle column field types. +var oracleTypes = map[string]string{ + "pk": "NOT NULL PRIMARY KEY", + "bool": "bool", + "string": "VARCHAR2(%d)", + "string-text": "VARCHAR2(%d)", + "time.Time-date": "DATE", + "time.Time": "TIMESTAMP", + "int8": "INTEGER", + "int16": "INTEGER", + "int32": "INTEGER", + "int64": "INTEGER", + "uint8": "INTEGER", + "uint16": "INTEGER", + "uint32": "INTEGER", + "uint64": "INTEGER", + "float64": "NUMBER", + "float64-decimal": "NUMBER(%d, %d)", +} + // oracle dbBaser type dbBaseOracle struct { dbBase @@ -27,3 +62,35 @@ func newdbBaseOracle() dbBaser { b.ins = b return b } + +// OperatorSQL get oracle operator. +func (d *dbBaseOracle) OperatorSQL(operator string) string { + return oracleOperators[operator] +} + +// DbTypes get oracle table field types. +func (d *dbBaseOracle) DbTypes() map[string]string { + return oracleTypes +} + +//ShowTablesQuery show all the tables in database +func (d *dbBaseOracle) ShowTablesQuery() string { + return "SELECT TABLE_NAME FROM USER_TABLES" +} + +// Oracle +func (d *dbBaseOracle) ShowColumnsQuery(table string) string { + return fmt.Sprintf("SELECT COLUMN_NAME FROM ALL_TAB_COLUMNS "+ + "WHERE TABLE_NAME ='%s'", strings.ToUpper(table)) +} + +// check index is exist +func (d *dbBaseOracle) IndexExists(db dbQuerier, table string, name string) bool { + row := db.QueryRow("SELECT COUNT(*) FROM USER_IND_COLUMNS, USER_INDEXES "+ + "WHERE USER_IND_COLUMNS.INDEX_NAME = USER_INDEXES.INDEX_NAME "+ + "AND USER_IND_COLUMNS.TABLE_NAME = ? AND USER_IND_COLUMNS.INDEX_NAME = ?", strings.ToUpper(table), strings.ToUpper(name)) + + var cnt int + row.Scan(&cnt) + return cnt > 0 +} diff --git a/vendor/github.com/astaxie/beego/orm/db_utils.go b/vendor/github.com/astaxie/beego/orm/db_utils.go index ae9b1625d..c97caf361 100644 --- a/vendor/github.com/astaxie/beego/orm/db_utils.go +++ b/vendor/github.com/astaxie/beego/orm/db_utils.go @@ -32,7 +32,7 @@ func getDbAlias(name string) *alias { func getExistPk(mi *modelInfo, ind reflect.Value) (column string, value interface{}, exist bool) { fi := mi.fields.pk - v := ind.Field(fi.fieldIndex) + v := ind.FieldByIndex(fi.fieldIndex) if fi.fieldType&IsPostiveIntegerField > 0 { vu := v.Uint() exist = vu > 0 diff --git a/vendor/github.com/astaxie/beego/orm/models_info_f.go b/vendor/github.com/astaxie/beego/orm/models_info_f.go index 14e1f2c62..996a2f408 100644 --- a/vendor/github.com/astaxie/beego/orm/models_info_f.go +++ b/vendor/github.com/astaxie/beego/orm/models_info_f.go @@ -102,7 +102,7 @@ func newFields() *fields { // single field info type fieldInfo struct { mi *modelInfo - fieldIndex int + fieldIndex []int fieldType int dbcol bool inModel bool @@ -138,7 +138,7 @@ type fieldInfo struct { } // new field info -func newFieldInfo(mi *modelInfo, field reflect.Value, sf reflect.StructField) (fi *fieldInfo, err error) { +func newFieldInfo(mi *modelInfo, field reflect.Value, sf reflect.StructField, mName string) (fi *fieldInfo, err error) { var ( tag string tagValue string @@ -278,7 +278,7 @@ checkType: fi.column = getColumnName(fieldType, addrField, sf, tags["column"]) fi.addrValue = addrField fi.sf = sf - fi.fullName = mi.fullName + "." + sf.Name + fi.fullName = mi.fullName + mName + "." + sf.Name fi.null = attrs["null"] fi.index = attrs["index"] diff --git a/vendor/github.com/astaxie/beego/orm/models_info_m.go b/vendor/github.com/astaxie/beego/orm/models_info_m.go index 2654cdb5b..bbb82444d 100644 --- a/vendor/github.com/astaxie/beego/orm/models_info_m.go +++ b/vendor/github.com/astaxie/beego/orm/models_info_m.go @@ -36,11 +36,6 @@ type modelInfo struct { // new model info func newModelInfo(val reflect.Value) (info *modelInfo) { - var ( - err error - fi *fieldInfo - sf reflect.StructField - ) info = &modelInfo{} info.fields = newFields() @@ -53,13 +48,31 @@ func newModelInfo(val reflect.Value) (info *modelInfo) { info.name = typ.Name() info.fullName = getFullName(typ) + addModelFields(info, ind, "", []int{}) + + return +} + +func addModelFields(info *modelInfo, ind reflect.Value, mName string, index []int) { + var ( + err error + fi *fieldInfo + sf reflect.StructField + ) + for i := 0; i < ind.NumField(); i++ { field := ind.Field(i) sf = ind.Type().Field(i) if sf.PkgPath != "" { continue } - fi, err = newFieldInfo(info, field, sf) + // add anonymous struct fields + if sf.Anonymous { + addModelFields(info, field, mName+"."+sf.Name, append(index, i)) + continue + } + + fi, err = newFieldInfo(info, field, sf, mName) if err != nil { if err == errSkipField { @@ -84,7 +97,7 @@ func newModelInfo(val reflect.Value) (info *modelInfo) { } } - fi.fieldIndex = i + fi.fieldIndex = append(index, i) fi.mi = info fi.inModel = true } @@ -93,8 +106,6 @@ func newModelInfo(val reflect.Value) (info *modelInfo) { fmt.Println(fmt.Errorf("field: %s.%s, %s", ind.Type(), sf.Name, err)) os.Exit(2) } - - return } // combine related model info to new model info. diff --git a/vendor/github.com/astaxie/beego/orm/orm.go b/vendor/github.com/astaxie/beego/orm/orm.go index d00d6d038..0ffb6b869 100644 --- a/vendor/github.com/astaxie/beego/orm/orm.go +++ b/vendor/github.com/astaxie/beego/orm/orm.go @@ -140,7 +140,7 @@ func (o *orm) ReadOrCreate(md interface{}, col1 string, cols ...string) (bool, i return (err == nil), id, err } - return false, ind.Field(mi.fields.pk.fieldIndex).Int(), err + return false, ind.FieldByIndex(mi.fields.pk.fieldIndex).Int(), err } // insert model data to database @@ -160,9 +160,9 @@ func (o *orm) Insert(md interface{}) (int64, error) { func (o *orm) setPk(mi *modelInfo, ind reflect.Value, id int64) { if mi.fields.pk.auto { if mi.fields.pk.fieldType&IsPostiveIntegerField > 0 { - ind.Field(mi.fields.pk.fieldIndex).SetUint(uint64(id)) + ind.FieldByIndex(mi.fields.pk.fieldIndex).SetUint(uint64(id)) } else { - ind.Field(mi.fields.pk.fieldIndex).SetInt(id) + ind.FieldByIndex(mi.fields.pk.fieldIndex).SetInt(id) } } } @@ -290,7 +290,7 @@ func (o *orm) LoadRelated(md interface{}, name string, args ...interface{}) (int qs.orders = []string{order} } - find := ind.Field(fi.fieldIndex) + find := ind.FieldByIndex(fi.fieldIndex) var nums int64 var err error diff --git a/vendor/github.com/astaxie/beego/orm/orm_object.go b/vendor/github.com/astaxie/beego/orm/orm_object.go index df5a6600e..8a5d85e28 100644 --- a/vendor/github.com/astaxie/beego/orm/orm_object.go +++ b/vendor/github.com/astaxie/beego/orm/orm_object.go @@ -51,9 +51,9 @@ func (o *insertSet) Insert(md interface{}) (int64, error) { if id > 0 { if o.mi.fields.pk.auto { if o.mi.fields.pk.fieldType&IsPostiveIntegerField > 0 { - ind.Field(o.mi.fields.pk.fieldIndex).SetUint(uint64(id)) + ind.FieldByIndex(o.mi.fields.pk.fieldIndex).SetUint(uint64(id)) } else { - ind.Field(o.mi.fields.pk.fieldIndex).SetInt(id) + ind.FieldByIndex(o.mi.fields.pk.fieldIndex).SetInt(id) } } } diff --git a/vendor/github.com/astaxie/beego/orm/orm_raw.go b/vendor/github.com/astaxie/beego/orm/orm_raw.go index cbb18064f..5f88121cb 100644 --- a/vendor/github.com/astaxie/beego/orm/orm_raw.go +++ b/vendor/github.com/astaxie/beego/orm/orm_raw.go @@ -342,7 +342,7 @@ func (o *rawSet) QueryRow(containers ...interface{}) error { for _, col := range columns { if fi := sMi.fields.GetByColumn(col); fi != nil { value := reflect.ValueOf(columnsMp[col]).Elem().Interface() - o.setFieldValue(ind.FieldByIndex([]int{fi.fieldIndex}), value) + o.setFieldValue(ind.FieldByIndex(fi.fieldIndex), value) } } } else { @@ -480,7 +480,7 @@ func (o *rawSet) QueryRows(containers ...interface{}) (int64, error) { for _, col := range columns { if fi := sMi.fields.GetByColumn(col); fi != nil { value := reflect.ValueOf(columnsMp[col]).Elem().Interface() - o.setFieldValue(ind.FieldByIndex([]int{fi.fieldIndex}), value) + o.setFieldValue(ind.FieldByIndex(fi.fieldIndex), value) } } } else { diff --git a/vendor/github.com/astaxie/beego/orm/types.go b/vendor/github.com/astaxie/beego/orm/types.go index 5fac5fed8..41933dd15 100644 --- a/vendor/github.com/astaxie/beego/orm/types.go +++ b/vendor/github.com/astaxie/beego/orm/types.go @@ -148,6 +148,10 @@ type QuerySeter interface { // add OFFSET value // same as Limit function's args[0] Offset(offset interface{}) QuerySeter + // add GROUP BY expression + // for example: + // qs.GroupBy("id") + GroupBy(exprs ...string) QuerySeter // add ORDER expression. // "column" means ASC, "-column" means DESC. // for example: @@ -162,6 +166,12 @@ type QuerySeter interface { // qs.RelatedSel("profile").One(&user) // user.Profile.Age = 32 RelatedSel(params ...interface{}) QuerySeter + // Set Distinct + // for example: + // o.QueryTable("policy").Filter("Groups__Group__Users__User", user). + // Distinct(). + // All(&permissions) + Distinct() QuerySeter // return QuerySeter execution result number // for example: // num, err = qs.Filter("profile__age__gt", 28).Count() diff --git a/vendor/github.com/astaxie/beego/parser.go b/vendor/github.com/astaxie/beego/parser.go index b14d74b9a..46d023201 100644 --- a/vendor/github.com/astaxie/beego/parser.go +++ b/vendor/github.com/astaxie/beego/parser.go @@ -58,7 +58,7 @@ func parserPkg(pkgRealpath, pkgpath string) error { rep := strings.NewReplacer("/", "_", ".", "_") commentFilename = coomentPrefix + rep.Replace(pkgpath) + ".go" if !compareFile(pkgRealpath) { - Info(pkgRealpath + " has not changed, not reloading") + Info(pkgRealpath + " no changed") return nil } genInfoList = make(map[string][]ControllerComments) @@ -130,7 +130,7 @@ func parserComments(comments *ast.CommentGroup, funcName, controllerName, pkgpat } func genRouterCode() { - os.Mkdir("routers", 0755) + os.Mkdir(path.Join(AppPath, "routers"), 0755) Info("generate router from comments") var ( globalinfo string @@ -172,7 +172,7 @@ func genRouterCode() { } } if globalinfo != "" { - f, err := os.Create(path.Join("routers", commentFilename)) + f, err := os.Create(path.Join(AppPath, "routers", commentFilename)) if err != nil { panic(err) } @@ -182,7 +182,7 @@ func genRouterCode() { } func compareFile(pkgRealpath string) bool { - if !utils.FileExists(path.Join("routers", commentFilename)) { + if !utils.FileExists(path.Join(AppPath, "routers", commentFilename)) { return true } if utils.FileExists(lastupdateFilename) { diff --git a/vendor/github.com/astaxie/beego/plugins/apiauth/apiauth.go b/vendor/github.com/astaxie/beego/plugins/apiauth/apiauth.go deleted file mode 100644 index 8af08088d..000000000 --- a/vendor/github.com/astaxie/beego/plugins/apiauth/apiauth.go +++ /dev/null @@ -1,180 +0,0 @@ -// 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 apiauth provides handlers to enable apiauth support. -// -// Simple Usage: -// import( -// "github.com/astaxie/beego" -// "github.com/astaxie/beego/plugins/apiauth" -// ) -// -// func main(){ -// // apiauth every request -// beego.InsertFilter("*", beego.BeforeRouter,apiauth.APIBaiscAuth("appid","appkey")) -// beego.Run() -// } -// -// Advanced Usage: -// -// func getAppSecret(appid string) string { -// // get appsecret by appid -// // maybe store in configure, maybe in database -// } -// -// beego.InsertFilter("*", beego.BeforeRouter,apiauth.APISecretAuth(getAppSecret, 360)) -// -// Infomation: -// -// In the request user should include these params in the query -// -// 1. appid -// -// appid is assigned to the application -// -// 2. signature -// -// get the signature use apiauth.Signature() -// -// when you send to server remember use url.QueryEscape() -// -// 3. timestamp: -// -// send the request time, the format is yyyy-mm-dd HH:ii:ss -// -package apiauth - -import ( - "crypto/hmac" - "crypto/sha256" - "encoding/base64" - "fmt" - "net/url" - "sort" - "time" - - "github.com/astaxie/beego" - "github.com/astaxie/beego/context" -) - -// AppIDToAppSecret is used to get appsecret throw appid -type AppIDToAppSecret func(string) string - -// APIBaiscAuth use the basic appid/appkey as the AppIdToAppSecret -func APIBaiscAuth(appid, appkey string) beego.FilterFunc { - ft := func(aid string) string { - if aid == appid { - return appkey - } - return "" - } - return APISecretAuth(ft, 300) -} - -// APISecretAuth use AppIdToAppSecret verify and -func APISecretAuth(f AppIDToAppSecret, timeout int) beego.FilterFunc { - return func(ctx *context.Context) { - if ctx.Input.Query("appid") == "" { - ctx.ResponseWriter.WriteHeader(403) - ctx.WriteString("miss query param: appid") - return - } - appsecret := f(ctx.Input.Query("appid")) - if appsecret == "" { - ctx.ResponseWriter.WriteHeader(403) - ctx.WriteString("not exist this appid") - return - } - if ctx.Input.Query("signature") == "" { - ctx.ResponseWriter.WriteHeader(403) - ctx.WriteString("miss query param: signature") - return - } - if ctx.Input.Query("timestamp") == "" { - ctx.ResponseWriter.WriteHeader(403) - ctx.WriteString("miss query param: timestamp") - return - } - u, err := time.Parse("2006-01-02 15:04:05", ctx.Input.Query("timestamp")) - if err != nil { - ctx.ResponseWriter.WriteHeader(403) - ctx.WriteString("timestamp format is error, should 2006-01-02 15:04:05") - return - } - t := time.Now() - if t.Sub(u).Seconds() > float64(timeout) { - ctx.ResponseWriter.WriteHeader(403) - ctx.WriteString("timeout! the request time is long ago, please try again") - return - } - if ctx.Input.Query("signature") != - Signature(appsecret, ctx.Input.Method(), ctx.Request.Form, ctx.Input.URI()) { - ctx.ResponseWriter.WriteHeader(403) - ctx.WriteString("auth failed") - } - } -} - -// Signature used to generate signature with the appsecret/method/params/RequestURI -func Signature(appsecret, method string, params url.Values, RequestURI string) (result string) { - var query string - pa := make(map[string]string) - for k, v := range params { - pa[k] = v[0] - } - vs := mapSorter(pa) - vs.Sort() - for i := 0; i < vs.Len(); i++ { - if vs.Keys[i] == "signature" { - continue - } - if vs.Keys[i] != "" && vs.Vals[i] != "" { - query = fmt.Sprintf("%v%v%v", query, vs.Keys[i], vs.Vals[i]) - } - } - stringToSign := fmt.Sprintf("%v\n%v\n%v\n", method, query, RequestURI) - - sha256 := sha256.New - hash := hmac.New(sha256, []byte(appsecret)) - hash.Write([]byte(stringToSign)) - return base64.StdEncoding.EncodeToString(hash.Sum(nil)) -} - -type valSorter struct { - Keys []string - Vals []string -} - -func mapSorter(m map[string]string) *valSorter { - vs := &valSorter{ - Keys: make([]string, 0, len(m)), - Vals: make([]string, 0, len(m)), - } - for k, v := range m { - vs.Keys = append(vs.Keys, k) - vs.Vals = append(vs.Vals, v) - } - return vs -} - -func (vs *valSorter) Sort() { - sort.Sort(vs) -} - -func (vs *valSorter) Len() int { return len(vs.Keys) } -func (vs *valSorter) Less(i, j int) bool { return vs.Keys[i] < vs.Keys[j] } -func (vs *valSorter) Swap(i, j int) { - vs.Vals[i], vs.Vals[j] = vs.Vals[j], vs.Vals[i] - vs.Keys[i], vs.Keys[j] = vs.Keys[j], vs.Keys[i] -} diff --git a/vendor/github.com/astaxie/beego/plugins/auth/basic.go b/vendor/github.com/astaxie/beego/plugins/auth/basic.go deleted file mode 100644 index c478044ab..000000000 --- a/vendor/github.com/astaxie/beego/plugins/auth/basic.go +++ /dev/null @@ -1,107 +0,0 @@ -// 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 auth provides handlers to enable basic auth support. -// Simple Usage: -// import( -// "github.com/astaxie/beego" -// "github.com/astaxie/beego/plugins/auth" -// ) -// -// func main(){ -// // authenticate every request -// beego.InsertFilter("*", beego.BeforeRouter,auth.Basic("username","secretpassword")) -// beego.Run() -// } -// -// -// Advanced Usage: -// -// func SecretAuth(username, password string) bool { -// return username == "astaxie" && password == "helloBeego" -// } -// authPlugin := auth.NewBasicAuthenticator(SecretAuth, "Authorization Required") -// beego.InsertFilter("*", beego.BeforeRouter,authPlugin) -package auth - -import ( - "encoding/base64" - "net/http" - "strings" - - "github.com/astaxie/beego" - "github.com/astaxie/beego/context" -) - -var defaultRealm = "Authorization Required" - -// Basic is the http basic auth -func Basic(username string, password string) beego.FilterFunc { - secrets := func(user, pass string) bool { - return user == username && pass == password - } - return NewBasicAuthenticator(secrets, defaultRealm) -} - -// NewBasicAuthenticator return the BasicAuth -func NewBasicAuthenticator(secrets SecretProvider, Realm string) beego.FilterFunc { - return func(ctx *context.Context) { - a := &BasicAuth{Secrets: secrets, Realm: Realm} - if username := a.CheckAuth(ctx.Request); username == "" { - a.RequireAuth(ctx.ResponseWriter, ctx.Request) - } - } -} - -// SecretProvider is the SecretProvider function -type SecretProvider func(user, pass string) bool - -// BasicAuth store the SecretProvider and Realm -type BasicAuth struct { - Secrets SecretProvider - Realm string -} - -// CheckAuth Checks the username/password combination from the request. Returns -// either an empty string (authentication failed) or the name of the -// authenticated user. -// Supports MD5 and SHA1 password entries -func (a *BasicAuth) CheckAuth(r *http.Request) string { - s := strings.SplitN(r.Header.Get("Authorization"), " ", 2) - if len(s) != 2 || s[0] != "Basic" { - return "" - } - - b, err := base64.StdEncoding.DecodeString(s[1]) - if err != nil { - return "" - } - pair := strings.SplitN(string(b), ":", 2) - if len(pair) != 2 { - return "" - } - - if a.Secrets(pair[0], pair[1]) { - return pair[0] - } - return "" -} - -// RequireAuth http.Handler for BasicAuth which initiates the authentication process -// (or requires reauthentication). -func (a *BasicAuth) RequireAuth(w http.ResponseWriter, r *http.Request) { - w.Header().Set("WWW-Authenticate", `Basic realm="`+a.Realm+`"`) - w.WriteHeader(401) - w.Write([]byte("401 Unauthorized\n")) -} diff --git a/vendor/github.com/astaxie/beego/plugins/cors/cors.go b/vendor/github.com/astaxie/beego/plugins/cors/cors.go deleted file mode 100644 index 1e973a405..000000000 --- a/vendor/github.com/astaxie/beego/plugins/cors/cors.go +++ /dev/null @@ -1,226 +0,0 @@ -// 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 cors provides handlers to enable CORS support. -// Usage -// import ( -// "github.com/astaxie/beego" -// "github.com/astaxie/beego/plugins/cors" -// ) -// -// func main() { -// // CORS for https://foo.* origins, allowing: -// // - PUT and PATCH methods -// // - Origin header -// // - Credentials share -// beego.InsertFilter("*", beego.BeforeRouter, cors.Allow(&cors.Options{ -// AllowOrigins: []string{"https://*.foo.com"}, -// AllowMethods: []string{"PUT", "PATCH"}, -// AllowHeaders: []string{"Origin"}, -// ExposeHeaders: []string{"Content-Length"}, -// AllowCredentials: true, -// })) -// beego.Run() -// } -package cors - -import ( - "regexp" - "strconv" - "strings" - "time" - - "github.com/astaxie/beego" - "github.com/astaxie/beego/context" -) - -const ( - headerAllowOrigin = "Access-Control-Allow-Origin" - headerAllowCredentials = "Access-Control-Allow-Credentials" - headerAllowHeaders = "Access-Control-Allow-Headers" - headerAllowMethods = "Access-Control-Allow-Methods" - headerExposeHeaders = "Access-Control-Expose-Headers" - headerMaxAge = "Access-Control-Max-Age" - - headerOrigin = "Origin" - headerRequestMethod = "Access-Control-Request-Method" - headerRequestHeaders = "Access-Control-Request-Headers" -) - -var ( - defaultAllowHeaders = []string{"Origin", "Accept", "Content-Type", "Authorization"} - // Regex patterns are generated from AllowOrigins. These are used and generated internally. - allowOriginPatterns = []string{} -) - -// Options represents Access Control options. -type Options struct { - // If set, all origins are allowed. - AllowAllOrigins bool - // A list of allowed origins. Wild cards and FQDNs are supported. - AllowOrigins []string - // If set, allows to share auth credentials such as cookies. - AllowCredentials bool - // A list of allowed HTTP methods. - AllowMethods []string - // A list of allowed HTTP headers. - AllowHeaders []string - // A list of exposed HTTP headers. - ExposeHeaders []string - // Max age of the CORS headers. - MaxAge time.Duration -} - -// Header converts options into CORS headers. -func (o *Options) Header(origin string) (headers map[string]string) { - headers = make(map[string]string) - // if origin is not allowed, don't extend the headers - // with CORS headers. - if !o.AllowAllOrigins && !o.IsOriginAllowed(origin) { - return - } - - // add allow origin - if o.AllowAllOrigins { - headers[headerAllowOrigin] = "*" - } else { - headers[headerAllowOrigin] = origin - } - - // add allow credentials - headers[headerAllowCredentials] = strconv.FormatBool(o.AllowCredentials) - - // add allow methods - if len(o.AllowMethods) > 0 { - headers[headerAllowMethods] = strings.Join(o.AllowMethods, ",") - } - - // add allow headers - if len(o.AllowHeaders) > 0 { - headers[headerAllowHeaders] = strings.Join(o.AllowHeaders, ",") - } - - // add exposed header - if len(o.ExposeHeaders) > 0 { - headers[headerExposeHeaders] = strings.Join(o.ExposeHeaders, ",") - } - // add a max age header - if o.MaxAge > time.Duration(0) { - headers[headerMaxAge] = strconv.FormatInt(int64(o.MaxAge/time.Second), 10) - } - return -} - -// PreflightHeader converts options into CORS headers for a preflight response. -func (o *Options) PreflightHeader(origin, rMethod, rHeaders string) (headers map[string]string) { - headers = make(map[string]string) - if !o.AllowAllOrigins && !o.IsOriginAllowed(origin) { - return - } - // verify if requested method is allowed - for _, method := range o.AllowMethods { - if method == rMethod { - headers[headerAllowMethods] = strings.Join(o.AllowMethods, ",") - break - } - } - - // verify if requested headers are allowed - var allowed []string - for _, rHeader := range strings.Split(rHeaders, ",") { - rHeader = strings.TrimSpace(rHeader) - lookupLoop: - for _, allowedHeader := range o.AllowHeaders { - if strings.ToLower(rHeader) == strings.ToLower(allowedHeader) { - allowed = append(allowed, rHeader) - break lookupLoop - } - } - } - - headers[headerAllowCredentials] = strconv.FormatBool(o.AllowCredentials) - // add allow origin - if o.AllowAllOrigins { - headers[headerAllowOrigin] = "*" - } else { - headers[headerAllowOrigin] = origin - } - - // add allowed headers - if len(allowed) > 0 { - headers[headerAllowHeaders] = strings.Join(allowed, ",") - } - - // add exposed headers - if len(o.ExposeHeaders) > 0 { - headers[headerExposeHeaders] = strings.Join(o.ExposeHeaders, ",") - } - // add a max age header - if o.MaxAge > time.Duration(0) { - headers[headerMaxAge] = strconv.FormatInt(int64(o.MaxAge/time.Second), 10) - } - return -} - -// IsOriginAllowed looks up if the origin matches one of the patterns -// generated from Options.AllowOrigins patterns. -func (o *Options) IsOriginAllowed(origin string) (allowed bool) { - for _, pattern := range allowOriginPatterns { - allowed, _ = regexp.MatchString(pattern, origin) - if allowed { - return - } - } - return -} - -// Allow enables CORS for requests those match the provided options. -func Allow(opts *Options) beego.FilterFunc { - // Allow default headers if nothing is specified. - if len(opts.AllowHeaders) == 0 { - opts.AllowHeaders = defaultAllowHeaders - } - - for _, origin := range opts.AllowOrigins { - pattern := regexp.QuoteMeta(origin) - pattern = strings.Replace(pattern, "\\*", ".*", -1) - pattern = strings.Replace(pattern, "\\?", ".", -1) - allowOriginPatterns = append(allowOriginPatterns, "^"+pattern+"$") - } - - return func(ctx *context.Context) { - var ( - origin = ctx.Input.Header(headerOrigin) - requestedMethod = ctx.Input.Header(headerRequestMethod) - requestedHeaders = ctx.Input.Header(headerRequestHeaders) - // additional headers to be added - // to the response. - headers map[string]string - ) - - if ctx.Input.Method() == "OPTIONS" && - (requestedMethod != "" || requestedHeaders != "") { - headers = opts.PreflightHeader(origin, requestedMethod, requestedHeaders) - for key, value := range headers { - ctx.Output.Header(key, value) - } - return - } - headers = opts.Header(origin) - - for key, value := range headers { - ctx.Output.Header(key, value) - } - } -} diff --git a/vendor/github.com/astaxie/beego/router.go b/vendor/github.com/astaxie/beego/router.go index 726936dee..d0bf534f2 100644 --- a/vendor/github.com/astaxie/beego/router.go +++ b/vendor/github.com/astaxie/beego/router.go @@ -62,12 +62,12 @@ var ( } // these beego.Controller's methods shouldn't reflect to AutoRouter exceptMethod = []string{"Init", "Prepare", "Finish", "Render", "RenderString", - "RenderBytes", "Redirect", "Abort", "StopRun", "UrlFor", "ServeJson", "ServeJsonp", - "ServeXml", "Input", "ParseForm", "GetString", "GetStrings", "GetInt", "GetBool", + "RenderBytes", "Redirect", "Abort", "StopRun", "UrlFor", "ServeJSON", "ServeJSONP", + "ServeXML", "Input", "ParseForm", "GetString", "GetStrings", "GetInt", "GetBool", "GetFloat", "GetFile", "SaveToFile", "StartSession", "SetSession", "GetSession", "DelSession", "SessionRegenerateID", "DestroySession", "IsAjax", "GetSecureCookie", "SetSecureCookie", "XsrfToken", "CheckXsrfCookie", "XsrfFormHtml", - "GetControllerAndAction"} + "GetControllerAndAction", "ServeFormatted"} urlPlaceholder = "{{placeholder}}" // DefaultAccessLogFilter will skip the accesslog if return true @@ -607,6 +607,7 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) ) context := p.pool.Get().(*beecontext.Context) context.Reset(rw, r) + defer p.pool.Put(context) defer p.recoverPanic(context) diff --git a/vendor/github.com/astaxie/beego/session/couchbase/sess_couchbase.go b/vendor/github.com/astaxie/beego/session/couchbase/sess_couchbase.go deleted file mode 100644 index d5be11d0b..000000000 --- a/vendor/github.com/astaxie/beego/session/couchbase/sess_couchbase.go +++ /dev/null @@ -1,243 +0,0 @@ -// 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 couchbase for session provider -// -// depend on github.com/couchbaselabs/go-couchbasee -// -// go install github.com/couchbaselabs/go-couchbase -// -// Usage: -// import( -// _ "github.com/astaxie/beego/session/couchbase" -// "github.com/astaxie/beego/session" -// ) -// -// func init() { -// globalSessions, _ = session.NewManager("couchbase", ``{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"http://host:port/, Pool, Bucket"}``) -// go globalSessions.GC() -// } -// -// more docs: http://beego.me/docs/module/session.md -package couchbase - -import ( - "net/http" - "strings" - "sync" - - couchbase "github.com/couchbase/go-couchbase" - - "github.com/astaxie/beego/session" -) - -var couchbpder = &Provider{} - -// SessionStore store each session -type SessionStore struct { - b *couchbase.Bucket - sid string - lock sync.RWMutex - values map[interface{}]interface{} - maxlifetime int64 -} - -// Provider couchabse provided -type Provider struct { - maxlifetime int64 - savePath string - pool string - bucket string - b *couchbase.Bucket -} - -// Set value to couchabse session -func (cs *SessionStore) Set(key, value interface{}) error { - cs.lock.Lock() - defer cs.lock.Unlock() - cs.values[key] = value - return nil -} - -// Get value from couchabse session -func (cs *SessionStore) Get(key interface{}) interface{} { - cs.lock.RLock() - defer cs.lock.RUnlock() - if v, ok := cs.values[key]; ok { - return v - } - return nil -} - -// Delete value in couchbase session by given key -func (cs *SessionStore) Delete(key interface{}) error { - cs.lock.Lock() - defer cs.lock.Unlock() - delete(cs.values, key) - return nil -} - -// Flush Clean all values in couchbase session -func (cs *SessionStore) Flush() error { - cs.lock.Lock() - defer cs.lock.Unlock() - cs.values = make(map[interface{}]interface{}) - return nil -} - -// SessionID Get couchbase session store id -func (cs *SessionStore) SessionID() string { - return cs.sid -} - -// SessionRelease Write couchbase session with Gob string -func (cs *SessionStore) SessionRelease(w http.ResponseWriter) { - defer cs.b.Close() - - bo, err := session.EncodeGob(cs.values) - if err != nil { - return - } - - cs.b.Set(cs.sid, int(cs.maxlifetime), bo) -} - -func (cp *Provider) getBucket() *couchbase.Bucket { - c, err := couchbase.Connect(cp.savePath) - if err != nil { - return nil - } - - pool, err := c.GetPool(cp.pool) - if err != nil { - return nil - } - - bucket, err := pool.GetBucket(cp.bucket) - if err != nil { - return nil - } - - return bucket -} - -// SessionInit init couchbase session -// savepath like couchbase server REST/JSON URL -// e.g. http://host:port/, Pool, Bucket -func (cp *Provider) SessionInit(maxlifetime int64, savePath string) error { - cp.maxlifetime = maxlifetime - configs := strings.Split(savePath, ",") - if len(configs) > 0 { - cp.savePath = configs[0] - } - if len(configs) > 1 { - cp.pool = configs[1] - } - if len(configs) > 2 { - cp.bucket = configs[2] - } - - return nil -} - -// SessionRead read couchbase session by sid -func (cp *Provider) SessionRead(sid string) (session.Store, error) { - cp.b = cp.getBucket() - - var doc []byte - - err := cp.b.Get(sid, &doc) - var kv map[interface{}]interface{} - if doc == nil { - kv = make(map[interface{}]interface{}) - } else { - kv, err = session.DecodeGob(doc) - if err != nil { - return nil, err - } - } - - cs := &SessionStore{b: cp.b, sid: sid, values: kv, maxlifetime: cp.maxlifetime} - return cs, nil -} - -// SessionExist Check couchbase session exist. -// it checkes sid exist or not. -func (cp *Provider) SessionExist(sid string) bool { - cp.b = cp.getBucket() - defer cp.b.Close() - - var doc []byte - - if err := cp.b.Get(sid, &doc); err != nil || doc == nil { - return false - } - return true -} - -// SessionRegenerate remove oldsid and use sid to generate new session -func (cp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error) { - cp.b = cp.getBucket() - - var doc []byte - if err := cp.b.Get(oldsid, &doc); err != nil || doc == nil { - cp.b.Set(sid, int(cp.maxlifetime), "") - } else { - err := cp.b.Delete(oldsid) - if err != nil { - return nil, err - } - _, _ = cp.b.Add(sid, int(cp.maxlifetime), doc) - } - - err := cp.b.Get(sid, &doc) - if err != nil { - return nil, err - } - var kv map[interface{}]interface{} - if doc == nil { - kv = make(map[interface{}]interface{}) - } else { - kv, err = session.DecodeGob(doc) - if err != nil { - return nil, err - } - } - - cs := &SessionStore{b: cp.b, sid: sid, values: kv, maxlifetime: cp.maxlifetime} - return cs, nil -} - -// SessionDestroy Remove bucket in this couchbase -func (cp *Provider) SessionDestroy(sid string) error { - cp.b = cp.getBucket() - defer cp.b.Close() - - cp.b.Delete(sid) - return nil -} - -// SessionGC Recycle -func (cp *Provider) SessionGC() { - return -} - -// SessionAll return all active session -func (cp *Provider) SessionAll() int { - return 0 -} - -func init() { - session.Register("couchbase", couchbpder) -} diff --git a/vendor/github.com/astaxie/beego/session/ledis/ledis_session.go b/vendor/github.com/astaxie/beego/session/ledis/ledis_session.go deleted file mode 100644 index 68f37b08c..000000000 --- a/vendor/github.com/astaxie/beego/session/ledis/ledis_session.go +++ /dev/null @@ -1,179 +0,0 @@ -// Package ledis provide session Provider -package ledis - -import ( - "net/http" - "strconv" - "strings" - "sync" - - "github.com/astaxie/beego/session" - "github.com/siddontang/ledisdb/config" - "github.com/siddontang/ledisdb/ledis" -) - -var ledispder = &Provider{} -var c *ledis.DB - -// SessionStore ledis session store -type SessionStore struct { - sid string - lock sync.RWMutex - values map[interface{}]interface{} - maxlifetime int64 -} - -// Set value in ledis session -func (ls *SessionStore) Set(key, value interface{}) error { - ls.lock.Lock() - defer ls.lock.Unlock() - ls.values[key] = value - return nil -} - -// Get value in ledis session -func (ls *SessionStore) Get(key interface{}) interface{} { - ls.lock.RLock() - defer ls.lock.RUnlock() - if v, ok := ls.values[key]; ok { - return v - } - return nil -} - -// Delete value in ledis session -func (ls *SessionStore) Delete(key interface{}) error { - ls.lock.Lock() - defer ls.lock.Unlock() - delete(ls.values, key) - return nil -} - -// Flush clear all values in ledis session -func (ls *SessionStore) Flush() error { - ls.lock.Lock() - defer ls.lock.Unlock() - ls.values = make(map[interface{}]interface{}) - return nil -} - -// SessionID get ledis session id -func (ls *SessionStore) SessionID() string { - return ls.sid -} - -// SessionRelease save session values to ledis -func (ls *SessionStore) SessionRelease(w http.ResponseWriter) { - b, err := session.EncodeGob(ls.values) - if err != nil { - return - } - c.Set([]byte(ls.sid), b) - c.Expire([]byte(ls.sid), ls.maxlifetime) -} - -// Provider ledis session provider -type Provider struct { - maxlifetime int64 - savePath string - db int -} - -// SessionInit init ledis session -// savepath like ledis server saveDataPath,pool size -// e.g. 127.0.0.1:6379,100,astaxie -func (lp *Provider) SessionInit(maxlifetime int64, savePath string) error { - var err error - lp.maxlifetime = maxlifetime - configs := strings.Split(savePath, ",") - if len(configs) == 1 { - lp.savePath = configs[0] - } else if len(configs) == 2 { - lp.savePath = configs[0] - lp.db, err = strconv.Atoi(configs[1]) - if err != nil { - return err - } - } - cfg := new(config.Config) - cfg.DataDir = lp.savePath - nowLedis, err := ledis.Open(cfg) - c, err = nowLedis.Select(lp.db) - if err != nil { - println(err) - return nil - } - return nil -} - -// SessionRead read ledis session by sid -func (lp *Provider) SessionRead(sid string) (session.Store, error) { - kvs, err := c.Get([]byte(sid)) - var kv map[interface{}]interface{} - if len(kvs) == 0 { - kv = make(map[interface{}]interface{}) - } else { - kv, err = session.DecodeGob(kvs) - if err != nil { - return nil, err - } - } - ls := &SessionStore{sid: sid, values: kv, maxlifetime: lp.maxlifetime} - return ls, nil -} - -// SessionExist check ledis session exist by sid -func (lp *Provider) SessionExist(sid string) bool { - count, _ := c.Exists([]byte(sid)) - if count == 0 { - return false - } - return true -} - -// SessionRegenerate generate new sid for ledis session -func (lp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error) { - count, _ := c.Exists([]byte(sid)) - if count == 0 { - // oldsid doesn't exists, set the new sid directly - // ignore error here, since if it return error - // the existed value will be 0 - c.Set([]byte(sid), []byte("")) - c.Expire([]byte(sid), lp.maxlifetime) - } else { - data, _ := c.Get([]byte(oldsid)) - c.Set([]byte(sid), data) - c.Expire([]byte(sid), lp.maxlifetime) - } - kvs, err := c.Get([]byte(sid)) - var kv map[interface{}]interface{} - if len(kvs) == 0 { - kv = make(map[interface{}]interface{}) - } else { - kv, err = session.DecodeGob([]byte(kvs)) - if err != nil { - return nil, err - } - } - ls := &SessionStore{sid: sid, values: kv, maxlifetime: lp.maxlifetime} - return ls, nil -} - -// SessionDestroy delete ledis session by id -func (lp *Provider) SessionDestroy(sid string) error { - c.Del([]byte(sid)) - return nil -} - -// SessionGC Impelment method, no used. -func (lp *Provider) SessionGC() { - return -} - -// SessionAll return all active session -func (lp *Provider) SessionAll() int { - return 0 -} -func init() { - session.Register("ledis", ledispder) -} diff --git a/vendor/github.com/astaxie/beego/session/memcache/sess_memcache.go b/vendor/github.com/astaxie/beego/session/memcache/sess_memcache.go deleted file mode 100644 index f1069bc93..000000000 --- a/vendor/github.com/astaxie/beego/session/memcache/sess_memcache.go +++ /dev/null @@ -1,232 +0,0 @@ -// 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 memcache for session provider -// -// depend on github.com/bradfitz/gomemcache/memcache -// -// go install github.com/bradfitz/gomemcache/memcache -// -// Usage: -// import( -// _ "github.com/astaxie/beego/session/memcache" -// "github.com/astaxie/beego/session" -// ) -// -// func init() { -// globalSessions, _ = session.NewManager("memcache", ``{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"127.0.0.1:11211"}``) -// go globalSessions.GC() -// } -// -// more docs: http://beego.me/docs/module/session.md -package memcache - -import ( - "net/http" - "strings" - "sync" - - "github.com/astaxie/beego/session" - - "github.com/bradfitz/gomemcache/memcache" -) - -var mempder = &MemProvider{} -var client *memcache.Client - -// SessionStore memcache session store -type SessionStore struct { - sid string - lock sync.RWMutex - values map[interface{}]interface{} - maxlifetime int64 -} - -// Set value in memcache session -func (rs *SessionStore) Set(key, value interface{}) error { - rs.lock.Lock() - defer rs.lock.Unlock() - rs.values[key] = value - return nil -} - -// Get value in memcache session -func (rs *SessionStore) Get(key interface{}) interface{} { - rs.lock.RLock() - defer rs.lock.RUnlock() - if v, ok := rs.values[key]; ok { - return v - } - return nil -} - -// Delete value in memcache session -func (rs *SessionStore) Delete(key interface{}) error { - rs.lock.Lock() - defer rs.lock.Unlock() - delete(rs.values, key) - return nil -} - -// Flush clear all values in memcache session -func (rs *SessionStore) Flush() error { - rs.lock.Lock() - defer rs.lock.Unlock() - rs.values = make(map[interface{}]interface{}) - return nil -} - -// SessionID get memcache session id -func (rs *SessionStore) SessionID() string { - return rs.sid -} - -// SessionRelease save session values to memcache -func (rs *SessionStore) SessionRelease(w http.ResponseWriter) { - b, err := session.EncodeGob(rs.values) - if err != nil { - return - } - item := memcache.Item{Key: rs.sid, Value: b, Expiration: int32(rs.maxlifetime)} - client.Set(&item) -} - -// MemProvider memcache session provider -type MemProvider struct { - maxlifetime int64 - conninfo []string - poolsize int - password string -} - -// SessionInit init memcache session -// savepath like -// e.g. 127.0.0.1:9090 -func (rp *MemProvider) SessionInit(maxlifetime int64, savePath string) error { - rp.maxlifetime = maxlifetime - rp.conninfo = strings.Split(savePath, ";") - client = memcache.New(rp.conninfo...) - return nil -} - -// SessionRead read memcache session by sid -func (rp *MemProvider) SessionRead(sid string) (session.Store, error) { - if client == nil { - if err := rp.connectInit(); err != nil { - return nil, err - } - } - item, err := client.Get(sid) - if err != nil && err == memcache.ErrCacheMiss { - rs := &SessionStore{sid: sid, values: make(map[interface{}]interface{}), maxlifetime: rp.maxlifetime} - return rs, nil - } - var kv map[interface{}]interface{} - if len(item.Value) == 0 { - kv = make(map[interface{}]interface{}) - } else { - kv, err = session.DecodeGob(item.Value) - if err != nil { - return nil, err - } - } - rs := &SessionStore{sid: sid, values: kv, maxlifetime: rp.maxlifetime} - return rs, nil -} - -// SessionExist check memcache session exist by sid -func (rp *MemProvider) SessionExist(sid string) bool { - if client == nil { - if err := rp.connectInit(); err != nil { - return false - } - } - if item, err := client.Get(sid); err != nil || len(item.Value) == 0 { - return false - } - return true -} - -// SessionRegenerate generate new sid for memcache session -func (rp *MemProvider) SessionRegenerate(oldsid, sid string) (session.Store, error) { - if client == nil { - if err := rp.connectInit(); err != nil { - return nil, err - } - } - var contain []byte - if item, err := client.Get(sid); err != nil || len(item.Value) == 0 { - // oldsid doesn't exists, set the new sid directly - // ignore error here, since if it return error - // the existed value will be 0 - item.Key = sid - item.Value = []byte("") - item.Expiration = int32(rp.maxlifetime) - client.Set(item) - } else { - client.Delete(oldsid) - item.Key = sid - item.Expiration = int32(rp.maxlifetime) - client.Set(item) - contain = item.Value - } - - var kv map[interface{}]interface{} - if len(contain) == 0 { - kv = make(map[interface{}]interface{}) - } else { - var err error - kv, err = session.DecodeGob(contain) - if err != nil { - return nil, err - } - } - - rs := &SessionStore{sid: sid, values: kv, maxlifetime: rp.maxlifetime} - return rs, nil -} - -// SessionDestroy delete memcache session by id -func (rp *MemProvider) SessionDestroy(sid string) error { - if client == nil { - if err := rp.connectInit(); err != nil { - return err - } - } - - err := client.Delete(sid) - if err != nil { - return err - } - return nil -} - -func (rp *MemProvider) connectInit() error { - client = memcache.New(rp.conninfo...) - return nil -} - -// SessionGC Impelment method, no used. -func (rp *MemProvider) SessionGC() { - return -} - -// SessionAll return all activeSession -func (rp *MemProvider) SessionAll() int { - return 0 -} - -func init() { - session.Register("memcache", mempder) -} diff --git a/vendor/github.com/astaxie/beego/session/mysql/sess_mysql.go b/vendor/github.com/astaxie/beego/session/mysql/sess_mysql.go deleted file mode 100644 index 969d26c97..000000000 --- a/vendor/github.com/astaxie/beego/session/mysql/sess_mysql.go +++ /dev/null @@ -1,233 +0,0 @@ -// 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 mysql for session provider -// -// depends on github.com/go-sql-driver/mysql: -// -// go install github.com/go-sql-driver/mysql -// -// mysql session support need create table as sql: -// CREATE TABLE `session` ( -// `session_key` char(64) NOT NULL, -// `session_data` blob, -// `session_expiry` int(11) unsigned NOT NULL, -// PRIMARY KEY (`session_key`) -// ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -// -// Usage: -// import( -// _ "github.com/astaxie/beego/session/mysql" -// "github.com/astaxie/beego/session" -// ) -// -// func init() { -// globalSessions, _ = session.NewManager("mysql", ``{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"[username[:password]@][protocol[(address)]]/dbname[?param1=value1&...¶mN=valueN]"}``) -// go globalSessions.GC() -// } -// -// more docs: http://beego.me/docs/module/session.md -package mysql - -import ( - "database/sql" - "net/http" - "sync" - "time" - - "github.com/astaxie/beego/session" - // import mysql driver - _ "github.com/go-sql-driver/mysql" -) - -var ( - // TableName store the session in MySQL - TableName = "session" - mysqlpder = &Provider{} -) - -// SessionStore mysql session store -type SessionStore struct { - c *sql.DB - sid string - lock sync.RWMutex - values map[interface{}]interface{} -} - -// Set value in mysql session. -// it is temp value in map. -func (st *SessionStore) Set(key, value interface{}) error { - st.lock.Lock() - defer st.lock.Unlock() - st.values[key] = value - return nil -} - -// Get value from mysql session -func (st *SessionStore) Get(key interface{}) interface{} { - st.lock.RLock() - defer st.lock.RUnlock() - if v, ok := st.values[key]; ok { - return v - } - return nil -} - -// Delete value in mysql session -func (st *SessionStore) Delete(key interface{}) error { - st.lock.Lock() - defer st.lock.Unlock() - delete(st.values, key) - return nil -} - -// Flush clear all values in mysql session -func (st *SessionStore) Flush() error { - st.lock.Lock() - defer st.lock.Unlock() - st.values = make(map[interface{}]interface{}) - return nil -} - -// SessionID get session id of this mysql session store -func (st *SessionStore) SessionID() string { - return st.sid -} - -// SessionRelease save mysql session values to database. -// must call this method to save values to database. -func (st *SessionStore) SessionRelease(w http.ResponseWriter) { - defer st.c.Close() - b, err := session.EncodeGob(st.values) - if err != nil { - return - } - st.c.Exec("UPDATE "+TableName+" set `session_data`=?, `session_expiry`=? where session_key=?", - b, time.Now().Unix(), st.sid) - -} - -// Provider mysql session provider -type Provider struct { - maxlifetime int64 - savePath string -} - -// connect to mysql -func (mp *Provider) connectInit() *sql.DB { - db, e := sql.Open("mysql", mp.savePath) - if e != nil { - return nil - } - return db -} - -// SessionInit init mysql session. -// savepath is the connection string of mysql. -func (mp *Provider) SessionInit(maxlifetime int64, savePath string) error { - mp.maxlifetime = maxlifetime - mp.savePath = savePath - return nil -} - -// SessionRead get mysql session by sid -func (mp *Provider) SessionRead(sid string) (session.Store, error) { - c := mp.connectInit() - row := c.QueryRow("select session_data from "+TableName+" where session_key=?", sid) - var sessiondata []byte - err := row.Scan(&sessiondata) - if err == sql.ErrNoRows { - c.Exec("insert into "+TableName+"(`session_key`,`session_data`,`session_expiry`) values(?,?,?)", - sid, "", time.Now().Unix()) - } - var kv map[interface{}]interface{} - if len(sessiondata) == 0 { - kv = make(map[interface{}]interface{}) - } else { - kv, err = session.DecodeGob(sessiondata) - if err != nil { - return nil, err - } - } - rs := &SessionStore{c: c, sid: sid, values: kv} - return rs, nil -} - -// SessionExist check mysql session exist -func (mp *Provider) SessionExist(sid string) bool { - c := mp.connectInit() - defer c.Close() - row := c.QueryRow("select session_data from "+TableName+" where session_key=?", sid) - var sessiondata []byte - err := row.Scan(&sessiondata) - if err == sql.ErrNoRows { - return false - } - return true -} - -// SessionRegenerate generate new sid for mysql session -func (mp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error) { - c := mp.connectInit() - row := c.QueryRow("select session_data from "+TableName+" where session_key=?", oldsid) - var sessiondata []byte - err := row.Scan(&sessiondata) - if err == sql.ErrNoRows { - c.Exec("insert into "+TableName+"(`session_key`,`session_data`,`session_expiry`) values(?,?,?)", oldsid, "", time.Now().Unix()) - } - c.Exec("update "+TableName+" set `session_key`=? where session_key=?", sid, oldsid) - var kv map[interface{}]interface{} - if len(sessiondata) == 0 { - kv = make(map[interface{}]interface{}) - } else { - kv, err = session.DecodeGob(sessiondata) - if err != nil { - return nil, err - } - } - rs := &SessionStore{c: c, sid: sid, values: kv} - return rs, nil -} - -// SessionDestroy delete mysql session by sid -func (mp *Provider) SessionDestroy(sid string) error { - c := mp.connectInit() - c.Exec("DELETE FROM "+TableName+" where session_key=?", sid) - c.Close() - return nil -} - -// SessionGC delete expired values in mysql session -func (mp *Provider) SessionGC() { - c := mp.connectInit() - c.Exec("DELETE from "+TableName+" where session_expiry < ?", time.Now().Unix()-mp.maxlifetime) - c.Close() - return -} - -// SessionAll count values in mysql session -func (mp *Provider) SessionAll() int { - c := mp.connectInit() - defer c.Close() - var total int - err := c.QueryRow("SELECT count(*) as num from " + TableName).Scan(&total) - if err != nil { - return 0 - } - return total -} - -func init() { - session.Register("mysql", mysqlpder) -} diff --git a/vendor/github.com/astaxie/beego/session/postgres/sess_postgresql.go b/vendor/github.com/astaxie/beego/session/postgres/sess_postgresql.go deleted file mode 100644 index 73f9c13a9..000000000 --- a/vendor/github.com/astaxie/beego/session/postgres/sess_postgresql.go +++ /dev/null @@ -1,248 +0,0 @@ -// 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 postgres for session provider -// -// depends on github.com/lib/pq: -// -// go install github.com/lib/pq -// -// -// needs this table in your database: -// -// CREATE TABLE session ( -// session_key char(64) NOT NULL, -// session_data bytea, -// session_expiry timestamp NOT NULL, -// CONSTRAINT session_key PRIMARY KEY(session_key) -// ); -// -// will be activated with these settings in app.conf: -// -// SessionOn = true -// SessionProvider = postgresql -// SessionSavePath = "user=a password=b dbname=c sslmode=disable" -// SessionName = session -// -// -// Usage: -// import( -// _ "github.com/astaxie/beego/session/postgresql" -// "github.com/astaxie/beego/session" -// ) -// -// func init() { -// globalSessions, _ = session.NewManager("postgresql", ``{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"user=pqgotest dbname=pqgotest sslmode=verify-full"}``) -// go globalSessions.GC() -// } -// -// more docs: http://beego.me/docs/module/session.md -package postgres - -import ( - "database/sql" - "net/http" - "sync" - "time" - - "github.com/astaxie/beego/session" - // import postgresql Driver - _ "github.com/lib/pq" -) - -var postgresqlpder = &Provider{} - -// SessionStore postgresql session store -type SessionStore struct { - c *sql.DB - sid string - lock sync.RWMutex - values map[interface{}]interface{} -} - -// Set value in postgresql session. -// it is temp value in map. -func (st *SessionStore) Set(key, value interface{}) error { - st.lock.Lock() - defer st.lock.Unlock() - st.values[key] = value - return nil -} - -// Get value from postgresql session -func (st *SessionStore) Get(key interface{}) interface{} { - st.lock.RLock() - defer st.lock.RUnlock() - if v, ok := st.values[key]; ok { - return v - } - return nil -} - -// Delete value in postgresql session -func (st *SessionStore) Delete(key interface{}) error { - st.lock.Lock() - defer st.lock.Unlock() - delete(st.values, key) - return nil -} - -// Flush clear all values in postgresql session -func (st *SessionStore) Flush() error { - st.lock.Lock() - defer st.lock.Unlock() - st.values = make(map[interface{}]interface{}) - return nil -} - -// SessionID get session id of this postgresql session store -func (st *SessionStore) SessionID() string { - return st.sid -} - -// SessionRelease save postgresql session values to database. -// must call this method to save values to database. -func (st *SessionStore) SessionRelease(w http.ResponseWriter) { - defer st.c.Close() - b, err := session.EncodeGob(st.values) - if err != nil { - return - } - st.c.Exec("UPDATE session set session_data=$1, session_expiry=$2 where session_key=$3", - b, time.Now().Format(time.RFC3339), st.sid) - -} - -// Provider postgresql session provider -type Provider struct { - maxlifetime int64 - savePath string -} - -// connect to postgresql -func (mp *Provider) connectInit() *sql.DB { - db, e := sql.Open("postgres", mp.savePath) - if e != nil { - return nil - } - return db -} - -// SessionInit init postgresql session. -// savepath is the connection string of postgresql. -func (mp *Provider) SessionInit(maxlifetime int64, savePath string) error { - mp.maxlifetime = maxlifetime - mp.savePath = savePath - return nil -} - -// SessionRead get postgresql session by sid -func (mp *Provider) SessionRead(sid string) (session.Store, error) { - c := mp.connectInit() - row := c.QueryRow("select session_data from session where session_key=$1", sid) - var sessiondata []byte - err := row.Scan(&sessiondata) - if err == sql.ErrNoRows { - _, err = c.Exec("insert into session(session_key,session_data,session_expiry) values($1,$2,$3)", - sid, "", time.Now().Format(time.RFC3339)) - - if err != nil { - return nil, err - } - } else if err != nil { - return nil, err - } - - var kv map[interface{}]interface{} - if len(sessiondata) == 0 { - kv = make(map[interface{}]interface{}) - } else { - kv, err = session.DecodeGob(sessiondata) - if err != nil { - return nil, err - } - } - rs := &SessionStore{c: c, sid: sid, values: kv} - return rs, nil -} - -// SessionExist check postgresql session exist -func (mp *Provider) SessionExist(sid string) bool { - c := mp.connectInit() - defer c.Close() - row := c.QueryRow("select session_data from session where session_key=$1", sid) - var sessiondata []byte - err := row.Scan(&sessiondata) - - if err == sql.ErrNoRows { - return false - } - return true -} - -// SessionRegenerate generate new sid for postgresql session -func (mp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error) { - c := mp.connectInit() - row := c.QueryRow("select session_data from session where session_key=$1", oldsid) - var sessiondata []byte - err := row.Scan(&sessiondata) - if err == sql.ErrNoRows { - c.Exec("insert into session(session_key,session_data,session_expiry) values($1,$2,$3)", - oldsid, "", time.Now().Format(time.RFC3339)) - } - c.Exec("update session set session_key=$1 where session_key=$2", sid, oldsid) - var kv map[interface{}]interface{} - if len(sessiondata) == 0 { - kv = make(map[interface{}]interface{}) - } else { - kv, err = session.DecodeGob(sessiondata) - if err != nil { - return nil, err - } - } - rs := &SessionStore{c: c, sid: sid, values: kv} - return rs, nil -} - -// SessionDestroy delete postgresql session by sid -func (mp *Provider) SessionDestroy(sid string) error { - c := mp.connectInit() - c.Exec("DELETE FROM session where session_key=$1", sid) - c.Close() - return nil -} - -// SessionGC delete expired values in postgresql session -func (mp *Provider) SessionGC() { - c := mp.connectInit() - c.Exec("DELETE from session where EXTRACT(EPOCH FROM (current_timestamp - session_expiry)) > $1", mp.maxlifetime) - c.Close() - return -} - -// SessionAll count values in postgresql session -func (mp *Provider) SessionAll() int { - c := mp.connectInit() - defer c.Close() - var total int - err := c.QueryRow("SELECT count(*) as num from session").Scan(&total) - if err != nil { - return 0 - } - return total -} - -func init() { - session.Register("postgresql", postgresqlpder) -} diff --git a/vendor/github.com/astaxie/beego/session/redis/sess_redis.go b/vendor/github.com/astaxie/beego/session/redis/sess_redis.go deleted file mode 100644 index c46fa7cdf..000000000 --- a/vendor/github.com/astaxie/beego/session/redis/sess_redis.go +++ /dev/null @@ -1,256 +0,0 @@ -// 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 redis for session provider -// -// depend on github.com/garyburd/redigo/redis -// -// go install github.com/garyburd/redigo/redis -// -// Usage: -// import( -// _ "github.com/astaxie/beego/session/redis" -// "github.com/astaxie/beego/session" -// ) -// -// func init() { -// globalSessions, _ = session.NewManager("redis", ``{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"127.0.0.1:7070"}``) -// go globalSessions.GC() -// } -// -// more docs: http://beego.me/docs/module/session.md -package redis - -import ( - "net/http" - "strconv" - "strings" - "sync" - - "github.com/astaxie/beego/session" - - "github.com/garyburd/redigo/redis" -) - -var redispder = &Provider{} - -// MaxPoolSize redis max pool size -var MaxPoolSize = 100 - -// SessionStore redis session store -type SessionStore struct { - p *redis.Pool - sid string - lock sync.RWMutex - values map[interface{}]interface{} - maxlifetime int64 -} - -// Set value in redis session -func (rs *SessionStore) Set(key, value interface{}) error { - rs.lock.Lock() - defer rs.lock.Unlock() - rs.values[key] = value - return nil -} - -// Get value in redis session -func (rs *SessionStore) Get(key interface{}) interface{} { - rs.lock.RLock() - defer rs.lock.RUnlock() - if v, ok := rs.values[key]; ok { - return v - } - return nil -} - -// Delete value in redis session -func (rs *SessionStore) Delete(key interface{}) error { - rs.lock.Lock() - defer rs.lock.Unlock() - delete(rs.values, key) - return nil -} - -// Flush clear all values in redis session -func (rs *SessionStore) Flush() error { - rs.lock.Lock() - defer rs.lock.Unlock() - rs.values = make(map[interface{}]interface{}) - return nil -} - -// SessionID get redis session id -func (rs *SessionStore) SessionID() string { - return rs.sid -} - -// SessionRelease save session values to redis -func (rs *SessionStore) SessionRelease(w http.ResponseWriter) { - b, err := session.EncodeGob(rs.values) - if err != nil { - return - } - c := rs.p.Get() - defer c.Close() - c.Do("SETEX", rs.sid, rs.maxlifetime, string(b)) -} - -// Provider redis session provider -type Provider struct { - maxlifetime int64 - savePath string - poolsize int - password string - dbNum int - poollist *redis.Pool -} - -// SessionInit init redis session -// savepath like redis server addr,pool size,password,dbnum -// e.g. 127.0.0.1:6379,100,astaxie,0 -func (rp *Provider) SessionInit(maxlifetime int64, savePath string) error { - rp.maxlifetime = maxlifetime - configs := strings.Split(savePath, ",") - if len(configs) > 0 { - rp.savePath = configs[0] - } - if len(configs) > 1 { - poolsize, err := strconv.Atoi(configs[1]) - if err != nil || poolsize <= 0 { - rp.poolsize = MaxPoolSize - } else { - rp.poolsize = poolsize - } - } else { - rp.poolsize = MaxPoolSize - } - if len(configs) > 2 { - rp.password = configs[2] - } - if len(configs) > 3 { - dbnum, err := strconv.Atoi(configs[3]) - if err != nil || dbnum < 0 { - rp.dbNum = 0 - } else { - rp.dbNum = dbnum - } - } else { - rp.dbNum = 0 - } - rp.poollist = redis.NewPool(func() (redis.Conn, error) { - c, err := redis.Dial("tcp", rp.savePath) - if err != nil { - return nil, err - } - if rp.password != "" { - if _, err := c.Do("AUTH", rp.password); err != nil { - c.Close() - return nil, err - } - } - _, err = c.Do("SELECT", rp.dbNum) - if err != nil { - c.Close() - return nil, err - } - return c, err - }, rp.poolsize) - - return rp.poollist.Get().Err() -} - -// SessionRead read redis session by sid -func (rp *Provider) SessionRead(sid string) (session.Store, error) { - c := rp.poollist.Get() - defer c.Close() - - kvs, err := redis.String(c.Do("GET", sid)) - var kv map[interface{}]interface{} - if len(kvs) == 0 { - kv = make(map[interface{}]interface{}) - } else { - kv, err = session.DecodeGob([]byte(kvs)) - if err != nil { - return nil, err - } - } - - rs := &SessionStore{p: rp.poollist, sid: sid, values: kv, maxlifetime: rp.maxlifetime} - return rs, nil -} - -// SessionExist check redis session exist by sid -func (rp *Provider) SessionExist(sid string) bool { - c := rp.poollist.Get() - defer c.Close() - - if existed, err := redis.Int(c.Do("EXISTS", sid)); err != nil || existed == 0 { - return false - } - return true -} - -// SessionRegenerate generate new sid for redis session -func (rp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error) { - c := rp.poollist.Get() - defer c.Close() - - if existed, _ := redis.Int(c.Do("EXISTS", oldsid)); existed == 0 { - // oldsid doesn't exists, set the new sid directly - // ignore error here, since if it return error - // the existed value will be 0 - c.Do("SET", sid, "", "EX", rp.maxlifetime) - } else { - c.Do("RENAME", oldsid, sid) - c.Do("EXPIRE", sid, rp.maxlifetime) - } - - kvs, err := redis.String(c.Do("GET", sid)) - var kv map[interface{}]interface{} - if len(kvs) == 0 { - kv = make(map[interface{}]interface{}) - } else { - kv, err = session.DecodeGob([]byte(kvs)) - if err != nil { - return nil, err - } - } - - rs := &SessionStore{p: rp.poollist, sid: sid, values: kv, maxlifetime: rp.maxlifetime} - return rs, nil -} - -// SessionDestroy delete redis session by id -func (rp *Provider) SessionDestroy(sid string) error { - c := rp.poollist.Get() - defer c.Close() - - c.Do("DEL", sid) - return nil -} - -// SessionGC Impelment method, no used. -func (rp *Provider) SessionGC() { - return -} - -// SessionAll return all activeSession -func (rp *Provider) SessionAll() int { - return 0 -} - -func init() { - session.Register("redis", redispder) -} diff --git a/vendor/github.com/astaxie/beego/session/sess_mem.go b/vendor/github.com/astaxie/beego/session/sess_mem.go index dd61ef573..64d8b0561 100644 --- a/vendor/github.com/astaxie/beego/session/sess_mem.go +++ b/vendor/github.com/astaxie/beego/session/sess_mem.go @@ -102,7 +102,7 @@ func (pder *MemProvider) SessionRead(sid string) (Store, error) { pder.lock.RUnlock() pder.lock.Lock() newsess := &MemSessionStore{sid: sid, timeAccessed: time.Now(), value: make(map[interface{}]interface{})} - element := pder.list.PushBack(newsess) + element := pder.list.PushFront(newsess) pder.sessions[sid] = element pder.lock.Unlock() return newsess, nil @@ -134,7 +134,7 @@ func (pder *MemProvider) SessionRegenerate(oldsid, sid string) (Store, error) { pder.lock.RUnlock() pder.lock.Lock() newsess := &MemSessionStore{sid: sid, timeAccessed: time.Now(), value: make(map[interface{}]interface{})} - element := pder.list.PushBack(newsess) + element := pder.list.PushFront(newsess) pder.sessions[sid] = element pder.lock.Unlock() return newsess, nil diff --git a/vendor/github.com/astaxie/beego/session/session.go b/vendor/github.com/astaxie/beego/session/session.go index 39d475fc1..9fe99a174 100644 --- a/vendor/github.com/astaxie/beego/session/session.go +++ b/vendor/github.com/astaxie/beego/session/session.go @@ -201,7 +201,9 @@ func (manager *Manager) SessionDestroy(w http.ResponseWriter, r *http.Request) { if err != nil || cookie.Value == "" { return } - manager.provider.SessionDestroy(cookie.Value) + + sid, _ := url.QueryUnescape(cookie.Value) + manager.provider.SessionDestroy(sid) if manager.config.EnableSetCookie { expiration := time.Now() cookie = &http.Cookie{Name: manager.config.CookieName, diff --git a/vendor/github.com/astaxie/beego/staticfile.go b/vendor/github.com/astaxie/beego/staticfile.go index 9534ce914..0aad2c81e 100644 --- a/vendor/github.com/astaxie/beego/staticfile.go +++ b/vendor/github.com/astaxie/beego/staticfile.go @@ -93,12 +93,14 @@ type serveContentHolder struct { var ( staticFileMap = make(map[string]*serveContentHolder) - mapLock sync.Mutex + mapLock sync.RWMutex ) func openFile(filePath string, fi os.FileInfo, acceptEncoding string) (bool, string, *serveContentHolder, error) { mapKey := acceptEncoding + ":" + filePath + mapLock.RLock() mapFile, _ := staticFileMap[mapKey] + mapLock.RUnlock() if isOk(mapFile, fi) { return mapFile.encoding != "", mapFile.encoding, mapFile, nil } diff --git a/vendor/github.com/astaxie/beego/swagger/docs_spec.go b/vendor/github.com/astaxie/beego/swagger/docs_spec.go deleted file mode 100644 index 680324dc0..000000000 --- a/vendor/github.com/astaxie/beego/swagger/docs_spec.go +++ /dev/null @@ -1,160 +0,0 @@ -// 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 swagger struct definition -package swagger - -// SwaggerVersion show the current swagger version -const SwaggerVersion = "1.2" - -// ResourceListing list the resource -type ResourceListing struct { - APIVersion string `json:"apiVersion"` - SwaggerVersion string `json:"swaggerVersion"` // e.g 1.2 - // BasePath string `json:"basePath"` obsolete in 1.1 - APIs []APIRef `json:"apis"` - Info Information `json:"info"` -} - -// APIRef description the api path and description -type APIRef struct { - Path string `json:"path"` // relative or absolute, must start with / - Description string `json:"description"` -} - -// Information show the API Information -type Information struct { - Title string `json:"title,omitempty"` - Description string `json:"description,omitempty"` - Contact string `json:"contact,omitempty"` - TermsOfServiceURL string `json:"termsOfServiceUrl,omitempty"` - License string `json:"license,omitempty"` - LicenseURL string `json:"licenseUrl,omitempty"` -} - -// APIDeclaration see https://github.com/wordnik/swagger-core/blob/scala_2.10-1.3-RC3/schemas/api-declaration-schema.json -type APIDeclaration struct { - APIVersion string `json:"apiVersion"` - SwaggerVersion string `json:"swaggerVersion"` - BasePath string `json:"basePath"` - ResourcePath string `json:"resourcePath"` // must start with / - Consumes []string `json:"consumes,omitempty"` - Produces []string `json:"produces,omitempty"` - APIs []API `json:"apis,omitempty"` - Models map[string]Model `json:"models,omitempty"` -} - -// API show tha API struct -type API struct { - Path string `json:"path"` // relative or absolute, must start with / - Description string `json:"description"` - Operations []Operation `json:"operations,omitempty"` -} - -// Operation desc the Operation -type Operation struct { - HTTPMethod string `json:"httpMethod"` - Nickname string `json:"nickname"` - Type string `json:"type"` // in 1.1 = DataType - // ResponseClass string `json:"responseClass"` obsolete in 1.2 - Summary string `json:"summary,omitempty"` - Notes string `json:"notes,omitempty"` - Parameters []Parameter `json:"parameters,omitempty"` - ResponseMessages []ResponseMessage `json:"responseMessages,omitempty"` // optional - Consumes []string `json:"consumes,omitempty"` - Produces []string `json:"produces,omitempty"` - Authorizations []Authorization `json:"authorizations,omitempty"` - Protocols []Protocol `json:"protocols,omitempty"` -} - -// Protocol support which Protocol -type Protocol struct { -} - -// ResponseMessage Show the -type ResponseMessage struct { - Code int `json:"code"` - Message string `json:"message"` - ResponseModel string `json:"responseModel"` -} - -// Parameter desc the request parameters -type Parameter struct { - ParamType string `json:"paramType"` // path,query,body,header,form - Name string `json:"name"` - Description string `json:"description"` - DataType string `json:"dataType"` // 1.2 needed? - Type string `json:"type"` // integer - Format string `json:"format"` // int64 - AllowMultiple bool `json:"allowMultiple"` - Required bool `json:"required"` - Minimum int `json:"minimum"` - Maximum int `json:"maximum"` -} - -// ErrorResponse desc response -type ErrorResponse struct { - Code int `json:"code"` - Reason string `json:"reason"` -} - -// Model define the data model -type Model struct { - ID string `json:"id"` - Required []string `json:"required,omitempty"` - Properties map[string]ModelProperty `json:"properties"` -} - -// ModelProperty define the properties -type ModelProperty struct { - Type string `json:"type"` - Description string `json:"description"` - Items map[string]string `json:"items,omitempty"` - Format string `json:"format"` -} - -// Authorization see https://github.com/wordnik/swagger-core/wiki/authorizations -type Authorization struct { - LocalOAuth OAuth `json:"local-oauth"` - APIKey APIKey `json:"apiKey"` -} - -// OAuth see https://github.com/wordnik/swagger-core/wiki/authorizations -type OAuth struct { - Type string `json:"type"` // e.g. oauth2 - Scopes []string `json:"scopes"` // e.g. PUBLIC - GrantTypes map[string]GrantType `json:"grantTypes"` -} - -// GrantType see https://github.com/wordnik/swagger-core/wiki/authorizations -type GrantType struct { - LoginEndpoint Endpoint `json:"loginEndpoint"` - TokenName string `json:"tokenName"` // e.g. access_code - TokenRequestEndpoint Endpoint `json:"tokenRequestEndpoint"` - TokenEndpoint Endpoint `json:"tokenEndpoint"` -} - -// Endpoint see https://github.com/wordnik/swagger-core/wiki/authorizations -type Endpoint struct { - URL string `json:"url"` - ClientIDName string `json:"clientIdName"` - ClientSecretName string `json:"clientSecretName"` - TokenName string `json:"tokenName"` -} - -// APIKey see https://github.com/wordnik/swagger-core/wiki/authorizations -type APIKey struct { - Type string `json:"type"` // e.g. apiKey - PassAs string `json:"passAs"` // e.g. header -} diff --git a/vendor/github.com/astaxie/beego/template.go b/vendor/github.com/astaxie/beego/template.go index 363c67541..e6c43f871 100644 --- a/vendor/github.com/astaxie/beego/template.go +++ b/vendor/github.com/astaxie/beego/template.go @@ -18,23 +18,41 @@ import ( "errors" "fmt" "html/template" + "io" "io/ioutil" "os" "path/filepath" "regexp" "strings" + "sync" "github.com/astaxie/beego/utils" ) var ( beegoTplFuncMap = make(template.FuncMap) - // BeeTemplates caching map and supported template file extensions. - BeeTemplates = make(map[string]*template.Template) - // BeeTemplateExt stores the template extension which will build - BeeTemplateExt = []string{"tpl", "html"} + // beeTemplates caching map and supported template file extensions. + beeTemplates = make(map[string]*template.Template) + templatesLock sync.RWMutex + // beeTemplateExt stores the template extension which will build + beeTemplateExt = []string{"tpl", "html"} ) +func executeTemplate(wr io.Writer, name string, data interface{}) error { + if BConfig.RunMode == DEV { + templatesLock.RLock() + defer templatesLock.RUnlock() + } + if t, ok := beeTemplates[name]; ok { + err := t.ExecuteTemplate(wr, name, data) + if err != nil { + Trace("template Execute err:", err) + } + return err + } + panic("can't find templatefile in the path:" + name) +} + func init() { beegoTplFuncMap["dateformat"] = DateFormat beegoTplFuncMap["date"] = Date @@ -53,7 +71,6 @@ func init() { beegoTplFuncMap["config"] = GetConfig beegoTplFuncMap["map_get"] = MapGet - // go1.2 added template funcs // Comparisons beegoTplFuncMap["eq"] = eq // == beegoTplFuncMap["ge"] = ge // >= @@ -62,21 +79,25 @@ func init() { beegoTplFuncMap["lt"] = lt // < beegoTplFuncMap["ne"] = ne // != - beegoTplFuncMap["urlfor"] = URLFor // != + beegoTplFuncMap["urlfor"] = URLFor // build a URL to match a Controller and it's method } // AddFuncMap let user to register a func in the template. -func AddFuncMap(key string, funname interface{}) error { - beegoTplFuncMap[key] = funname +func AddFuncMap(key string, fn interface{}) error { + beegoTplFuncMap[key] = fn return nil } -type templatefile struct { +type templateFile struct { root string files map[string][]string } -func (tf *templatefile) visit(paths string, f os.FileInfo, err error) error { +// visit will make the paths into two part,the first is subDir (without tf.root),the second is full path(without tf.root). +// if tf.root="views" and +// paths is "views/errors/404.html",the subDir will be "errors",the file will be "errors/404.html" +// paths is "views/admin/errors/404.html",the subDir will be "admin/errors",the file will be "admin/errors/404.html" +func (tf *templateFile) visit(paths string, f os.FileInfo, err error) error { if f == nil { return err } @@ -88,24 +109,16 @@ func (tf *templatefile) visit(paths string, f os.FileInfo, err error) error { } replace := strings.NewReplacer("\\", "/") - a := []byte(paths) - a = a[len([]byte(tf.root)):] - file := strings.TrimLeft(replace.Replace(string(a)), "/") - subdir := filepath.Dir(file) - if _, ok := tf.files[subdir]; ok { - tf.files[subdir] = append(tf.files[subdir], file) - } else { - m := make([]string, 1) - m[0] = file - tf.files[subdir] = m - } + file := strings.TrimLeft(replace.Replace(paths[len(tf.root):]), "/") + subDir := filepath.Dir(file) + tf.files[subDir] = append(tf.files[subDir], file) return nil } // HasTemplateExt return this path contains supported template extension of beego or not. func HasTemplateExt(paths string) bool { - for _, v := range BeeTemplateExt { + for _, v := range beeTemplateExt { if strings.HasSuffix(paths, "."+v) { return true } @@ -115,12 +128,12 @@ func HasTemplateExt(paths string) bool { // AddTemplateExt add new extension for template. func AddTemplateExt(ext string) { - for _, v := range BeeTemplateExt { + for _, v := range beeTemplateExt { if v == ext { return } } - BeeTemplateExt = append(BeeTemplateExt, ext) + beeTemplateExt = append(beeTemplateExt, ext) } // BuildTemplate will build all template files in a directory. @@ -132,7 +145,7 @@ func BuildTemplate(dir string, files ...string) error { } return errors.New("dir open err") } - self := &templatefile{ + self := &templateFile{ root: dir, files: make(map[string][]string), } @@ -146,12 +159,14 @@ func BuildTemplate(dir string, files ...string) error { for _, v := range self.files { for _, file := range v { if len(files) == 0 || utils.InSlice(file, files) { + templatesLock.Lock() t, err := getTemplate(self.root, file, v...) if err != nil { Trace("parse template err:", file, err) } else { - BeeTemplates[file] = t + beeTemplates[file] = t } + templatesLock.Unlock() } } } @@ -159,16 +174,16 @@ func BuildTemplate(dir string, files ...string) error { } func getTplDeep(root, file, parent string, t *template.Template) (*template.Template, [][]string, error) { - var fileabspath string + var fileAbsPath string if filepath.HasPrefix(file, "../") { - fileabspath = filepath.Join(root, filepath.Dir(parent), file) + fileAbsPath = filepath.Join(root, filepath.Dir(parent), file) } else { - fileabspath = filepath.Join(root, file) + fileAbsPath = filepath.Join(root, file) } - if e := utils.FileExists(fileabspath); !e { + if e := utils.FileExists(fileAbsPath); !e { panic("can't find template file:" + file) } - data, err := ioutil.ReadFile(fileabspath) + data, err := ioutil.ReadFile(fileAbsPath) if err != nil { return nil, [][]string{}, err } @@ -177,11 +192,11 @@ func getTplDeep(root, file, parent string, t *template.Template) (*template.Temp return nil, [][]string{}, err } reg := regexp.MustCompile(BConfig.WebConfig.TemplateLeft + "[ ]*template[ ]+\"([^\"]+)\"") - allsub := reg.FindAllStringSubmatch(string(data), -1) - for _, m := range allsub { + allSub := reg.FindAllStringSubmatch(string(data), -1) + for _, m := range allSub { if len(m) == 2 { - tlook := t.Lookup(m[1]) - if tlook != nil { + tl := t.Lookup(m[1]) + if tl != nil { continue } if !HasTemplateExt(m[1]) { @@ -193,17 +208,17 @@ func getTplDeep(root, file, parent string, t *template.Template) (*template.Temp } } } - return t, allsub, nil + return t, allSub, nil } func getTemplate(root, file string, others ...string) (t *template.Template, err error) { t = template.New(file).Delims(BConfig.WebConfig.TemplateLeft, BConfig.WebConfig.TemplateRight).Funcs(beegoTplFuncMap) - var submods [][]string - t, submods, err = getTplDeep(root, file, "", t) + var subMods [][]string + t, subMods, err = getTplDeep(root, file, "", t) if err != nil { return nil, err } - t, err = _getTemplate(t, root, submods, others...) + t, err = _getTemplate(t, root, subMods, others...) if err != nil { return nil, err @@ -211,44 +226,44 @@ func getTemplate(root, file string, others ...string) (t *template.Template, err return } -func _getTemplate(t0 *template.Template, root string, submods [][]string, others ...string) (t *template.Template, err error) { +func _getTemplate(t0 *template.Template, root string, subMods [][]string, others ...string) (t *template.Template, err error) { t = t0 - for _, m := range submods { + for _, m := range subMods { if len(m) == 2 { - templ := t.Lookup(m[1]) - if templ != nil { + tpl := t.Lookup(m[1]) + if tpl != nil { continue } //first check filename - for _, otherfile := range others { - if otherfile == m[1] { - var submods1 [][]string - t, submods1, err = getTplDeep(root, otherfile, "", t) + for _, otherFile := range others { + if otherFile == m[1] { + var subMods1 [][]string + t, subMods1, err = getTplDeep(root, otherFile, "", t) if err != nil { Trace("template parse file err:", err) - } else if submods1 != nil && len(submods1) > 0 { - t, err = _getTemplate(t, root, submods1, others...) + } else if subMods1 != nil && len(subMods1) > 0 { + t, err = _getTemplate(t, root, subMods1, others...) } break } } //second check define - for _, otherfile := range others { - fileabspath := filepath.Join(root, otherfile) - data, err := ioutil.ReadFile(fileabspath) + for _, otherFile := range others { + fileAbsPath := filepath.Join(root, otherFile) + data, err := ioutil.ReadFile(fileAbsPath) if err != nil { continue } reg := regexp.MustCompile(BConfig.WebConfig.TemplateLeft + "[ ]*define[ ]+\"([^\"]+)\"") - allsub := reg.FindAllStringSubmatch(string(data), -1) - for _, sub := range allsub { + allSub := reg.FindAllStringSubmatch(string(data), -1) + for _, sub := range allSub { if len(sub) == 2 && sub[1] == m[1] { - var submods1 [][]string - t, submods1, err = getTplDeep(root, otherfile, "", t) + var subMods1 [][]string + t, subMods1, err = getTplDeep(root, otherFile, "", t) if err != nil { Trace("template parse file err:", err) - } else if submods1 != nil && len(submods1) > 0 { - t, err = _getTemplate(t, root, submods1, others...) + } else if subMods1 != nil && len(subMods1) > 0 { + t, err = _getTemplate(t, root, subMods1, others...) } break } @@ -272,7 +287,9 @@ func SetStaticPath(url string, path string) *App { if !strings.HasPrefix(url, "/") { url = "/" + url } - url = strings.TrimRight(url, "/") + if url != "/" { + url = strings.TrimRight(url, "/") + } BConfig.WebConfig.StaticDir[url] = path return BeeApp } @@ -282,7 +299,9 @@ func DelStaticPath(url string) *App { if !strings.HasPrefix(url, "/") { url = "/" + url } - url = strings.TrimRight(url, "/") + if url != "/" { + url = strings.TrimRight(url, "/") + } delete(BConfig.WebConfig.StaticDir, url) return BeeApp } diff --git a/vendor/github.com/astaxie/beego/testing/assertions.go b/vendor/github.com/astaxie/beego/testing/assertions.go deleted file mode 100644 index 96c5d4ddc..000000000 --- a/vendor/github.com/astaxie/beego/testing/assertions.go +++ /dev/null @@ -1,15 +0,0 @@ -// 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 testing diff --git a/vendor/github.com/astaxie/beego/testing/client.go b/vendor/github.com/astaxie/beego/testing/client.go deleted file mode 100644 index c3737e9c6..000000000 --- a/vendor/github.com/astaxie/beego/testing/client.go +++ /dev/null @@ -1,65 +0,0 @@ -// 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 testing - -import ( - "github.com/astaxie/beego/config" - "github.com/astaxie/beego/httplib" -) - -var port = "" -var baseURL = "http://localhost:" - -// TestHTTPRequest beego test request client -type TestHTTPRequest struct { - httplib.BeegoHTTPRequest -} - -func getPort() string { - if port == "" { - config, err := config.NewConfig("ini", "../conf/app.conf") - if err != nil { - return "8080" - } - port = config.String("httpport") - return port - } - return port -} - -// Get returns test client in GET method -func Get(path string) *TestHTTPRequest { - return &TestHTTPRequest{*httplib.Get(baseURL + getPort() + path)} -} - -// Post returns test client in POST method -func Post(path string) *TestHTTPRequest { - return &TestHTTPRequest{*httplib.Post(baseURL + getPort() + path)} -} - -// Put returns test client in PUT method -func Put(path string) *TestHTTPRequest { - return &TestHTTPRequest{*httplib.Put(baseURL + getPort() + path)} -} - -// Delete returns test client in DELETE method -func Delete(path string) *TestHTTPRequest { - return &TestHTTPRequest{*httplib.Delete(baseURL + getPort() + path)} -} - -// Head returns test client in HEAD method -func Head(path string) *TestHTTPRequest { - return &TestHTTPRequest{*httplib.Head(baseURL + getPort() + path)} -} diff --git a/vendor/github.com/astaxie/beego/tree.go b/vendor/github.com/astaxie/beego/tree.go index a6ffe062e..0601099cd 100644 --- a/vendor/github.com/astaxie/beego/tree.go +++ b/vendor/github.com/astaxie/beego/tree.go @@ -141,7 +141,7 @@ func (t *Tree) addtree(segments []string, tree *Tree, wildcards []string, reg st regexpStr = "([^.]+).(.+)" params = params[1:] } else { - for range params { + for _ = range params { regexpStr = "([^/]+)/" + regexpStr } } @@ -254,7 +254,7 @@ func (t *Tree) addseg(segments []string, route interface{}, wildcards []string, regexpStr = "/([^.]+).(.+)" params = params[1:] } else { - for range params { + for _ = range params { regexpStr = "/([^/]+)" + regexpStr } } @@ -265,15 +265,14 @@ func (t *Tree) addseg(segments []string, route interface{}, wildcards []string, } t.wildcard.addseg(segments[1:], route, append(wildcards, params...), reg+regexpStr) } else { - var ok bool var subTree *Tree - for _, subTree = range t.fixrouters { - if t.prefix == seg { - ok = true + for _, sub := range t.fixrouters { + if sub.prefix == seg { + subTree = sub break } } - if !ok { + if subTree == nil { subTree = NewTree() subTree.prefix = seg t.fixrouters = append(t.fixrouters, subTree) @@ -390,7 +389,7 @@ type leafInfo struct { func (leaf *leafInfo) match(wildcardValues []string, ctx *context.Context) (ok bool) { //fmt.Println("Leaf:", wildcardValues, leaf.wildcards, leaf.regexps) if leaf.regexps == nil { - if len(wildcardValues) == 0 { // static path + if len(wildcardValues) == 0 && len(leaf.wildcards) == 0 { // static path return true } // match * @@ -420,7 +419,11 @@ func (leaf *leafInfo) match(wildcardValues []string, ctx *context.Context) (ok b if len(strs) == 2 { ctx.Input.SetParam(":ext", strs[1]) } - ctx.Input.SetParam(":path", path.Join(path.Join(wildcardValues[index:len(wildcardValues)-1]...), strs[0])) + if index > (len(wildcardValues) - 1) { + ctx.Input.SetParam(":path", "") + } else { + ctx.Input.SetParam(":path", path.Join(path.Join(wildcardValues[index:len(wildcardValues)-1]...), strs[0])) + } return true } // match :id @@ -438,7 +441,9 @@ func (leaf *leafInfo) match(wildcardValues []string, ctx *context.Context) (ok b } matches := leaf.regexps.FindStringSubmatch(path.Join(wildcardValues...)) for i, match := range matches[1:] { - ctx.Input.SetParam(leaf.wildcards[i], match) + if i < len(leaf.wildcards) { + ctx.Input.SetParam(leaf.wildcards[i], match) + } } return true } @@ -448,17 +453,11 @@ func (leaf *leafInfo) match(wildcardValues []string, ctx *context.Context) (ok b // "/admin/" -> ["admin"] // "/admin/users" -> ["admin", "users"] func splitPath(key string) []string { + key = strings.Trim(key, "/ ") if key == "" { return []string{} } - elements := strings.Split(key, "/") - if elements[0] == "" { - elements = elements[1:] - } - if elements[len(elements)-1] == "" { - elements = elements[:len(elements)-1] - } - return elements + return strings.Split(key, "/") } // "admin" -> false, nil, "" @@ -542,13 +541,19 @@ func splitSegment(key string) (bool, []string, string) { continue } } - if v == ':' { + // Escape Sequence '\' + if i > 0 && key[i-1] == '\\' { + out = append(out, v) + } else if v == ':' { param = make([]rune, 0) start = true } else if v == '(' { startexp = true start = false - params = append(params, ":"+string(param)) + if len(param) > 0 { + params = append(params, ":"+string(param)) + param = make([]rune, 0) + } paramsNum++ expt = make([]rune, 0) expt = append(expt, '(') diff --git a/vendor/github.com/astaxie/beego/utils/captcha/LICENSE b/vendor/github.com/astaxie/beego/utils/captcha/LICENSE deleted file mode 100644 index 0ad73ae0e..000000000 --- a/vendor/github.com/astaxie/beego/utils/captcha/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2011-2014 Dmitry Chestnykh - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/vendor/github.com/astaxie/beego/utils/captcha/README.md b/vendor/github.com/astaxie/beego/utils/captcha/README.md deleted file mode 100644 index dbc2026b1..000000000 --- a/vendor/github.com/astaxie/beego/utils/captcha/README.md +++ /dev/null @@ -1,45 +0,0 @@ -# Captcha - -an example for use captcha - -``` -package controllers - -import ( - "github.com/astaxie/beego" - "github.com/astaxie/beego/cache" - "github.com/astaxie/beego/utils/captcha" -) - -var cpt *captcha.Captcha - -func init() { - // use beego cache system store the captcha data - store := cache.NewMemoryCache() - cpt = captcha.NewWithFilter("/captcha/", store) -} - -type MainController struct { - beego.Controller -} - -func (this *MainController) Get() { - this.TplName = "index.tpl" -} - -func (this *MainController) Post() { - this.TplName = "index.tpl" - - this.Data["Success"] = cpt.VerifyReq(this.Ctx.Request) -} -``` - -template usage - -``` -{{.Success}} -
- {{create_captcha}} - -
-``` diff --git a/vendor/github.com/astaxie/beego/utils/captcha/captcha.go b/vendor/github.com/astaxie/beego/utils/captcha/captcha.go deleted file mode 100644 index 1a4a6edcb..000000000 --- a/vendor/github.com/astaxie/beego/utils/captcha/captcha.go +++ /dev/null @@ -1,269 +0,0 @@ -// 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 captcha implements generation and verification of image CAPTCHAs. -// an example for use captcha -// -// ``` -// package controllers -// -// import ( -// "github.com/astaxie/beego" -// "github.com/astaxie/beego/cache" -// "github.com/astaxie/beego/utils/captcha" -// ) -// -// var cpt *captcha.Captcha -// -// func init() { -// // use beego cache system store the captcha data -// store := cache.NewMemoryCache() -// cpt = captcha.NewWithFilter("/captcha/", store) -// } -// -// type MainController struct { -// beego.Controller -// } -// -// func (this *MainController) Get() { -// this.TplName = "index.tpl" -// } -// -// func (this *MainController) Post() { -// this.TplName = "index.tpl" -// -// this.Data["Success"] = cpt.VerifyReq(this.Ctx.Request) -// } -// ``` -// -// template usage -// -// ``` -// {{.Success}} -//
-// {{create_captcha}} -// -//
-// ``` -package captcha - -import ( - "fmt" - "html/template" - "net/http" - "path" - "strings" - "time" - - "github.com/astaxie/beego" - "github.com/astaxie/beego/cache" - "github.com/astaxie/beego/context" - "github.com/astaxie/beego/utils" -) - -var ( - defaultChars = []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} -) - -const ( - // default captcha attributes - challengeNums = 6 - expiration = 600 * time.Second - fieldIDName = "captcha_id" - fieldCaptchaName = "captcha" - cachePrefix = "captcha_" - defaultURLPrefix = "/captcha/" -) - -// Captcha struct -type Captcha struct { - // beego cache store - store cache.Cache - - // url prefix for captcha image - URLPrefix string - - // specify captcha id input field name - FieldIDName string - // specify captcha result input field name - FieldCaptchaName string - - // captcha image width and height - StdWidth int - StdHeight int - - // captcha chars nums - ChallengeNums int - - // captcha expiration seconds - Expiration time.Duration - - // cache key prefix - CachePrefix string -} - -// generate key string -func (c *Captcha) key(id string) string { - return c.CachePrefix + id -} - -// generate rand chars with default chars -func (c *Captcha) genRandChars() []byte { - return utils.RandomCreateBytes(c.ChallengeNums, defaultChars...) -} - -// Handler beego filter handler for serve captcha image -func (c *Captcha) Handler(ctx *context.Context) { - var chars []byte - - id := path.Base(ctx.Request.RequestURI) - if i := strings.Index(id, "."); i != -1 { - id = id[:i] - } - - key := c.key(id) - - if len(ctx.Input.Query("reload")) > 0 { - chars = c.genRandChars() - if err := c.store.Put(key, chars, c.Expiration); err != nil { - ctx.Output.SetStatus(500) - ctx.WriteString("captcha reload error") - beego.Error("Reload Create Captcha Error:", err) - return - } - } else { - if v, ok := c.store.Get(key).([]byte); ok { - chars = v - } else { - ctx.Output.SetStatus(404) - ctx.WriteString("captcha not found") - return - } - } - - img := NewImage(chars, c.StdWidth, c.StdHeight) - if _, err := img.WriteTo(ctx.ResponseWriter); err != nil { - beego.Error("Write Captcha Image Error:", err) - } -} - -// CreateCaptchaHTML template func for output html -func (c *Captcha) CreateCaptchaHTML() template.HTML { - value, err := c.CreateCaptcha() - if err != nil { - beego.Error("Create Captcha Error:", err) - return "" - } - - // create html - return template.HTML(fmt.Sprintf(``+ - ``+ - ``+ - ``, c.FieldIDName, value, c.URLPrefix, value, c.URLPrefix, value)) -} - -// CreateCaptcha create a new captcha id -func (c *Captcha) CreateCaptcha() (string, error) { - // generate captcha id - id := string(utils.RandomCreateBytes(15)) - - // get the captcha chars - chars := c.genRandChars() - - // save to store - if err := c.store.Put(c.key(id), chars, c.Expiration); err != nil { - return "", err - } - - return id, nil -} - -// VerifyReq verify from a request -func (c *Captcha) VerifyReq(req *http.Request) bool { - req.ParseForm() - return c.Verify(req.Form.Get(c.FieldIDName), req.Form.Get(c.FieldCaptchaName)) -} - -// Verify direct verify id and challenge string -func (c *Captcha) Verify(id string, challenge string) (success bool) { - if len(challenge) == 0 || len(id) == 0 { - return - } - - var chars []byte - - key := c.key(id) - - if v, ok := c.store.Get(key).([]byte); ok { - chars = v - } else { - return - } - - defer func() { - // finally remove it - c.store.Delete(key) - }() - - if len(chars) != len(challenge) { - return - } - // verify challenge - for i, c := range chars { - if c != challenge[i]-48 { - return - } - } - - return true -} - -// NewCaptcha create a new captcha.Captcha -func NewCaptcha(urlPrefix string, store cache.Cache) *Captcha { - cpt := &Captcha{} - cpt.store = store - cpt.FieldIDName = fieldIDName - cpt.FieldCaptchaName = fieldCaptchaName - cpt.ChallengeNums = challengeNums - cpt.Expiration = expiration - cpt.CachePrefix = cachePrefix - cpt.StdWidth = stdWidth - cpt.StdHeight = stdHeight - - if len(urlPrefix) == 0 { - urlPrefix = defaultURLPrefix - } - - if urlPrefix[len(urlPrefix)-1] != '/' { - urlPrefix += "/" - } - - cpt.URLPrefix = urlPrefix - - return cpt -} - -// NewWithFilter create a new captcha.Captcha and auto AddFilter for serve captacha image -// and add a template func for output html -func NewWithFilter(urlPrefix string, store cache.Cache) *Captcha { - cpt := NewCaptcha(urlPrefix, store) - - // create filter for serve captcha image - beego.InsertFilter(cpt.URLPrefix+"*", beego.BeforeRouter, cpt.Handler) - - // add to template func map - beego.AddFuncMap("create_captcha", cpt.CreateCaptchaHTML) - - return cpt -} diff --git a/vendor/github.com/astaxie/beego/utils/captcha/image.go b/vendor/github.com/astaxie/beego/utils/captcha/image.go deleted file mode 100644 index 1057192aa..000000000 --- a/vendor/github.com/astaxie/beego/utils/captcha/image.go +++ /dev/null @@ -1,498 +0,0 @@ -// 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 captcha - -import ( - "bytes" - "image" - "image/color" - "image/png" - "io" - "math" -) - -const ( - fontWidth = 11 - fontHeight = 18 - blackChar = 1 - - // Standard width and height of a captcha image. - stdWidth = 240 - stdHeight = 80 - // Maximum absolute skew factor of a single digit. - maxSkew = 0.7 - // Number of background circles. - circleCount = 20 -) - -var font = [][]byte{ - { // 0 - 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, - 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, - 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, - }, - { // 1 - 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - }, - { // 2 - 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, - 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, - 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - }, - { // 3 - 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, - 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, - }, - { // 4 - 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, - }, - { // 5 - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, - }, - { // 6 - 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, - 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, - 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, - 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, - }, - { // 7 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, - }, - { // 8 - 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, - 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, - 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, - 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, - 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, - 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, - 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, - }, - { // 9 - 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, - 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, - 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, - }, -} - -// Image struct -type Image struct { - *image.Paletted - numWidth int - numHeight int - dotSize int -} - -var prng = &siprng{} - -// randIntn returns a pseudorandom non-negative int in range [0, n). -func randIntn(n int) int { - return prng.Intn(n) -} - -// randInt returns a pseudorandom int in range [from, to]. -func randInt(from, to int) int { - return prng.Intn(to+1-from) + from -} - -// randFloat returns a pseudorandom float64 in range [from, to]. -func randFloat(from, to float64) float64 { - return (to-from)*prng.Float64() + from -} - -func randomPalette() color.Palette { - p := make([]color.Color, circleCount+1) - // Transparent color. - p[0] = color.RGBA{0xFF, 0xFF, 0xFF, 0x00} - // Primary color. - prim := color.RGBA{ - uint8(randIntn(129)), - uint8(randIntn(129)), - uint8(randIntn(129)), - 0xFF, - } - p[1] = prim - // Circle colors. - for i := 2; i <= circleCount; i++ { - p[i] = randomBrightness(prim, 255) - } - return p -} - -// NewImage returns a new captcha image of the given width and height with the -// given digits, where each digit must be in range 0-9. -func NewImage(digits []byte, width, height int) *Image { - m := new(Image) - m.Paletted = image.NewPaletted(image.Rect(0, 0, width, height), randomPalette()) - m.calculateSizes(width, height, len(digits)) - // Randomly position captcha inside the image. - maxx := width - (m.numWidth+m.dotSize)*len(digits) - m.dotSize - maxy := height - m.numHeight - m.dotSize*2 - var border int - if width > height { - border = height / 5 - } else { - border = width / 5 - } - x := randInt(border, maxx-border) - y := randInt(border, maxy-border) - // Draw digits. - for _, n := range digits { - m.drawDigit(font[n], x, y) - x += m.numWidth + m.dotSize - } - // Draw strike-through line. - m.strikeThrough() - // Apply wave distortion. - m.distort(randFloat(5, 10), randFloat(100, 200)) - // Fill image with random circles. - m.fillWithCircles(circleCount, m.dotSize) - return m -} - -// encodedPNG encodes an image to PNG and returns -// the result as a byte slice. -func (m *Image) encodedPNG() []byte { - var buf bytes.Buffer - if err := png.Encode(&buf, m.Paletted); err != nil { - panic(err.Error()) - } - return buf.Bytes() -} - -// WriteTo writes captcha image in PNG format into the given writer. -func (m *Image) WriteTo(w io.Writer) (int64, error) { - n, err := w.Write(m.encodedPNG()) - return int64(n), err -} - -func (m *Image) calculateSizes(width, height, ncount int) { - // Goal: fit all digits inside the image. - var border int - if width > height { - border = height / 4 - } else { - border = width / 4 - } - // Convert everything to floats for calculations. - w := float64(width - border*2) - h := float64(height - border*2) - // fw takes into account 1-dot spacing between digits. - fw := float64(fontWidth + 1) - fh := float64(fontHeight) - nc := float64(ncount) - // Calculate the width of a single digit taking into account only the - // width of the image. - nw := w / nc - // Calculate the height of a digit from this width. - nh := nw * fh / fw - // Digit too high? - if nh > h { - // Fit digits based on height. - nh = h - nw = fw / fh * nh - } - // Calculate dot size. - m.dotSize = int(nh / fh) - // Save everything, making the actual width smaller by 1 dot to account - // for spacing between digits. - m.numWidth = int(nw) - m.dotSize - m.numHeight = int(nh) -} - -func (m *Image) drawHorizLine(fromX, toX, y int, colorIdx uint8) { - for x := fromX; x <= toX; x++ { - m.SetColorIndex(x, y, colorIdx) - } -} - -func (m *Image) drawCircle(x, y, radius int, colorIdx uint8) { - f := 1 - radius - dfx := 1 - dfy := -2 * radius - xo := 0 - yo := radius - - m.SetColorIndex(x, y+radius, colorIdx) - m.SetColorIndex(x, y-radius, colorIdx) - m.drawHorizLine(x-radius, x+radius, y, colorIdx) - - for xo < yo { - if f >= 0 { - yo-- - dfy += 2 - f += dfy - } - xo++ - dfx += 2 - f += dfx - m.drawHorizLine(x-xo, x+xo, y+yo, colorIdx) - m.drawHorizLine(x-xo, x+xo, y-yo, colorIdx) - m.drawHorizLine(x-yo, x+yo, y+xo, colorIdx) - m.drawHorizLine(x-yo, x+yo, y-xo, colorIdx) - } -} - -func (m *Image) fillWithCircles(n, maxradius int) { - maxx := m.Bounds().Max.X - maxy := m.Bounds().Max.Y - for i := 0; i < n; i++ { - colorIdx := uint8(randInt(1, circleCount-1)) - r := randInt(1, maxradius) - m.drawCircle(randInt(r, maxx-r), randInt(r, maxy-r), r, colorIdx) - } -} - -func (m *Image) strikeThrough() { - maxx := m.Bounds().Max.X - maxy := m.Bounds().Max.Y - y := randInt(maxy/3, maxy-maxy/3) - amplitude := randFloat(5, 20) - period := randFloat(80, 180) - dx := 2.0 * math.Pi / period - for x := 0; x < maxx; x++ { - xo := amplitude * math.Cos(float64(y)*dx) - yo := amplitude * math.Sin(float64(x)*dx) - for yn := 0; yn < m.dotSize; yn++ { - r := randInt(0, m.dotSize) - m.drawCircle(x+int(xo), y+int(yo)+(yn*m.dotSize), r/2, 1) - } - } -} - -func (m *Image) drawDigit(digit []byte, x, y int) { - skf := randFloat(-maxSkew, maxSkew) - xs := float64(x) - r := m.dotSize / 2 - y += randInt(-r, r) - for yo := 0; yo < fontHeight; yo++ { - for xo := 0; xo < fontWidth; xo++ { - if digit[yo*fontWidth+xo] != blackChar { - continue - } - m.drawCircle(x+xo*m.dotSize, y+yo*m.dotSize, r, 1) - } - xs += skf - x = int(xs) - } -} - -func (m *Image) distort(amplude float64, period float64) { - w := m.Bounds().Max.X - h := m.Bounds().Max.Y - - oldm := m.Paletted - newm := image.NewPaletted(image.Rect(0, 0, w, h), oldm.Palette) - - dx := 2.0 * math.Pi / period - for x := 0; x < w; x++ { - for y := 0; y < h; y++ { - xo := amplude * math.Sin(float64(y)*dx) - yo := amplude * math.Cos(float64(x)*dx) - newm.SetColorIndex(x, y, oldm.ColorIndexAt(x+int(xo), y+int(yo))) - } - } - m.Paletted = newm -} - -func randomBrightness(c color.RGBA, max uint8) color.RGBA { - minc := min3(c.R, c.G, c.B) - maxc := max3(c.R, c.G, c.B) - if maxc > max { - return c - } - n := randIntn(int(max-maxc)) - int(minc) - return color.RGBA{ - uint8(int(c.R) + n), - uint8(int(c.G) + n), - uint8(int(c.B) + n), - uint8(c.A), - } -} - -func min3(x, y, z uint8) (m uint8) { - m = x - if y < m { - m = y - } - if z < m { - m = z - } - return -} - -func max3(x, y, z uint8) (m uint8) { - m = x - if y > m { - m = y - } - if z > m { - m = z - } - return -} diff --git a/vendor/github.com/astaxie/beego/utils/captcha/siprng.go b/vendor/github.com/astaxie/beego/utils/captcha/siprng.go deleted file mode 100644 index 5e256cf93..000000000 --- a/vendor/github.com/astaxie/beego/utils/captcha/siprng.go +++ /dev/null @@ -1,277 +0,0 @@ -// 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 captcha - -import ( - "crypto/rand" - "encoding/binary" - "io" - "sync" -) - -// siprng is PRNG based on SipHash-2-4. -type siprng struct { - mu sync.Mutex - k0, k1, ctr uint64 -} - -// siphash implements SipHash-2-4, accepting a uint64 as a message. -func siphash(k0, k1, m uint64) uint64 { - // Initialization. - v0 := k0 ^ 0x736f6d6570736575 - v1 := k1 ^ 0x646f72616e646f6d - v2 := k0 ^ 0x6c7967656e657261 - v3 := k1 ^ 0x7465646279746573 - t := uint64(8) << 56 - - // Compression. - v3 ^= m - - // Round 1. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - // Round 2. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - v0 ^= m - - // Compress last block. - v3 ^= t - - // Round 1. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - // Round 2. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - v0 ^= t - - // Finalization. - v2 ^= 0xff - - // Round 1. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - // Round 2. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - // Round 3. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - // Round 4. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - return v0 ^ v1 ^ v2 ^ v3 -} - -// rekey sets a new PRNG key, which is read from crypto/rand. -func (p *siprng) rekey() { - var k [16]byte - if _, err := io.ReadFull(rand.Reader, k[:]); err != nil { - panic(err.Error()) - } - p.k0 = binary.LittleEndian.Uint64(k[0:8]) - p.k1 = binary.LittleEndian.Uint64(k[8:16]) - p.ctr = 1 -} - -// Uint64 returns a new pseudorandom uint64. -// It rekeys PRNG on the first call and every 64 MB of generated data. -func (p *siprng) Uint64() uint64 { - p.mu.Lock() - if p.ctr == 0 || p.ctr > 8*1024*1024 { - p.rekey() - } - v := siphash(p.k0, p.k1, p.ctr) - p.ctr++ - p.mu.Unlock() - return v -} - -func (p *siprng) Int63() int64 { - return int64(p.Uint64() & 0x7fffffffffffffff) -} - -func (p *siprng) Uint32() uint32 { - return uint32(p.Uint64()) -} - -func (p *siprng) Int31() int32 { - return int32(p.Uint32() & 0x7fffffff) -} - -func (p *siprng) Intn(n int) int { - if n <= 0 { - panic("invalid argument to Intn") - } - if n <= 1<<31-1 { - return int(p.Int31n(int32(n))) - } - return int(p.Int63n(int64(n))) -} - -func (p *siprng) Int63n(n int64) int64 { - if n <= 0 { - panic("invalid argument to Int63n") - } - max := int64((1 << 63) - 1 - (1<<63)%uint64(n)) - v := p.Int63() - for v > max { - v = p.Int63() - } - return v % n -} - -func (p *siprng) Int31n(n int32) int32 { - if n <= 0 { - panic("invalid argument to Int31n") - } - max := int32((1 << 31) - 1 - (1<<31)%uint32(n)) - v := p.Int31() - for v > max { - v = p.Int31() - } - return v % n -} - -func (p *siprng) Float64() float64 { return float64(p.Int63()) / (1 << 63) } diff --git a/vendor/github.com/astaxie/beego/utils/mail.go b/vendor/github.com/astaxie/beego/utils/mail.go index 1d80a0391..10555a0a3 100644 --- a/vendor/github.com/astaxie/beego/utils/mail.go +++ b/vendor/github.com/astaxie/beego/utils/mail.go @@ -31,10 +31,13 @@ import ( "path/filepath" "strconv" "strings" + "sync" ) const ( maxLineLength = 76 + + upperhex = "0123456789ABCDEF" ) // Email is the type used for email messages @@ -74,9 +77,6 @@ func NewEMail(config string) *Email { if err != nil { return nil } - if e.From == "" { - e.From = e.Username - } return e } @@ -228,14 +228,21 @@ func (e *Email) Send() error { to := make([]string, 0, len(e.To)+len(e.Cc)+len(e.Bcc)) to = append(append(append(to, e.To...), e.Cc...), e.Bcc...) // Check to make sure there is at least one recipient and one "From" address - if e.From == "" || len(to) == 0 { - return errors.New("Must specify at least one From address and one To address") + if len(to) == 0 { + return errors.New("Must specify at least one To address") } - from, err := mail.ParseAddress(e.From) + + from, err := mail.ParseAddress(e.Username) if err != nil { return err } - e.From = from.String() + + if len(e.From) == 0 { + e.From = e.Username + } + // use mail's RFC 2047 to encode any string + e.Subject = qEncode("utf-8", e.Subject) + raw, err := e.Bytes() if err != nil { return err @@ -342,3 +349,73 @@ func base64Wrap(w io.Writer, b []byte) { w.Write(out) } } + +// Encode returns the encoded-word form of s. If s is ASCII without special +// characters, it is returned unchanged. The provided charset is the IANA +// charset name of s. It is case insensitive. +// RFC 2047 encoded-word +func qEncode(charset, s string) string { + if !needsEncoding(s) { + return s + } + return encodeWord(charset, s) +} + +func needsEncoding(s string) bool { + for _, b := range s { + if (b < ' ' || b > '~') && b != '\t' { + return true + } + } + return false +} + +// encodeWord encodes a string into an encoded-word. +func encodeWord(charset, s string) string { + buf := getBuffer() + + buf.WriteString("=?") + buf.WriteString(charset) + buf.WriteByte('?') + buf.WriteByte('q') + buf.WriteByte('?') + + enc := make([]byte, 3) + for i := 0; i < len(s); i++ { + b := s[i] + switch { + case b == ' ': + buf.WriteByte('_') + case b <= '~' && b >= '!' && b != '=' && b != '?' && b != '_': + buf.WriteByte(b) + default: + enc[0] = '=' + enc[1] = upperhex[b>>4] + enc[2] = upperhex[b&0x0f] + buf.Write(enc) + } + } + buf.WriteString("?=") + + es := buf.String() + putBuffer(buf) + return es +} + +var bufPool = sync.Pool{ + New: func() interface{} { + return new(bytes.Buffer) + }, +} + +func getBuffer() *bytes.Buffer { + return bufPool.Get().(*bytes.Buffer) +} + +func putBuffer(buf *bytes.Buffer) { + if buf.Len() > 1024 { + return + } + buf.Reset() + bufPool.Put(buf) +} diff --git a/vendor/github.com/astaxie/beego/utils/pagination/controller.go b/vendor/github.com/astaxie/beego/utils/pagination/controller.go deleted file mode 100644 index 1d99cac5c..000000000 --- a/vendor/github.com/astaxie/beego/utils/pagination/controller.go +++ /dev/null @@ -1,26 +0,0 @@ -// 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 pagination - -import ( - "github.com/astaxie/beego/context" -) - -// SetPaginator Instantiates a Paginator and assigns it to context.Input.Data["paginator"]. -func SetPaginator(context *context.Context, per int, nums int64) (paginator *Paginator) { - paginator = NewPaginator(context.Request, per, nums) - context.Input.SetData("paginator", &paginator) - return -} diff --git a/vendor/github.com/astaxie/beego/utils/pagination/doc.go b/vendor/github.com/astaxie/beego/utils/pagination/doc.go deleted file mode 100644 index 9abc6d782..000000000 --- a/vendor/github.com/astaxie/beego/utils/pagination/doc.go +++ /dev/null @@ -1,58 +0,0 @@ -/* -Package pagination provides utilities to setup a paginator within the -context of a http request. - -Usage - -In your beego.Controller: - - package controllers - - import "github.com/astaxie/beego/utils/pagination" - - type PostsController struct { - beego.Controller - } - - func (this *PostsController) ListAllPosts() { - // sets this.Data["paginator"] with the current offset (from the url query param) - postsPerPage := 20 - paginator := pagination.SetPaginator(this.Ctx, postsPerPage, CountPosts()) - - // fetch the next 20 posts - this.Data["posts"] = ListPostsByOffsetAndLimit(paginator.Offset(), postsPerPage) - } - - -In your view templates: - - {{if .paginator.HasPages}} - - {{end}} - -See also - -http://beego.me/docs/mvc/view/page.md - -*/ -package pagination diff --git a/vendor/github.com/astaxie/beego/utils/pagination/paginator.go b/vendor/github.com/astaxie/beego/utils/pagination/paginator.go deleted file mode 100644 index c6db31e08..000000000 --- a/vendor/github.com/astaxie/beego/utils/pagination/paginator.go +++ /dev/null @@ -1,189 +0,0 @@ -// 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 pagination - -import ( - "math" - "net/http" - "net/url" - "strconv" -) - -// Paginator within the state of a http request. -type Paginator struct { - Request *http.Request - PerPageNums int - MaxPages int - - nums int64 - pageRange []int - pageNums int - page int -} - -// PageNums Returns the total number of pages. -func (p *Paginator) PageNums() int { - if p.pageNums != 0 { - return p.pageNums - } - pageNums := math.Ceil(float64(p.nums) / float64(p.PerPageNums)) - if p.MaxPages > 0 { - pageNums = math.Min(pageNums, float64(p.MaxPages)) - } - p.pageNums = int(pageNums) - return p.pageNums -} - -// Nums Returns the total number of items (e.g. from doing SQL count). -func (p *Paginator) Nums() int64 { - return p.nums -} - -// SetNums Sets the total number of items. -func (p *Paginator) SetNums(nums interface{}) { - p.nums, _ = toInt64(nums) -} - -// Page Returns the current page. -func (p *Paginator) Page() int { - if p.page != 0 { - return p.page - } - if p.Request.Form == nil { - p.Request.ParseForm() - } - p.page, _ = strconv.Atoi(p.Request.Form.Get("p")) - if p.page > p.PageNums() { - p.page = p.PageNums() - } - if p.page <= 0 { - p.page = 1 - } - return p.page -} - -// Pages Returns a list of all pages. -// -// Usage (in a view template): -// -// {{range $index, $page := .paginator.Pages}} -// -// {{$page}} -// -// {{end}} -func (p *Paginator) Pages() []int { - if p.pageRange == nil && p.nums > 0 { - var pages []int - pageNums := p.PageNums() - page := p.Page() - switch { - case page >= pageNums-4 && pageNums > 9: - start := pageNums - 9 + 1 - pages = make([]int, 9) - for i := range pages { - pages[i] = start + i - } - case page >= 5 && pageNums > 9: - start := page - 5 + 1 - pages = make([]int, int(math.Min(9, float64(page+4+1)))) - for i := range pages { - pages[i] = start + i - } - default: - pages = make([]int, int(math.Min(9, float64(pageNums)))) - for i := range pages { - pages[i] = i + 1 - } - } - p.pageRange = pages - } - return p.pageRange -} - -// PageLink Returns URL for a given page index. -func (p *Paginator) PageLink(page int) string { - link, _ := url.ParseRequestURI(p.Request.URL.String()) - values := link.Query() - if page == 1 { - values.Del("p") - } else { - values.Set("p", strconv.Itoa(page)) - } - link.RawQuery = values.Encode() - return link.String() -} - -// PageLinkPrev Returns URL to the previous page. -func (p *Paginator) PageLinkPrev() (link string) { - if p.HasPrev() { - link = p.PageLink(p.Page() - 1) - } - return -} - -// PageLinkNext Returns URL to the next page. -func (p *Paginator) PageLinkNext() (link string) { - if p.HasNext() { - link = p.PageLink(p.Page() + 1) - } - return -} - -// PageLinkFirst Returns URL to the first page. -func (p *Paginator) PageLinkFirst() (link string) { - return p.PageLink(1) -} - -// PageLinkLast Returns URL to the last page. -func (p *Paginator) PageLinkLast() (link string) { - return p.PageLink(p.PageNums()) -} - -// HasPrev Returns true if the current page has a predecessor. -func (p *Paginator) HasPrev() bool { - return p.Page() > 1 -} - -// HasNext Returns true if the current page has a successor. -func (p *Paginator) HasNext() bool { - return p.Page() < p.PageNums() -} - -// IsActive Returns true if the given page index points to the current page. -func (p *Paginator) IsActive(page int) bool { - return p.Page() == page -} - -// Offset Returns the current offset. -func (p *Paginator) Offset() int { - return (p.Page() - 1) * p.PerPageNums -} - -// HasPages Returns true if there is more than one page. -func (p *Paginator) HasPages() bool { - return p.PageNums() > 1 -} - -// NewPaginator Instantiates a paginator struct for the current http request. -func NewPaginator(req *http.Request, per int, nums interface{}) *Paginator { - p := Paginator{} - p.Request = req - if per <= 0 { - per = 10 - } - p.PerPageNums = per - p.SetNums(nums) - return &p -} diff --git a/vendor/github.com/astaxie/beego/utils/pagination/utils.go b/vendor/github.com/astaxie/beego/utils/pagination/utils.go deleted file mode 100644 index 686e68b0d..000000000 --- a/vendor/github.com/astaxie/beego/utils/pagination/utils.go +++ /dev/null @@ -1,34 +0,0 @@ -// 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 pagination - -import ( - "fmt" - "reflect" -) - -// ToInt64 convert any numeric value to int64 -func toInt64(value interface{}) (d int64, err error) { - val := reflect.ValueOf(value) - switch value.(type) { - case int, int8, int16, int32, int64: - d = val.Int() - case uint, uint8, uint16, uint32, uint64: - d = int64(val.Uint()) - default: - err = fmt.Errorf("ToInt64 need numeric not `%T`", value) - } - return -} diff --git a/vendor/github.com/astaxie/beego/validation/validators.go b/vendor/github.com/astaxie/beego/validation/validators.go index ebff2191a..9b04c5cef 100644 --- a/vendor/github.com/astaxie/beego/validation/validators.go +++ b/vendor/github.com/astaxie/beego/validation/validators.go @@ -588,7 +588,7 @@ func (b Base64) GetLimitValue() interface{} { } // just for chinese mobile phone number -var mobilePattern = regexp.MustCompile("^((\\+86)|(86))?(1(([35][0-9])|[8][0-9]|[7][0679]|[4][579]))\\d{8}$") +var mobilePattern = regexp.MustCompile("^((\\+86)|(86))?(1(([35][0-9])|[8][0-9]|[7][06789]|[4][579]))\\d{8}$") // Mobile check struct type Mobile struct { diff --git a/vendor/vendor.json b/vendor/vendor.json new file mode 100644 index 000000000..66393f61c --- /dev/null +++ b/vendor/vendor.json @@ -0,0 +1,89 @@ +{ + "comment": "", + "ignore": "test", + "package": [ + { + "checksumSHA1": "G0MBhApkgOH9++JlIA8FPfU7j9Y=", + "path": "github.com/astaxie/beego", + "revision": "1aeb3d90512734def678c7aa9f612fe6f659e6b5", + "revisionTime": "2016-03-11T03:35:24Z", + "version": "v1.6.1", + "versionExact": "v1.6.1" + }, + { + "checksumSHA1": "gSSu0SO0GZIZrBgQpybXeNMWSJs=", + "path": "github.com/astaxie/beego/cache", + "revision": "88c5dfa6ead42e624c2e7d9e04eab6cb2d07412a", + "revisionTime": "2016-03-23T09:05:40Z" + }, + { + "checksumSHA1": "raJhf500jq7AzIGIclRQBo0B5+s=", + "path": "github.com/astaxie/beego/config", + "revision": "1aeb3d90512734def678c7aa9f612fe6f659e6b5", + "revisionTime": "2016-03-11T03:35:24Z", + "version": "v1.6.1", + "versionExact": "v1.6.1" + }, + { + "checksumSHA1": "52Cnm/rmogm6vPa2jW9D6SuKm3g=", + "path": "github.com/astaxie/beego/context", + "revision": "1aeb3d90512734def678c7aa9f612fe6f659e6b5", + "revisionTime": "2016-03-11T03:35:24Z", + "version": "v1.6.1", + "versionExact": "v1.6.1" + }, + { + "checksumSHA1": "PDNn16w89zWODshT9zlPzSmWZFA=", + "path": "github.com/astaxie/beego/grace", + "revision": "1aeb3d90512734def678c7aa9f612fe6f659e6b5", + "revisionTime": "2016-03-11T03:35:24Z", + "version": "v1.6.1", + "versionExact": "v1.6.1" + }, + { + "checksumSHA1": "xxtx4xJs8UcrvaXNQ9A5QM9+oFg=", + "path": "github.com/astaxie/beego/logs", + "revision": "1aeb3d90512734def678c7aa9f612fe6f659e6b5", + "revisionTime": "2016-03-11T03:35:24Z", + "version": "v1.6.1", + "versionExact": "v1.6.1" + }, + { + "checksumSHA1": "4X7wg7DBwdaRW4W2dBf3U0+fTHc=", + "path": "github.com/astaxie/beego/orm", + "revision": "88c5dfa6ead42e624c2e7d9e04eab6cb2d07412a", + "revisionTime": "2016-03-23T09:05:40Z" + }, + { + "checksumSHA1": "Zeh58fFq41Ym/YNH47O6gdm1Mh8=", + "path": "github.com/astaxie/beego/session", + "revision": "1aeb3d90512734def678c7aa9f612fe6f659e6b5", + "revisionTime": "2016-03-11T03:35:24Z", + "version": "v1.6.1", + "versionExact": "v1.6.1" + }, + { + "checksumSHA1": "Mu2lA5Jq0tRk9MjhWllyzcJD6KU=", + "path": "github.com/astaxie/beego/toolbox", + "revision": "1aeb3d90512734def678c7aa9f612fe6f659e6b5", + "revisionTime": "2016-03-11T03:35:24Z", + "version": "v1.6.1", + "versionExact": "v1.6.1" + }, + { + "checksumSHA1": "x90ZIgNp0dy/saCS+4tBR3gdQ6g=", + "path": "github.com/astaxie/beego/utils", + "revision": "1aeb3d90512734def678c7aa9f612fe6f659e6b5", + "revisionTime": "2016-03-11T03:35:24Z", + "version": "v1.6.1", + "versionExact": "v1.6.1" + }, + { + "checksumSHA1": "pt/trdXvFa8AvhR67iMhfvqNfDU=", + "path": "github.com/astaxie/beego/validation", + "revision": "88c5dfa6ead42e624c2e7d9e04eab6cb2d07412a", + "revisionTime": "2016-03-23T09:05:40Z" + } + ], + "rootPath": "github.com/vmware/harbor" +}