From 0d77a3f8d2d4b7f27169d2652ca3da9b9c9e94db Mon Sep 17 00:00:00 2001 From: DennisMao Date: Thu, 6 Dec 2018 10:49:50 +0800 Subject: [PATCH 01/80] FixOrmDescrptionTag --- orm/models_info_f.go | 2 +- orm/models_utils.go | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/orm/models_info_f.go b/orm/models_info_f.go index 479f5ae6..7044b0bd 100644 --- a/orm/models_info_f.go +++ b/orm/models_info_f.go @@ -301,7 +301,7 @@ checkType: fi.sf = sf fi.fullName = mi.fullName + mName + "." + sf.Name - fi.description = sf.Tag.Get("description") + fi.description = tags["description"] fi.null = attrs["null"] fi.index = attrs["index"] fi.auto = attrs["auto"] diff --git a/orm/models_utils.go b/orm/models_utils.go index 31f8fb5a..8faa7683 100644 --- a/orm/models_utils.go +++ b/orm/models_utils.go @@ -44,6 +44,7 @@ var supportTag = map[string]int{ "decimals": 2, "on_delete": 2, "type": 2, + "description": 2, } // get reflect.Type name with package path. From bf468c8d0c75364947225be7f100f6611dec327d Mon Sep 17 00:00:00 2001 From: DennisMao Date: Thu, 6 Dec 2018 10:57:32 +0800 Subject: [PATCH 02/80] fix format --- orm/models_utils.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/orm/models_utils.go b/orm/models_utils.go index 8faa7683..13a22aca 100644 --- a/orm/models_utils.go +++ b/orm/models_utils.go @@ -44,7 +44,7 @@ var supportTag = map[string]int{ "decimals": 2, "on_delete": 2, "type": 2, - "description": 2, + "description": 2, } // get reflect.Type name with package path. From 5e4241fc875385899a24641a258e9a278810f339 Mon Sep 17 00:00:00 2001 From: zav8 Date: Thu, 6 Dec 2018 16:07:07 +0800 Subject: [PATCH 03/80] add support for field of type sql.NullXxx in rawSet.setFieldValue() --- orm/orm_raw.go | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/orm/orm_raw.go b/orm/orm_raw.go index c8ef4398..08efa4e5 100644 --- a/orm/orm_raw.go +++ b/orm/orm_raw.go @@ -150,8 +150,10 @@ func (o *rawSet) setFieldValue(ind reflect.Value, value interface{}) { case reflect.Struct: if value == nil { ind.Set(reflect.Zero(ind.Type())) - - } else if _, ok := ind.Interface().(time.Time); ok { + return + } + switch indi := ind.Interface().(type) { + case time.Time: var str string switch d := value.(type) { case time.Time: @@ -178,6 +180,26 @@ func (o *rawSet) setFieldValue(ind reflect.Value, value interface{}) { } } } + case sql.NullString: + err := indi.Scan(value) + if err == nil { + ind.Set(reflect.ValueOf(indi)) + } + case sql.NullInt64: + err := indi.Scan(value) + if err == nil { + ind.Set(reflect.ValueOf(indi)) + } + case sql.NullFloat64: + err := indi.Scan(value) + if err == nil { + ind.Set(reflect.ValueOf(indi)) + } + case sql.NullBool: + err := indi.Scan(value) + if err == nil { + ind.Set(reflect.ValueOf(indi)) + } } } } From 6da4a66c20b284e78d4508013310f0872ae81eb8 Mon Sep 17 00:00:00 2001 From: zav8 Date: Thu, 6 Dec 2018 16:09:39 +0800 Subject: [PATCH 04/80] merge switch cases --- orm/orm_raw.go | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/orm/orm_raw.go b/orm/orm_raw.go index 08efa4e5..27651fe4 100644 --- a/orm/orm_raw.go +++ b/orm/orm_raw.go @@ -152,7 +152,7 @@ func (o *rawSet) setFieldValue(ind reflect.Value, value interface{}) { ind.Set(reflect.Zero(ind.Type())) return } - switch indi := ind.Interface().(type) { + switch ind.Interface().(type) { case time.Time: var str string switch d := value.(type) { @@ -180,25 +180,15 @@ func (o *rawSet) setFieldValue(ind reflect.Value, value interface{}) { } } } - case sql.NullString: - err := indi.Scan(value) - if err == nil { - ind.Set(reflect.ValueOf(indi)) + case sql.NullString, sql.NullInt64, sql.NullFloat64, sql.NullBool: + indi := reflect.New(ind.Type()).Interface() + sc, ok := indi.(sql.Scanner) + if !ok { + return } - case sql.NullInt64: - err := indi.Scan(value) + err := sc.Scan(value) if err == nil { - ind.Set(reflect.ValueOf(indi)) - } - case sql.NullFloat64: - err := indi.Scan(value) - if err == nil { - ind.Set(reflect.ValueOf(indi)) - } - case sql.NullBool: - err := indi.Scan(value) - if err == nil { - ind.Set(reflect.ValueOf(indi)) + ind.Set(reflect.Indirect(reflect.ValueOf(sc))) } } } From f03a7d11288879aa8b394f8dd5afbb08b30087f9 Mon Sep 17 00:00:00 2001 From: Chance Date: Thu, 13 Dec 2018 15:37:19 +0800 Subject: [PATCH 05/80] add GetProvider --- session/session.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/session/session.go b/session/session.go index c7e7dc69..46a9f1f0 100644 --- a/session/session.go +++ b/session/session.go @@ -81,6 +81,15 @@ func Register(name string, provide Provider) { provides[name] = provide } +//GetProvider +func GetProvider(name string) (Provider, error) { + provider, ok := provides[name] + if !ok { + return nil, fmt.Errorf("session: unknown provide %q (forgotten import?)", name) + } + return provider, nil +} + // ManagerConfig define the session config type ManagerConfig struct { CookieName string `json:"cookieName"` From c8f22be6750371ce1396f4357873da8dc9f030f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=83=AD=E4=B8=80=E9=B8=A3?= <281499083@qq.com> Date: Mon, 17 Dec 2018 21:47:47 +0800 Subject: [PATCH 06/80] Add redis sentinel session support (#3427) Add Redis Sentinel session support --- session/redis_sentinel/sess_redis_sentinel.go | 234 ++++++++++++++++++ .../sess_redis_sentinel_test.go | 84 +++++++ 2 files changed, 318 insertions(+) create mode 100644 session/redis_sentinel/sess_redis_sentinel.go create mode 100644 session/redis_sentinel/sess_redis_sentinel_test.go diff --git a/session/redis_sentinel/sess_redis_sentinel.go b/session/redis_sentinel/sess_redis_sentinel.go new file mode 100644 index 00000000..6ecb2977 --- /dev/null +++ b/session/redis_sentinel/sess_redis_sentinel.go @@ -0,0 +1,234 @@ +// 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/go-redis/redis +// +// go install github.com/go-redis/redis +// +// Usage: +// import( +// _ "github.com/astaxie/beego/session/redis_sentinel" +// "github.com/astaxie/beego/session" +// ) +// +// func init() { +// globalSessions, _ = session.NewManager("redis_sentinel", ``{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"127.0.0.1:26379;127.0.0.2:26379"}``) +// go globalSessions.GC() +// } +// +// more detail about params: please check the notes on the function SessionInit in this package +package redis_sentinel + +import ( + "github.com/astaxie/beego/session" + "github.com/go-redis/redis" + "net/http" + "strconv" + "strings" + "sync" + "time" +) + +var redispder = &Provider{} + +// DefaultPoolSize redis_sentinel default pool size +var DefaultPoolSize = 100 + +// SessionStore redis_sentinel session store +type SessionStore struct { + p *redis.Client + sid string + lock sync.RWMutex + values map[interface{}]interface{} + maxlifetime int64 +} + +// Set value in redis_sentinel 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_sentinel 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_sentinel 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_sentinel session +func (rs *SessionStore) Flush() error { + rs.lock.Lock() + defer rs.lock.Unlock() + rs.values = make(map[interface{}]interface{}) + return nil +} + +// SessionID get redis_sentinel session id +func (rs *SessionStore) SessionID() string { + return rs.sid +} + +// SessionRelease save session values to redis_sentinel +func (rs *SessionStore) SessionRelease(w http.ResponseWriter) { + b, err := session.EncodeGob(rs.values) + if err != nil { + return + } + c := rs.p + c.Set(rs.sid, string(b), time.Duration(rs.maxlifetime)*time.Second) +} + +// Provider redis_sentinel session provider +type Provider struct { + maxlifetime int64 + savePath string + poolsize int + password string + dbNum int + poollist *redis.Client + masterName string +} + +// SessionInit init redis_sentinel session +// savepath like redis sentinel addr,pool size,password,dbnum,masterName +// e.g. 127.0.0.1:26379;127.0.0.2:26379,100,1qaz2wsx,0,mymaster +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 = DefaultPoolSize + } else { + rp.poolsize = poolsize + } + } else { + rp.poolsize = DefaultPoolSize + } + 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 + } + if len(configs) > 4 { + if configs[4] != "" { + rp.masterName = configs[4] + } else { + rp.masterName = "mymaster" + } + } else { + rp.masterName = "mymaster" + } + + rp.poollist = redis.NewFailoverClient(&redis.FailoverOptions{ + SentinelAddrs: strings.Split(rp.savePath, ";"), + Password: rp.password, + PoolSize: rp.poolsize, + DB: rp.dbNum, + MasterName: rp.masterName, + }) + + return rp.poollist.Ping().Err() +} + +// SessionRead read redis_sentinel session by sid +func (rp *Provider) SessionRead(sid string) (session.Store, error) { + var kv map[interface{}]interface{} + kvs, err := rp.poollist.Get(sid).Result() + if err != nil && err != redis.Nil { + return nil, err + } + if len(kvs) == 0 { + kv = make(map[interface{}]interface{}) + } else { + if kv, err = session.DecodeGob([]byte(kvs)); err != nil { + return nil, err + } + } + + rs := &SessionStore{p: rp.poollist, sid: sid, values: kv, maxlifetime: rp.maxlifetime} + return rs, nil +} + +// SessionExist check redis_sentinel session exist by sid +func (rp *Provider) SessionExist(sid string) bool { + c := rp.poollist + if existed, err := c.Exists(sid).Result(); err != nil || existed == 0 { + return false + } + return true +} + +// SessionRegenerate generate new sid for redis_sentinel session +func (rp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error) { + c := rp.poollist + + if existed, err := c.Exists(oldsid).Result(); err != nil || 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.Set(sid, "", time.Duration(rp.maxlifetime)*time.Second) + } else { + c.Rename(oldsid, sid) + c.Expire(sid, time.Duration(rp.maxlifetime)*time.Second) + } + return rp.SessionRead(sid) +} + +// SessionDestroy delete redis session by id +func (rp *Provider) SessionDestroy(sid string) error { + c := rp.poollist + c.Del(sid) + return nil +} + +// SessionGC Impelment method, no used. +func (rp *Provider) SessionGC() { +} + +// SessionAll return all activeSession +func (rp *Provider) SessionAll() int { + return 0 +} + +func init() { + session.Register("redis_sentinel", redispder) +} diff --git a/session/redis_sentinel/sess_redis_sentinel_test.go b/session/redis_sentinel/sess_redis_sentinel_test.go new file mode 100644 index 00000000..851fe804 --- /dev/null +++ b/session/redis_sentinel/sess_redis_sentinel_test.go @@ -0,0 +1,84 @@ +package redis_sentinel + +import ( + "github.com/astaxie/beego/session" + "net/http" + "net/http/httptest" + "testing" +) + +func TestRedisSentinel(t *testing.T) { + sessionConfig := &session.ManagerConfig{ + CookieName: "gosessionid", + EnableSetCookie: true, + Gclifetime: 3600, + Maxlifetime: 3600, + Secure: false, + CookieLifeTime: 3600, + ProviderConfig: "119.23.132.234:26379,100,,0,master", + } + globalSessions, _ := session.NewManager("redis_sentinel", sessionConfig) + go globalSessions.GC() + + r, _ := http.NewRequest("GET", "/", nil) + w := httptest.NewRecorder() + + sess, err := globalSessions.SessionStart(w, r) + if err != nil { + t.Fatal("session start failed:", err) + } + defer sess.SessionRelease(w) + + // SET AND GET + err = sess.Set("username", "astaxie") + if err != nil { + t.Fatal("set username failed:", err) + } + username := sess.Get("username") + if username != "astaxie" { + t.Fatal("get username failed") + } + + // DELETE + err = sess.Delete("username") + if err != nil { + t.Fatal("delete username failed:", err) + } + username = sess.Get("username") + if username != nil { + t.Fatal("delete username failed") + } + + // FLUSH + err = sess.Set("username", "astaxie") + if err != nil { + t.Fatal("set failed:", err) + } + err = sess.Set("password", "1qaz2wsx") + if err != nil { + t.Fatal("set failed:", err) + } + username = sess.Get("username") + if username != "astaxie" { + t.Fatal("get username failed") + } + password := sess.Get("password") + if password != "1qaz2wsx" { + t.Fatal("get password failed") + } + err = sess.Flush() + if err != nil { + t.Fatal("flush failed:", err) + } + username = sess.Get("username") + if username != nil { + t.Fatal("flush failed") + } + password = sess.Get("password") + if password != nil { + t.Fatal("flush failed") + } + + sess.SessionRelease(w) + +} From d2c289193ab2dfb5c981f3da66f6adb2eefa10b6 Mon Sep 17 00:00:00 2001 From: zav8 Date: Tue, 18 Dec 2018 10:37:41 +0800 Subject: [PATCH 07/80] add test case for QueryRow and QueryRows --- orm/orm_test.go | 51 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/orm/orm_test.go b/orm/orm_test.go index 89a714b6..4f499a7c 100644 --- a/orm/orm_test.go +++ b/orm/orm_test.go @@ -1679,6 +1679,31 @@ func TestRawQueryRow(t *testing.T) { throwFail(t, AssertIs(uid, 4)) throwFail(t, AssertIs(*status, 3)) throwFail(t, AssertIs(pid, nil)) + + // test for sql.Null* fields + nData := &DataNull{ + NullString: sql.NullString{String: "test sql.null", Valid: true}, + NullBool: sql.NullBool{Bool: true, Valid: true}, + NullInt64: sql.NullInt64{Int64: 42, Valid: true}, + NullFloat64: sql.NullFloat64{Float64: 42.42, Valid: true}, + } + newId, err := dORM.Insert(nData) + throwFailNow(t, err) + + var nd *DataNull + query = fmt.Sprintf("SELECT * FROM %sdata_null%s where id=?", Q, Q) + err = dORM.Raw(query, newId).QueryRow(&nd) + throwFailNow(t, err) + + throwFailNow(t, AssertNot(nd, nil)) + throwFail(t, AssertIs(nd.NullBool.Valid, true)) + throwFail(t, AssertIs(nd.NullBool.Bool, true)) + throwFail(t, AssertIs(nd.NullString.Valid, true)) + throwFail(t, AssertIs(nd.NullString.String, "test sql.null")) + throwFail(t, AssertIs(nd.NullInt64.Valid, true)) + throwFail(t, AssertIs(nd.NullInt64.Int64, 42)) + throwFail(t, AssertIs(nd.NullFloat64.Valid, true)) + throwFail(t, AssertIs(nd.NullFloat64.Float64, 42.42)) } // user_profile table @@ -1771,6 +1796,32 @@ func TestQueryRows(t *testing.T) { throwFailNow(t, AssertIs(l[1].UserName, "astaxie")) throwFailNow(t, AssertIs(l[1].Age, 30)) + // test for sql.Null* fields + nData := &DataNull{ + NullString: sql.NullString{String: "test sql.null", Valid: true}, + NullBool: sql.NullBool{Bool: true, Valid: true}, + NullInt64: sql.NullInt64{Int64: 42, Valid: true}, + NullFloat64: sql.NullFloat64{Float64: 42.42, Valid: true}, + } + newId, err := dORM.Insert(nData) + throwFailNow(t, err) + + var nDataList []*DataNull + query = fmt.Sprintf("SELECT * FROM %sdata_null%s where id=?", Q, Q) + num, err = dORM.Raw(query, newId).QueryRows(&nDataList) + throwFailNow(t, err) + throwFailNow(t, AssertIs(num, 1)) + + nd := nDataList[0] + throwFailNow(t, AssertNot(nd, nil)) + throwFail(t, AssertIs(nd.NullBool.Valid, true)) + throwFail(t, AssertIs(nd.NullBool.Bool, true)) + throwFail(t, AssertIs(nd.NullString.Valid, true)) + throwFail(t, AssertIs(nd.NullString.String, "test sql.null")) + throwFail(t, AssertIs(nd.NullInt64.Valid, true)) + throwFail(t, AssertIs(nd.NullInt64.Int64, 42)) + throwFail(t, AssertIs(nd.NullFloat64.Valid, true)) + throwFail(t, AssertIs(nd.NullFloat64.Float64, 42.42)) } func TestRawValues(t *testing.T) { From 1dea80d4ea05fd88c97119c7fdfb38565506b93e Mon Sep 17 00:00:00 2001 From: James Pettyjohn Date: Sun, 13 Aug 2017 14:09:42 -0700 Subject: [PATCH 08/80] Fixed error handling in memcache sessions --- session/memcache/sess_memcache.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/session/memcache/sess_memcache.go b/session/memcache/sess_memcache.go index 755979c4..85a2d815 100644 --- a/session/memcache/sess_memcache.go +++ b/session/memcache/sess_memcache.go @@ -128,9 +128,12 @@ func (rp *MemProvider) SessionRead(sid string) (session.Store, error) { } } 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 + if err != nil { + if err == memcache.ErrCacheMiss { + rs := &SessionStore{sid: sid, values: make(map[interface{}]interface{}), maxlifetime: rp.maxlifetime} + return rs, nil + } + return nil, err } var kv map[interface{}]interface{} if len(item.Value) == 0 { From 2034d1b10118feb633615ab4cd594a161bea263d Mon Sep 17 00:00:00 2001 From: zhl11b Date: Sat, 29 Dec 2018 17:41:59 +0800 Subject: [PATCH 09/80] =?UTF-8?q?=E8=81=94=E9=80=9A171=EF=BC=8C175=20?= =?UTF-8?q?=E7=94=B5=E4=BF=A1173?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- validation/validators.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/validation/validators.go b/validation/validators.go index 4dff9c0b..dc18b11e 100644 --- a/validation/validators.go +++ b/validation/validators.go @@ -632,7 +632,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][06789]|[4][579]))\d{8}$`) +var mobilePattern = regexp.MustCompile(`^((\+86)|(86))?(1(([35][0-9])|[8][0-9]|[7][01356789]|[4][579]))\d{8}$`) // Mobile check struct type Mobile struct { From d02699a189c1874442752ada8d3bd232e672063b Mon Sep 17 00:00:00 2001 From: zhl11b Date: Sun, 30 Dec 2018 20:51:21 +0800 Subject: [PATCH 10/80] add new test case for china mobile phone --- validation/validation_test.go | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/validation/validation_test.go b/validation/validation_test.go index f97105fd..3146766b 100644 --- a/validation/validation_test.go +++ b/validation/validation_test.go @@ -268,6 +268,18 @@ func TestMobile(t *testing.T) { if !valid.Mobile("+8614700008888", "mobile").Ok { t.Error("\"+8614700008888\" is a valid mobile phone number should be true") } + if !valid.Mobile("17300008888", "mobile").Ok { + t.Error("\"17300008888\" is a valid mobile phone number should be true") + } + if !valid.Mobile("+8617100008888", "mobile").Ok { + t.Error("\"+8617100008888\" is a valid mobile phone number should be true") + } + if !valid.Mobile("8617500008888", "mobile").Ok { + t.Error("\"8617500008888\" is a valid mobile phone number should be true") + } + if valid.Mobile("8617400008888", "mobile").Ok { + t.Error("\"8617400008888\" is a valid mobile phone number should be false") + } } func TestTel(t *testing.T) { @@ -453,7 +465,7 @@ func TestPointer(t *testing.T) { u := User{ ReqEmail: nil, - Email: nil, + Email: nil, } valid := Validation{} @@ -468,7 +480,7 @@ func TestPointer(t *testing.T) { validEmail := "a@a.com" u = User{ ReqEmail: &validEmail, - Email: nil, + Email: nil, } valid = Validation{RequiredFirst: true} @@ -482,7 +494,7 @@ func TestPointer(t *testing.T) { u = User{ ReqEmail: &validEmail, - Email: nil, + Email: nil, } valid = Validation{} @@ -497,7 +509,7 @@ func TestPointer(t *testing.T) { invalidEmail := "a@a" u = User{ ReqEmail: &validEmail, - Email: &invalidEmail, + Email: &invalidEmail, } valid = Validation{RequiredFirst: true} @@ -511,7 +523,7 @@ func TestPointer(t *testing.T) { u = User{ ReqEmail: &validEmail, - Email: &invalidEmail, + Email: &invalidEmail, } valid = Validation{} @@ -524,19 +536,18 @@ func TestPointer(t *testing.T) { } } - func TestCanSkipAlso(t *testing.T) { type User struct { ID int - Email string `valid:"Email"` - ReqEmail string `valid:"Required;Email"` - MatchRange int `valid:"Range(10, 20)"` + Email string `valid:"Email"` + ReqEmail string `valid:"Required;Email"` + MatchRange int `valid:"Range(10, 20)"` } u := User{ - ReqEmail: "a@a.com", - Email: "", + ReqEmail: "a@a.com", + Email: "", MatchRange: 0, } @@ -560,4 +571,3 @@ func TestCanSkipAlso(t *testing.T) { } } - From 24215fb3eb134a4abf88d9b6fd2cc893bf550712 Mon Sep 17 00:00:00 2001 From: DennisMao Date: Wed, 2 Jan 2019 15:37:41 +0800 Subject: [PATCH 11/80] update dependency --- go.mod | 2 +- logs/es/es.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 9b3eb08e..a7e1194b 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ require ( github.com/Knetic/govaluate v3.0.0+incompatible // indirect github.com/beego/goyaml2 v0.0.0-20130207012346-5545475820dd github.com/beego/x2j v0.0.0-20131220205130-a0352aadc542 - github.com/belogik/goes v0.0.0-20151229125003-e54d722c3aff + github.com/OwnLocal/goes v1.0.0 github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737 github.com/casbin/casbin v1.7.0 github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58 diff --git a/logs/es/es.go b/logs/es/es.go index 22f4f650..9c0b830d 100644 --- a/logs/es/es.go +++ b/logs/es/es.go @@ -9,7 +9,7 @@ import ( "time" "github.com/astaxie/beego/logs" - "github.com/belogik/goes" + "github.com/OwnLocal/goes" ) // NewES return a LoggerInterface From 6e16b8cdcfec27bca8e7b62211381953e9a4bfde Mon Sep 17 00:00:00 2001 From: DennisMao Date: Wed, 2 Jan 2019 16:46:27 +0800 Subject: [PATCH 12/80] fix ci losing dependency --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index ed04c9d1..97fc317b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,6 +35,7 @@ install: - go get github.com/Knetic/govaluate - go get github.com/casbin/casbin - go get github.com/elazarl/go-bindata-assetfs + - go get github.com/OwnLocal/goes - go get -u honnef.co/go/tools/cmd/gosimple - go get -u github.com/mdempsky/unconvert - go get -u github.com/gordonklaus/ineffassign From edb1c52dee08d36a1ab7031647d94068f2c93533 Mon Sep 17 00:00:00 2001 From: DennisMao Date: Wed, 2 Jan 2019 17:01:46 +0800 Subject: [PATCH 13/80] fix function changes --- logs/es/es.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/logs/es/es.go b/logs/es/es.go index 9c0b830d..9d6a615c 100644 --- a/logs/es/es.go +++ b/logs/es/es.go @@ -8,8 +8,8 @@ import ( "net/url" "time" - "github.com/astaxie/beego/logs" "github.com/OwnLocal/goes" + "github.com/astaxie/beego/logs" ) // NewES return a LoggerInterface @@ -21,7 +21,7 @@ func NewES() logs.Logger { } type esLogger struct { - *goes.Connection + *goes.Client DSN string `json:"dsn"` Level int `json:"level"` } @@ -41,8 +41,8 @@ func (el *esLogger) Init(jsonconfig string) error { } else if host, port, err := net.SplitHostPort(u.Host); err != nil { return err } else { - conn := goes.NewConnection(host, port) - el.Connection = conn + conn := goes.NewClient(host, port) + el.Client = conn } return nil } @@ -78,3 +78,4 @@ func (el *esLogger) Flush() { func init() { logs.Register(logs.AdapterEs, NewES) } + From bf15535a5bf5783b53e6764268dd1554cde3608e Mon Sep 17 00:00:00 2001 From: sanghee Date: Thu, 3 Jan 2019 22:44:32 +0900 Subject: [PATCH 14/80] fix panic: sync: negative WaitGroup counter --- grace/conn.go | 3 +-- grace/server.go | 5 +++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/grace/conn.go b/grace/conn.go index e020f850..32623650 100644 --- a/grace/conn.go +++ b/grace/conn.go @@ -28,12 +28,11 @@ func (c *graceConn) Close() (err error) { }() c.m.Lock() + defer c.m.Unlock() if c.closed { - c.m.Unlock() return } c.server.wg.Done() c.closed = true - c.m.Unlock() return c.Conn.Close() } diff --git a/grace/server.go b/grace/server.go index 513a52a9..ef5cbe7e 100644 --- a/grace/server.go +++ b/grace/server.go @@ -34,6 +34,11 @@ type Server struct { // creating a new service goroutine for each. // The service goroutines read requests and then call srv.Handler to reply to them. func (srv *Server) Serve() (err error) { + defer func() { + if r := recover(); r != nil { + log.Println("wait group counter is negative", r) + } + }() srv.state = StateRunning err = srv.Server.Serve(srv.GraceListener) log.Println(syscall.Getpid(), "Waiting for connections to finish...") From d792536c23a25f98fb6e5c54de3e6cc111c466ed Mon Sep 17 00:00:00 2001 From: duyazhe Date: Mon, 14 Jan 2019 15:14:11 +0800 Subject: [PATCH 15/80] Update orm_log.go MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit orm log支持用户自定义函数处理 --- orm/orm_log.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/orm/orm_log.go b/orm/orm_log.go index 2a879c13..f107bb59 100644 --- a/orm/orm_log.go +++ b/orm/orm_log.go @@ -29,6 +29,9 @@ type Log struct { *log.Logger } +//costomer log func +var LogFunc func(query map[string]interface{}) + // NewLog set io.Writer to create a Logger. func NewLog(out io.Writer) *Log { d := new(Log) @@ -37,12 +40,15 @@ func NewLog(out io.Writer) *Log { } func debugLogQueies(alias *alias, operaton, query string, t time.Time, err error, args ...interface{}) { + var logMap = make(map[string]interface{}) sub := time.Now().Sub(t) / 1e5 elsp := float64(int(sub)) / 10.0 + logMap["cost_time"] = elsp flag := " OK" if err != nil { flag = "FAIL" } + logMap["flag"] = flag con := fmt.Sprintf(" -[Queries/%s] - [%s / %11s / %7.1fms] - [%s]", alias.Name, flag, operaton, elsp, query) cons := make([]string, 0, len(args)) for _, arg := range args { @@ -54,6 +60,10 @@ func debugLogQueies(alias *alias, operaton, query string, t time.Time, err error if err != nil { con += " - " + err.Error() } + logMap["sql"] = fmt.Sprintf("%s-`%s`", query, strings.Join(cons, "`, `")) + if LogFunc != nil{ + LogFunc(logMap) + } DebugLog.Println(con) } From 7173fd7490841746aa0ed254b81692117f892e54 Mon Sep 17 00:00:00 2001 From: nuczzz Date: Thu, 17 Jan 2019 20:17:57 +0800 Subject: [PATCH 16/80] modify http graceful --- grace/conn.go | 38 ------------------ grace/grace.go | 22 +++++------ grace/listener.go | 62 ------------------------------ grace/server.go | 98 ++++++++++++++++------------------------------- 4 files changed, 43 insertions(+), 177 deletions(-) delete mode 100644 grace/conn.go delete mode 100644 grace/listener.go diff --git a/grace/conn.go b/grace/conn.go deleted file mode 100644 index 32623650..00000000 --- a/grace/conn.go +++ /dev/null @@ -1,38 +0,0 @@ -package grace - -import ( - "errors" - "net" - "sync" -) - -type graceConn struct { - net.Conn - server *Server - m sync.Mutex - closed bool -} - -func (c *graceConn) Close() (err error) { - defer func() { - if r := recover(); r != nil { - switch x := r.(type) { - case string: - err = errors.New(x) - case error: - err = x - default: - err = errors.New("Unknown panic") - } - } - }() - - c.m.Lock() - defer c.m.Unlock() - if c.closed { - return - } - c.server.wg.Done() - c.closed = true - return c.Conn.Close() -} diff --git a/grace/grace.go b/grace/grace.go index 6ebf8455..5a8bc3b8 100644 --- a/grace/grace.go +++ b/grace/grace.go @@ -122,7 +122,6 @@ func NewServer(addr string, handler http.Handler) (srv *Server) { } srv = &Server{ - wg: sync.WaitGroup{}, sigChan: make(chan os.Signal), isChild: isChild, SignalHooks: map[int]map[os.Signal][]func(){ @@ -137,20 +136,21 @@ func NewServer(addr string, handler http.Handler) (srv *Server) { syscall.SIGTERM: {}, }, }, - state: StateInit, - Network: "tcp", + state: StateInit, + Network: "tcp", + terminalChan: make(chan error), //no cache channel + } + srv.Server = &http.Server{ + Addr: addr, + ReadTimeout: DefaultReadTimeOut, + WriteTimeout: DefaultWriteTimeOut, + MaxHeaderBytes: DefaultMaxHeaderBytes, + Handler: handler, } - srv.Server = &http.Server{} - srv.Server.Addr = addr - srv.Server.ReadTimeout = DefaultReadTimeOut - srv.Server.WriteTimeout = DefaultWriteTimeOut - srv.Server.MaxHeaderBytes = DefaultMaxHeaderBytes - srv.Server.Handler = handler runningServersOrder = append(runningServersOrder, addr) runningServers[addr] = srv - - return + return srv } // ListenAndServe refer http.ListenAndServe diff --git a/grace/listener.go b/grace/listener.go deleted file mode 100644 index 7ede63a3..00000000 --- a/grace/listener.go +++ /dev/null @@ -1,62 +0,0 @@ -package grace - -import ( - "net" - "os" - "syscall" - "time" -) - -type graceListener struct { - net.Listener - stop chan error - stopped bool - server *Server -} - -func newGraceListener(l net.Listener, srv *Server) (el *graceListener) { - el = &graceListener{ - Listener: l, - stop: make(chan error), - server: srv, - } - go func() { - <-el.stop - el.stopped = true - el.stop <- el.Listener.Close() - }() - return -} - -func (gl *graceListener) Accept() (c net.Conn, err error) { - tc, err := gl.Listener.(*net.TCPListener).AcceptTCP() - if err != nil { - return - } - - tc.SetKeepAlive(true) - tc.SetKeepAlivePeriod(3 * time.Minute) - - c = &graceConn{ - Conn: tc, - server: gl.server, - } - - gl.server.wg.Add(1) - return -} - -func (gl *graceListener) Close() error { - if gl.stopped { - return syscall.EINVAL - } - gl.stop <- nil - return <-gl.stop -} - -func (gl *graceListener) File() *os.File { - // returns a dup(2) - FD_CLOEXEC flag *not* set - tl := gl.Listener.(*net.TCPListener) - fl, _ := tl.File() - return fl -} diff --git a/grace/server.go b/grace/server.go index ef5cbe7e..ade05ef7 100644 --- a/grace/server.go +++ b/grace/server.go @@ -1,6 +1,7 @@ package grace import ( + "context" "crypto/tls" "crypto/x509" "fmt" @@ -12,39 +13,37 @@ import ( "os/exec" "os/signal" "strings" - "sync" "syscall" - "time" ) // Server embedded http.Server type Server struct { *http.Server - GraceListener net.Listener - SignalHooks map[int]map[os.Signal][]func() - tlsInnerListener *graceListener - wg sync.WaitGroup - sigChan chan os.Signal - isChild bool - state uint8 - Network string + ln net.Listener + SignalHooks map[int]map[os.Signal][]func() + sigChan chan os.Signal + isChild bool + state uint8 + Network string + terminalChan chan error } // Serve accepts incoming connections on the Listener l, // creating a new service goroutine for each. // The service goroutines read requests and then call srv.Handler to reply to them. func (srv *Server) Serve() (err error) { - defer func() { - if r := recover(); r != nil { - log.Println("wait group counter is negative", r) - } - }() srv.state = StateRunning - err = srv.Server.Serve(srv.GraceListener) - log.Println(syscall.Getpid(), "Waiting for connections to finish...") - srv.wg.Wait() - srv.state = StateTerminate - return + defer func() { srv.state = StateTerminate }() + + // When Shutdown is called, Serve, ListenAndServe, and ListenAndServeTLS + // immediately return ErrServerClosed. Make sure the program doesn't exit + // and waits instead for Shutdown to return. + if err = srv.Server.Serve(srv.ln); err != nil && err != http.ErrServerClosed { + return err + } + + // wait for Shutdown to return + return <-srv.terminalChan } // ListenAndServe listens on the TCP network address srv.Addr and then calls Serve @@ -58,14 +57,12 @@ func (srv *Server) ListenAndServe() (err error) { go srv.handleSignals() - l, err := srv.getListener(addr) + srv.ln, err = srv.getListener(addr) if err != nil { log.Println(err) return err } - srv.GraceListener = newGraceListener(l, srv) - if srv.isChild { process, err := os.FindProcess(os.Getppid()) if err != nil { @@ -112,14 +109,12 @@ func (srv *Server) ListenAndServeTLS(certFile, keyFile string) (err error) { go srv.handleSignals() - l, err := srv.getListener(addr) + ln, err := srv.getListener(addr) if err != nil { log.Println(err) return err } - - srv.tlsInnerListener = newGraceListener(l, srv) - srv.GraceListener = tls.NewListener(srv.tlsInnerListener, srv.TLSConfig) + srv.ln = tls.NewListener(ln, srv.TLSConfig) if srv.isChild { process, err := os.FindProcess(os.Getppid()) @@ -132,6 +127,7 @@ func (srv *Server) ListenAndServeTLS(certFile, keyFile string) (err error) { return err } } + log.Println(os.Getpid(), srv.Addr) return srv.Serve() } @@ -168,14 +164,12 @@ func (srv *Server) ListenAndServeMutualTLS(certFile, keyFile, trustFile string) log.Println("Mutual HTTPS") go srv.handleSignals() - l, err := srv.getListener(addr) + ln, err := srv.getListener(addr) if err != nil { log.Println(err) return err } - - srv.tlsInnerListener = newGraceListener(l, srv) - srv.GraceListener = tls.NewListener(srv.tlsInnerListener, srv.TLSConfig) + srv.ln = tls.NewListener(ln, srv.TLSConfig) if srv.isChild { process, err := os.FindProcess(os.Getppid()) @@ -188,6 +182,7 @@ func (srv *Server) ListenAndServeMutualTLS(certFile, keyFile, trustFile string) return err } } + log.Println(os.Getpid(), srv.Addr) return srv.Serve() } @@ -270,37 +265,12 @@ func (srv *Server) shutdown() { } srv.state = StateShuttingDown + log.Println(syscall.Getpid(), "Waiting for connections to finish...") + ctx := context.Background() if DefaultTimeout >= 0 { - go srv.serverTimeout(DefaultTimeout) - } - err := srv.GraceListener.Close() - if err != nil { - log.Println(syscall.Getpid(), "Listener.Close() error:", err) - } else { - log.Println(syscall.Getpid(), srv.GraceListener.Addr(), "Listener closed.") - } -} - -// serverTimeout forces the server to shutdown in a given timeout - whether it -// finished outstanding requests or not. if Read/WriteTimeout are not set or the -// max header size is very big a connection could hang -func (srv *Server) serverTimeout(d time.Duration) { - defer func() { - if r := recover(); r != nil { - log.Println("WaitGroup at 0", r) - } - }() - if srv.state != StateShuttingDown { - return - } - time.Sleep(d) - log.Println("[STOP - Hammer Time] Forcefully shutting down parent") - for { - if srv.state == StateTerminate { - break - } - srv.wg.Done() + ctx, _ = context.WithTimeout(context.Background(), DefaultTimeout) } + srv.terminalChan <- srv.Server.Shutdown(ctx) } func (srv *Server) fork() (err error) { @@ -314,12 +284,8 @@ func (srv *Server) fork() (err error) { var files = make([]*os.File, len(runningServers)) var orderArgs = make([]string, len(runningServers)) for _, srvPtr := range runningServers { - switch srvPtr.GraceListener.(type) { - case *graceListener: - files[socketPtrOffsetMap[srvPtr.Server.Addr]] = srvPtr.GraceListener.(*graceListener).File() - default: - files[socketPtrOffsetMap[srvPtr.Server.Addr]] = srvPtr.tlsInnerListener.File() - } + f, _ := srvPtr.ln.(*net.TCPListener).File() + files[socketPtrOffsetMap[srvPtr.Server.Addr]] = f orderArgs[socketPtrOffsetMap[srvPtr.Server.Addr]] = srvPtr.Server.Addr } From 2ae480556dc660ac3e9b9a5078568e7af7a5847a Mon Sep 17 00:00:00 2001 From: Bharat Patel Date: Thu, 17 Jan 2019 09:56:42 -0800 Subject: [PATCH 17/80] Add DBStats method wrapper to provide sql.DBStats when using ormer --- orm/orm.go | 5 +++++ orm/types.go | 1 + 2 files changed, 6 insertions(+) diff --git a/orm/orm.go b/orm/orm.go index bcf6e4be..b7296ab9 100644 --- a/orm/orm.go +++ b/orm/orm.go @@ -522,6 +522,11 @@ func (o *orm) Driver() Driver { return driver(o.alias.Name) } +// return sql.DBStats for current database +func (o *orm) DBStats() sql.DBStats { + return o.alias.DB.Stats() +} + // NewOrm create new orm func NewOrm() Ormer { BootStrap() // execute only once diff --git a/orm/types.go b/orm/types.go index ddf39a2b..4c67c7a6 100644 --- a/orm/types.go +++ b/orm/types.go @@ -128,6 +128,7 @@ type Ormer interface { // // update user testing's name to slene Raw(query string, args ...interface{}) RawSeter Driver() Driver + DBStats() sql.DBStats } // Inserter insert prepared statement From 313be996cd9ed3c4bc2647b6303d651c4b487fd3 Mon Sep 17 00:00:00 2001 From: nuczzz Date: Fri, 18 Jan 2019 19:33:45 +0800 Subject: [PATCH 18/80] call cancel after shutdown --- grace/server.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/grace/server.go b/grace/server.go index ade05ef7..ac3eefa7 100644 --- a/grace/server.go +++ b/grace/server.go @@ -268,7 +268,9 @@ func (srv *Server) shutdown() { log.Println(syscall.Getpid(), "Waiting for connections to finish...") ctx := context.Background() if DefaultTimeout >= 0 { - ctx, _ = context.WithTimeout(context.Background(), DefaultTimeout) + var cancel context.CancelFunc + ctx, cancel = context.WithTimeout(context.Background(), DefaultTimeout) + defer cancel() } srv.terminalChan <- srv.Server.Shutdown(ctx) } From e295c3c7c3f0bec6ed782d77cc55a49b5c31b4ec Mon Sep 17 00:00:00 2001 From: nuczzz Date: Fri, 18 Jan 2019 19:50:22 +0800 Subject: [PATCH 19/80] add shutdown log --- grace/server.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/grace/server.go b/grace/server.go index ac3eefa7..e5302baa 100644 --- a/grace/server.go +++ b/grace/server.go @@ -39,9 +39,11 @@ func (srv *Server) Serve() (err error) { // immediately return ErrServerClosed. Make sure the program doesn't exit // and waits instead for Shutdown to return. if err = srv.Server.Serve(srv.ln); err != nil && err != http.ErrServerClosed { + log.Println(syscall.Getpid(), "Server.Serve() error:", err) return err } + log.Println(syscall.Getpid(), srv.ln.Addr(), "Listener closed.") // wait for Shutdown to return return <-srv.terminalChan } From f508f8d959258ecfab3314f0183fc02be755f246 Mon Sep 17 00:00:00 2001 From: Bharat Patel Date: Fri, 18 Jan 2019 16:51:40 -0800 Subject: [PATCH 20/80] Nil check --- orm/orm.go | 9 +++++++-- orm/types.go | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/orm/orm.go b/orm/orm.go index b7296ab9..fc3cd400 100644 --- a/orm/orm.go +++ b/orm/orm.go @@ -523,8 +523,13 @@ func (o *orm) Driver() Driver { } // return sql.DBStats for current database -func (o *orm) DBStats() sql.DBStats { - return o.alias.DB.Stats() +func (o *orm) DBStats() *sql.DBStats { + if o.alias != nil && o.alias.DB != nil { + stats := o.alias.DB.Stats() + return &stats + } + + return nil } // NewOrm create new orm diff --git a/orm/types.go b/orm/types.go index 4c67c7a6..6c6443c7 100644 --- a/orm/types.go +++ b/orm/types.go @@ -128,7 +128,7 @@ type Ormer interface { // // update user testing's name to slene Raw(query string, args ...interface{}) RawSeter Driver() Driver - DBStats() sql.DBStats + DBStats() *sql.DBStats } // Inserter insert prepared statement From fe519bd2a054cd1da746d2d9b82843379c2067df Mon Sep 17 00:00:00 2001 From: nuczzz Date: Sun, 20 Jan 2019 11:17:10 +0800 Subject: [PATCH 21/80] update tls KeepAlive setting --- grace/server.go | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/grace/server.go b/grace/server.go index e5302baa..1ce8bc78 100644 --- a/grace/server.go +++ b/grace/server.go @@ -14,6 +14,7 @@ import ( "os/signal" "strings" "syscall" + "time" ) // Server embedded http.Server @@ -116,7 +117,7 @@ func (srv *Server) ListenAndServeTLS(certFile, keyFile string) (err error) { log.Println(err) return err } - srv.ln = tls.NewListener(ln, srv.TLSConfig) + srv.ln = tls.NewListener(tcpKeepAliveListener{ln.(*net.TCPListener)}, srv.TLSConfig) if srv.isChild { process, err := os.FindProcess(os.Getppid()) @@ -171,7 +172,7 @@ func (srv *Server) ListenAndServeMutualTLS(certFile, keyFile, trustFile string) log.Println(err) return err } - srv.ln = tls.NewListener(ln, srv.TLSConfig) + srv.ln = tls.NewListener(tcpKeepAliveListener{ln.(*net.TCPListener)}, srv.TLSConfig) if srv.isChild { process, err := os.FindProcess(os.Getppid()) @@ -215,6 +216,20 @@ func (srv *Server) getListener(laddr string) (l net.Listener, err error) { return } +type tcpKeepAliveListener struct { + *net.TCPListener +} + +func (ln tcpKeepAliveListener) Accept() (c net.Conn, err error) { + tc, err := ln.AcceptTCP() + if err != nil { + return + } + tc.SetKeepAlive(true) + tc.SetKeepAlivePeriod(3 * time.Minute) + return tc, nil +} + // handleSignals listens for os Signals and calls any hooked in function that the // user had registered with the signal. func (srv *Server) handleSignals() { From 30b80cba9219bc007e7898ea5af4fac88859b27d Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 22 Jan 2019 16:23:10 +0800 Subject: [PATCH 22/80] errors is better style --- router.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/router.go b/router.go index 997b6854..0ccc1568 100644 --- a/router.go +++ b/router.go @@ -15,6 +15,7 @@ package beego import ( + "errors" "fmt" "net/http" "path" @@ -479,8 +480,7 @@ func (p *ControllerRegister) InsertFilter(pattern string, pos int, filter Filter // add Filter into func (p *ControllerRegister) insertFilterRouter(pos int, mr *FilterRouter) (err error) { if pos < BeforeStatic || pos > FinishRouter { - err = fmt.Errorf("can not find your filter position") - return + return errors.New("can not find your filter position") } p.enableFilter = true p.filters[pos] = append(p.filters[pos], mr) From 475feb7e241e96da85e26d02bafa9ab9cd295318 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 22 Jan 2019 16:25:17 +0800 Subject: [PATCH 23/80] camel name style --- router.go | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/router.go b/router.go index 0ccc1568..9004819c 100644 --- a/router.go +++ b/router.go @@ -510,10 +510,10 @@ func (p *ControllerRegister) URLFor(endpoint string, values ...interface{}) stri } } } - controllName := strings.Join(paths[:len(paths)-1], "/") + controllerName := strings.Join(paths[:len(paths)-1], "/") methodName := paths[len(paths)-1] for m, t := range p.routers { - ok, url := p.geturl(t, "/", controllName, methodName, params, m) + ok, url := p.getUrl(t, "/", controllerName, methodName, params, m) if ok { return url } @@ -521,17 +521,17 @@ func (p *ControllerRegister) URLFor(endpoint string, values ...interface{}) stri return "" } -func (p *ControllerRegister) geturl(t *Tree, url, controllName, methodName string, params map[string]string, httpMethod string) (bool, string) { +func (p *ControllerRegister) getUrl(t *Tree, url, controllerName, methodName string, params map[string]string, httpMethod string) (bool, string) { for _, subtree := range t.fixrouters { u := path.Join(url, subtree.prefix) - ok, u := p.geturl(subtree, u, controllName, methodName, params, httpMethod) + ok, u := p.getUrl(subtree, u, controllerName, methodName, params, httpMethod) if ok { return ok, u } } if t.wildcard != nil { u := path.Join(url, urlPlaceholder) - ok, u := p.geturl(t.wildcard, u, controllName, methodName, params, httpMethod) + ok, u := p.getUrl(t.wildcard, u, controllerName, methodName, params, httpMethod) if ok { return ok, u } @@ -539,7 +539,7 @@ func (p *ControllerRegister) geturl(t *Tree, url, controllName, methodName strin for _, l := range t.leaves { if c, ok := l.runObject.(*ControllerInfo); ok { if c.routerType == routerTypeBeego && - strings.HasSuffix(path.Join(c.controllerType.PkgPath(), c.controllerType.Name()), controllName) { + strings.HasSuffix(path.Join(c.controllerType.PkgPath(), c.controllerType.Name()), controllerName) { find := false if HTTPMETHOD[strings.ToUpper(methodName)] { if len(c.methods) == 0 { @@ -578,18 +578,18 @@ func (p *ControllerRegister) geturl(t *Tree, url, controllName, methodName strin } } } - canskip := false + canSkip := false for _, v := range l.wildcards { if v == ":" { - canskip = true + canSkip = true continue } if u, ok := params[v]; ok { delete(params, v) url = strings.Replace(url, urlPlaceholder, u, 1) } else { - if canskip { - canskip = false + if canSkip { + canSkip = false continue } return false, "" @@ -598,27 +598,27 @@ func (p *ControllerRegister) geturl(t *Tree, url, controllName, methodName strin return true, url + toURL(params) } var i int - var startreg bool - regurl := "" + var startReg bool + regUrl := "" for _, v := range strings.Trim(l.regexps.String(), "^$") { if v == '(' { - startreg = true + startReg = true continue } else if v == ')' { - startreg = false + startReg = false if v, ok := params[l.wildcards[i]]; ok { delete(params, l.wildcards[i]) - regurl = regurl + v + regUrl = regUrl + v i++ } else { break } - } else if !startreg { - regurl = string(append([]rune(regurl), v)) + } else if !startReg { + regUrl = string(append([]rune(regUrl), v)) } } - if l.regexps.MatchString(regurl) { - ps := strings.Split(regurl, "/") + if l.regexps.MatchString(regUrl) { + ps := strings.Split(regUrl, "/") for _, p := range ps { url = strings.Replace(url, urlPlaceholder, p, 1) } From 3ed82c088208119ab6a021f42657441003fc2634 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 22 Jan 2019 17:43:55 +0800 Subject: [PATCH 24/80] Gosimple has been deprecated. Please use staticcheck instead. --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 97fc317b..343041bf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,7 +36,7 @@ install: - go get github.com/casbin/casbin - go get github.com/elazarl/go-bindata-assetfs - go get github.com/OwnLocal/goes - - go get -u honnef.co/go/tools/cmd/gosimple + - go get -u honnef.co/go/tools/cmd/staticcheck - go get -u github.com/mdempsky/unconvert - go get -u github.com/gordonklaus/ineffassign - go get -u github.com/golang/lint/golint @@ -55,7 +55,7 @@ after_script: - rm -rf ./res/var/* script: - go test -v ./... - - gosimple -ignore "$(cat .gosimpleignore)" $(go list ./... | grep -v /vendor/) + - staticcheck -show-ignore "$(cat .gosimpleignore)" $(go list ./... | grep -v /vendor/) - unconvert $(go list ./... | grep -v /vendor/) - ineffassign . - find . ! \( -path './vendor' -prune \) -type f -name '*.go' -print0 | xargs -0 gofmt -l -s From e65a9cbc0092d935e5ca848e6054f06bc230c2dc Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 22 Jan 2019 18:01:14 +0800 Subject: [PATCH 25/80] Gosimple has been deprecated. Please use staticcheck instead. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 343041bf..6755cac3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -55,7 +55,7 @@ after_script: - rm -rf ./res/var/* script: - go test -v ./... - - staticcheck -show-ignore "$(cat .gosimpleignore)" $(go list ./... | grep -v /vendor/) + - staticcheck -show-ignored "$(cat .gosimpleignore)" $(go list ./... | grep -v /vendor/) - unconvert $(go list ./... | grep -v /vendor/) - ineffassign . - find . ! \( -path './vendor' -prune \) -type f -name '*.go' -print0 | xargs -0 gofmt -l -s From 0d54bbff0238f6d22c983db07f97c02efd1617da Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 22 Jan 2019 19:09:57 +0800 Subject: [PATCH 26/80] make staticcheck happy --- controller.go | 17 ++++++++--------- fs.go | 2 +- namespace.go | 8 ++++---- parser.go | 14 +++++++------- router.go | 2 +- router_test.go | 15 +-------------- template.go | 4 ++-- templatefunc.go | 2 +- templatefunc_test.go | 1 - 9 files changed, 25 insertions(+), 40 deletions(-) diff --git a/controller.go b/controller.go index 4b8f9807..7859681f 100644 --- a/controller.go +++ b/controller.go @@ -34,7 +34,7 @@ import ( var ( // ErrAbort custom error when user stop request handler manually. - ErrAbort = errors.New("User stop run") + ErrAbort = errors.New("user stop run") // GlobalControllerRouter store comments with controller. pkgpath+controller:comments GlobalControllerRouter = make(map[string][]ControllerComments) ) @@ -93,7 +93,6 @@ type Controller struct { controllerName string actionName string methodMapping map[string]func() //method:routertree - gotofunc string AppController interface{} // template data @@ -156,37 +155,37 @@ func (c *Controller) Finish() {} // Get adds a request function to handle GET request. func (c *Controller) Get() { - http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405) + http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", http.StatusMethodNotAllowed) } // Post adds a request function to handle POST request. func (c *Controller) Post() { - http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405) + http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", http.StatusMethodNotAllowed) } // Delete adds a request function to handle DELETE request. func (c *Controller) Delete() { - http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405) + http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", http.StatusMethodNotAllowed) } // Put adds a request function to handle PUT request. func (c *Controller) Put() { - http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405) + http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", http.StatusMethodNotAllowed) } // Head adds a request function to handle HEAD request. func (c *Controller) Head() { - http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405) + http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", http.StatusMethodNotAllowed) } // Patch adds a request function to handle PATCH request. func (c *Controller) Patch() { - http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405) + http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", http.StatusMethodNotAllowed) } // Options adds a request function to handle OPTIONS request. func (c *Controller) Options() { - http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405) + http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", http.StatusMethodNotAllowed) } // HandlerFunc call function with the name diff --git a/fs.go b/fs.go index bf7002ad..41cc6f6e 100644 --- a/fs.go +++ b/fs.go @@ -42,13 +42,13 @@ func walk(fs http.FileSystem, path string, info os.FileInfo, walkFn filepath.Wal } dir, err := fs.Open(path) - defer dir.Close() if err != nil { if err1 := walkFn(path, info, err); err1 != nil { return err1 } return err } + defer dir.Close() dirs, err := dir.Readdir(-1) err1 := walkFn(path, info, err) // If err != nil, walk can't walk into this directory. diff --git a/namespace.go b/namespace.go index 72f22a72..4952c9d5 100644 --- a/namespace.go +++ b/namespace.go @@ -207,11 +207,11 @@ func (n *Namespace) Include(cList ...ControllerInterface) *Namespace { func (n *Namespace) Namespace(ns ...*Namespace) *Namespace { for _, ni := range ns { for k, v := range ni.handlers.routers { - if t, ok := n.handlers.routers[k]; ok { + if _, ok := n.handlers.routers[k]; ok { addPrefix(v, ni.prefix) n.handlers.routers[k].AddTree(ni.prefix, v) } else { - t = NewTree() + t := NewTree() t.AddTree(ni.prefix, v) addPrefix(t, ni.prefix) n.handlers.routers[k] = t @@ -236,11 +236,11 @@ func (n *Namespace) Namespace(ns ...*Namespace) *Namespace { func AddNamespace(nl ...*Namespace) { for _, n := range nl { for k, v := range n.handlers.routers { - if t, ok := BeeApp.Handlers.routers[k]; ok { + if _, ok := BeeApp.Handlers.routers[k]; ok { addPrefix(v, n.prefix) BeeApp.Handlers.routers[k].AddTree(n.prefix, v) } else { - t = NewTree() + t := NewTree() t.AddTree(n.prefix, v) addPrefix(t, n.prefix) BeeApp.Handlers.routers[k] = t diff --git a/parser.go b/parser.go index a8690274..9c509075 100644 --- a/parser.go +++ b/parser.go @@ -259,9 +259,9 @@ func parseComment(lines []*ast.Comment) (pcs []*parsedComment, err error) { imports := []parsedImport{} for _, c := range lines { - t := strings.TrimSpace(strings.TrimLeft(c.Text, "//")) + t := strings.TrimSpace(strings.TrimPrefix(c.Text, "//")) if strings.HasPrefix(t, "@Param") { - pv := getparams(strings.TrimSpace(strings.TrimLeft(t, "@Param"))) + pv := getparams(strings.TrimSpace(strings.TrimPrefix(t, "@Param"))) if len(pv) < 4 { logs.Error("Invalid @Param format. Needs at least 4 parameters") } @@ -286,7 +286,7 @@ func parseComment(lines []*ast.Comment) (pcs []*parsedComment, err error) { } for _, c := range lines { - t := strings.TrimSpace(strings.TrimLeft(c.Text, "//")) + t := strings.TrimSpace(strings.TrimPrefix(c.Text, "//")) if strings.HasPrefix(t, "@Import") { iv := getparams(strings.TrimSpace(strings.TrimLeft(t, "@Import"))) if len(iv) == 0 || len(iv) > 2 { @@ -307,9 +307,9 @@ func parseComment(lines []*ast.Comment) (pcs []*parsedComment, err error) { filterLoop: for _, c := range lines { - t := strings.TrimSpace(strings.TrimLeft(c.Text, "//")) + t := strings.TrimSpace(strings.TrimLeft(c.Text, "/")) if strings.HasPrefix(t, "@Filter") { - fv := getparams(strings.TrimSpace(strings.TrimLeft(t, "@Filter"))) + fv := getparams(strings.TrimSpace(strings.TrimPrefix(t, "@Filter"))) if len(fv) < 3 { logs.Error("Invalid @Filter format. Needs at least 3 parameters") continue filterLoop @@ -349,9 +349,9 @@ filterLoop: pc.filters = filters pc.imports = imports - t := strings.TrimSpace(strings.TrimLeft(c.Text, "//")) + t := strings.TrimSpace(strings.TrimLeft(c.Text, "/")) if strings.HasPrefix(t, "@router") { - t := strings.TrimSpace(strings.TrimLeft(c.Text, "//")) + t := strings.TrimSpace(strings.TrimLeft(c.Text, "/")) matches := routeRegex.FindStringSubmatch(t) if len(matches) == 3 { pc.routerPath = matches[1] diff --git a/router.go b/router.go index 9004819c..c5b618c3 100644 --- a/router.go +++ b/router.go @@ -690,7 +690,7 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) // filter wrong http method if !HTTPMETHOD[r.Method] { - http.Error(rw, "Method Not Allowed", 405) + http.Error(rw, "Method Not Allowed", http.StatusMethodNotAllowed) goto Admin } diff --git a/router_test.go b/router_test.go index 90104427..2797b33a 100644 --- a/router_test.go +++ b/router_test.go @@ -71,10 +71,6 @@ func (tc *TestController) GetEmptyBody() { tc.Ctx.Output.Body(res) } -type ResStatus struct { - Code int - Msg string -} type JSONController struct { Controller @@ -475,7 +471,7 @@ func TestParamResetFilter(t *testing.T) { // a response header of `Splat`. The expectation here is that that Header // value should match what the _request's_ router set, not the filter's. - headers := rw.HeaderMap + headers := rw.Result().Header if len(headers["Splat"]) != 1 { t.Errorf( "%s: There was an error in the test. Splat param not set in Header", @@ -660,25 +656,16 @@ func beegoBeforeRouter1(ctx *context.Context) { ctx.WriteString("|BeforeRouter1") } -func beegoBeforeRouter2(ctx *context.Context) { - ctx.WriteString("|BeforeRouter2") -} func beegoBeforeExec1(ctx *context.Context) { ctx.WriteString("|BeforeExec1") } -func beegoBeforeExec2(ctx *context.Context) { - ctx.WriteString("|BeforeExec2") -} func beegoAfterExec1(ctx *context.Context) { ctx.WriteString("|AfterExec1") } -func beegoAfterExec2(ctx *context.Context) { - ctx.WriteString("|AfterExec2") -} func beegoFinishRouter1(ctx *context.Context) { ctx.WriteString("|FinishRouter1") diff --git a/template.go b/template.go index cf41cb9b..264ce931 100644 --- a/template.go +++ b/template.go @@ -240,7 +240,7 @@ func getTplDeep(root string, fs http.FileSystem, file string, parent string, t * var fileAbsPath string var rParent string var err error - if filepath.HasPrefix(file, "../") { + if strings.HasPrefix(file, "../") { rParent = filepath.Join(filepath.Dir(parent), file) fileAbsPath = filepath.Join(root, filepath.Dir(parent), file) } else { @@ -248,10 +248,10 @@ func getTplDeep(root string, fs http.FileSystem, file string, parent string, t * fileAbsPath = filepath.Join(root, file) } f, err := fs.Open(fileAbsPath) - defer f.Close() if err != nil { panic("can't find template file:" + file) } + defer f.Close() data, err := ioutil.ReadAll(f) if err != nil { return nil, [][]string{}, err diff --git a/templatefunc.go b/templatefunc.go index 8c1504aa..9ec2a9e8 100644 --- a/templatefunc.go +++ b/templatefunc.go @@ -172,7 +172,7 @@ func GetConfig(returnType, key string, defaultVal interface{}) (value interface{ case "DIY": value, err = AppConfig.DIY(key) default: - err = errors.New("Config keys must be of type String, Bool, Int, Int64, Float, or DIY") + err = errors.New("config keys must be of type String, Bool, Int, Int64, Float, or DIY") } if err != nil { diff --git a/templatefunc_test.go b/templatefunc_test.go index c7b8fbd3..e99ff880 100644 --- a/templatefunc_test.go +++ b/templatefunc_test.go @@ -197,7 +197,6 @@ func TestParseForm(t *testing.T) { func TestRenderForm(t *testing.T) { type user struct { ID int `form:"-"` - tag string `form:"tag"` Name interface{} `form:"username"` Age int `form:"age,text,年龄:"` Sex string From c3eca637fba319665b794a50b3197c76e90bfbae Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 22 Jan 2019 19:10:23 +0800 Subject: [PATCH 27/80] no need gosimple --- .gosimpleignore | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 .gosimpleignore diff --git a/.gosimpleignore b/.gosimpleignore deleted file mode 100644 index 84df9b95..00000000 --- a/.gosimpleignore +++ /dev/null @@ -1,4 +0,0 @@ -github.com/astaxie/beego/*/*:S1012 -github.com/astaxie/beego/*:S1012 -github.com/astaxie/beego/*/*:S1007 -github.com/astaxie/beego/*:S1007 \ No newline at end of file From 2956d33bab1dd95d80ccab213f604c8737d716a3 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 22 Jan 2019 19:12:25 +0800 Subject: [PATCH 28/80] no need gosimple --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 6755cac3..8c3252b5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -55,7 +55,7 @@ after_script: - rm -rf ./res/var/* script: - go test -v ./... - - staticcheck -show-ignored "$(cat .gosimpleignore)" $(go list ./... | grep -v /vendor/) + - staticcheck -show-ignored $(go list ./... | grep -v /vendor/) - unconvert $(go list ./... | grep -v /vendor/) - ineffassign . - find . ! \( -path './vendor' -prune \) -type f -name '*.go' -print0 | xargs -0 gofmt -l -s From 00264650b5c87fd2a287b4f4085a2519eb2d829f Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 22 Jan 2019 19:29:53 +0800 Subject: [PATCH 29/80] modify travis and redis_sentinel test --- .travis.yml | 2 +- session/redis_sentinel/sess_redis_sentinel_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8c3252b5..1bc896af 100644 --- a/.travis.yml +++ b/.travis.yml @@ -55,7 +55,7 @@ after_script: - rm -rf ./res/var/* script: - go test -v ./... - - staticcheck -show-ignored $(go list ./... | grep -v /vendor/) + - staticcheck -show-ignored - unconvert $(go list ./... | grep -v /vendor/) - ineffassign . - find . ! \( -path './vendor' -prune \) -type f -name '*.go' -print0 | xargs -0 gofmt -l -s diff --git a/session/redis_sentinel/sess_redis_sentinel_test.go b/session/redis_sentinel/sess_redis_sentinel_test.go index 851fe804..f4e2be5f 100644 --- a/session/redis_sentinel/sess_redis_sentinel_test.go +++ b/session/redis_sentinel/sess_redis_sentinel_test.go @@ -15,7 +15,7 @@ func TestRedisSentinel(t *testing.T) { Maxlifetime: 3600, Secure: false, CookieLifeTime: 3600, - ProviderConfig: "119.23.132.234:26379,100,,0,master", + ProviderConfig: "127.0.0.1:26379,100,,0,master", } globalSessions, _ := session.NewManager("redis_sentinel", sessionConfig) go globalSessions.GC() From f237ff049ab2410572df46b4dbcf83912a8ae9e6 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 22 Jan 2019 19:45:32 +0800 Subject: [PATCH 30/80] redis_sentinel test ignore --- session/redis_sentinel/sess_redis_sentinel_test.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/session/redis_sentinel/sess_redis_sentinel_test.go b/session/redis_sentinel/sess_redis_sentinel_test.go index f4e2be5f..d5abc051 100644 --- a/session/redis_sentinel/sess_redis_sentinel_test.go +++ b/session/redis_sentinel/sess_redis_sentinel_test.go @@ -1,10 +1,11 @@ package redis_sentinel import ( - "github.com/astaxie/beego/session" "net/http" "net/http/httptest" "testing" + + "github.com/astaxie/beego/session" ) func TestRedisSentinel(t *testing.T) { @@ -15,9 +16,13 @@ func TestRedisSentinel(t *testing.T) { Maxlifetime: 3600, Secure: false, CookieLifeTime: 3600, - ProviderConfig: "127.0.0.1:26379,100,,0,master", + ProviderConfig: "127.0.0.1:6379,100,,0,master", + } + globalSessions, e := session.NewManager("redis_sentinel", sessionConfig) + if e != nil { + t.Log(e) + return } - globalSessions, _ := session.NewManager("redis_sentinel", sessionConfig) go globalSessions.GC() r, _ := http.NewRequest("GET", "/", nil) From abc9c38224293c51c1273f4516d12e1c560e01ed Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 22 Jan 2019 20:04:30 +0800 Subject: [PATCH 31/80] ignore some staticcheck checks --- staticcheck.conf | 1 + 1 file changed, 1 insertion(+) create mode 100644 staticcheck.conf diff --git a/staticcheck.conf b/staticcheck.conf new file mode 100644 index 00000000..7803887f --- /dev/null +++ b/staticcheck.conf @@ -0,0 +1 @@ +checks = ["all", "-ST1017", "-U1000", "-ST1005","-S1034","-S1012","-SA4006","-ST1005","-SA6005","-SA1019"] \ No newline at end of file From 97713849a17674bfcc7e6ab2ca7581388836306a Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 22 Jan 2019 20:21:00 +0800 Subject: [PATCH 32/80] delete stackcheck config file and ignore some staticcheck checks --- .travis.yml | 2 +- session/redis_sentinel/sess_redis_sentinel_test.go | 1 + staticcheck.conf | 1 - 3 files changed, 2 insertions(+), 2 deletions(-) delete mode 100644 staticcheck.conf diff --git a/.travis.yml b/.travis.yml index 1bc896af..d77f8048 100644 --- a/.travis.yml +++ b/.travis.yml @@ -55,7 +55,7 @@ after_script: - rm -rf ./res/var/* script: - go test -v ./... - - staticcheck -show-ignored + - staticcheck -show-ignored -checks "-ST1017", "-U1000", "-ST1005","-S1034","-S1012","-SA4006","-ST1003","-SA6005","-SA1019" - unconvert $(go list ./... | grep -v /vendor/) - ineffassign . - find . ! \( -path './vendor' -prune \) -type f -name '*.go' -print0 | xargs -0 gofmt -l -s diff --git a/session/redis_sentinel/sess_redis_sentinel_test.go b/session/redis_sentinel/sess_redis_sentinel_test.go index d5abc051..fd4155c6 100644 --- a/session/redis_sentinel/sess_redis_sentinel_test.go +++ b/session/redis_sentinel/sess_redis_sentinel_test.go @@ -23,6 +23,7 @@ func TestRedisSentinel(t *testing.T) { t.Log(e) return } + //todo test if e==nil go globalSessions.GC() r, _ := http.NewRequest("GET", "/", nil) diff --git a/staticcheck.conf b/staticcheck.conf deleted file mode 100644 index 7803887f..00000000 --- a/staticcheck.conf +++ /dev/null @@ -1 +0,0 @@ -checks = ["all", "-ST1017", "-U1000", "-ST1005","-S1034","-S1012","-SA4006","-ST1005","-SA6005","-SA1019"] \ No newline at end of file From 5b42afa32480baeb17d932299f7951ab01f35bf3 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 22 Jan 2019 20:30:05 +0800 Subject: [PATCH 33/80] modiyf staticcheck checks --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d77f8048..7465ceca 100644 --- a/.travis.yml +++ b/.travis.yml @@ -55,7 +55,7 @@ after_script: - rm -rf ./res/var/* script: - go test -v ./... - - staticcheck -show-ignored -checks "-ST1017", "-U1000", "-ST1005","-S1034","-S1012","-SA4006","-ST1003","-SA6005","-SA1019" + - staticcheck -show-ignored -checks "-ST1017,-U1000,-ST1005,-S1034,-S1012,-SA4006,-ST1003,-SA6005,-SA1019" - unconvert $(go list ./... | grep -v /vendor/) - ineffassign . - find . ! \( -path './vendor' -prune \) -type f -name '*.go' -print0 | xargs -0 gofmt -l -s From 2a579eb27c3a9a9ec06d402256bf06bc10413dde Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 22 Jan 2019 20:41:07 +0800 Subject: [PATCH 34/80] staticcheck checks -ST1003 remove --- .travis.yml | 2 +- router.go | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7465ceca..8f44b5ea 100644 --- a/.travis.yml +++ b/.travis.yml @@ -55,7 +55,7 @@ after_script: - rm -rf ./res/var/* script: - go test -v ./... - - staticcheck -show-ignored -checks "-ST1017,-U1000,-ST1005,-S1034,-S1012,-SA4006,-ST1003,-SA6005,-SA1019" + - staticcheck -show-ignored -checks "-ST1017,-U1000,-ST1005,-S1034,-S1012,-SA4006,-SA6005,-SA1019" - unconvert $(go list ./... | grep -v /vendor/) - ineffassign . - find . ! \( -path './vendor' -prune \) -type f -name '*.go' -print0 | xargs -0 gofmt -l -s diff --git a/router.go b/router.go index c5b618c3..851934a8 100644 --- a/router.go +++ b/router.go @@ -513,7 +513,7 @@ func (p *ControllerRegister) URLFor(endpoint string, values ...interface{}) stri controllerName := strings.Join(paths[:len(paths)-1], "/") methodName := paths[len(paths)-1] for m, t := range p.routers { - ok, url := p.getUrl(t, "/", controllerName, methodName, params, m) + ok, url := p.getURL(t, "/", controllerName, methodName, params, m) if ok { return url } @@ -521,17 +521,17 @@ func (p *ControllerRegister) URLFor(endpoint string, values ...interface{}) stri return "" } -func (p *ControllerRegister) getUrl(t *Tree, url, controllerName, methodName string, params map[string]string, httpMethod string) (bool, string) { +func (p *ControllerRegister) getURL(t *Tree, url, controllerName, methodName string, params map[string]string, httpMethod string) (bool, string) { for _, subtree := range t.fixrouters { u := path.Join(url, subtree.prefix) - ok, u := p.getUrl(subtree, u, controllerName, methodName, params, httpMethod) + ok, u := p.getURL(subtree, u, controllerName, methodName, params, httpMethod) if ok { return ok, u } } if t.wildcard != nil { u := path.Join(url, urlPlaceholder) - ok, u := p.getUrl(t.wildcard, u, controllerName, methodName, params, httpMethod) + ok, u := p.getURL(t.wildcard, u, controllerName, methodName, params, httpMethod) if ok { return ok, u } @@ -599,7 +599,7 @@ func (p *ControllerRegister) getUrl(t *Tree, url, controllerName, methodName str } var i int var startReg bool - regUrl := "" + regURL := "" for _, v := range strings.Trim(l.regexps.String(), "^$") { if v == '(' { startReg = true @@ -608,17 +608,17 @@ func (p *ControllerRegister) getUrl(t *Tree, url, controllerName, methodName str startReg = false if v, ok := params[l.wildcards[i]]; ok { delete(params, l.wildcards[i]) - regUrl = regUrl + v + regURL = regURL + v i++ } else { break } } else if !startReg { - regUrl = string(append([]rune(regUrl), v)) + regURL = string(append([]rune(regURL), v)) } } - if l.regexps.MatchString(regUrl) { - ps := strings.Split(regUrl, "/") + if l.regexps.MatchString(regURL) { + ps := strings.Split(regURL, "/") for _, p := range ps { url = strings.Replace(url, urlPlaceholder, p, 1) } From 0145fe348669e85057d75a0a3d32e151ff35d1cb Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 22 Jan 2019 20:52:06 +0800 Subject: [PATCH 35/80] remove SA1024 staticchek --- .travis.yml | 2 +- parser.go | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8f44b5ea..3a3a6f66 100644 --- a/.travis.yml +++ b/.travis.yml @@ -55,7 +55,7 @@ after_script: - rm -rf ./res/var/* script: - go test -v ./... - - staticcheck -show-ignored -checks "-ST1017,-U1000,-ST1005,-S1034,-S1012,-SA4006,-SA6005,-SA1019" + - staticcheck -show-ignored -checks "-ST1017,-U1000,-ST1005,-S1034,-S1012,-SA4006,-SA6005,-SA1019,-SA1024" - unconvert $(go list ./... | grep -v /vendor/) - ineffassign . - find . ! \( -path './vendor' -prune \) -type f -name '*.go' -print0 | xargs -0 gofmt -l -s diff --git a/parser.go b/parser.go index 9c509075..a8690274 100644 --- a/parser.go +++ b/parser.go @@ -259,9 +259,9 @@ func parseComment(lines []*ast.Comment) (pcs []*parsedComment, err error) { imports := []parsedImport{} for _, c := range lines { - t := strings.TrimSpace(strings.TrimPrefix(c.Text, "//")) + t := strings.TrimSpace(strings.TrimLeft(c.Text, "//")) if strings.HasPrefix(t, "@Param") { - pv := getparams(strings.TrimSpace(strings.TrimPrefix(t, "@Param"))) + pv := getparams(strings.TrimSpace(strings.TrimLeft(t, "@Param"))) if len(pv) < 4 { logs.Error("Invalid @Param format. Needs at least 4 parameters") } @@ -286,7 +286,7 @@ func parseComment(lines []*ast.Comment) (pcs []*parsedComment, err error) { } for _, c := range lines { - t := strings.TrimSpace(strings.TrimPrefix(c.Text, "//")) + t := strings.TrimSpace(strings.TrimLeft(c.Text, "//")) if strings.HasPrefix(t, "@Import") { iv := getparams(strings.TrimSpace(strings.TrimLeft(t, "@Import"))) if len(iv) == 0 || len(iv) > 2 { @@ -307,9 +307,9 @@ func parseComment(lines []*ast.Comment) (pcs []*parsedComment, err error) { filterLoop: for _, c := range lines { - t := strings.TrimSpace(strings.TrimLeft(c.Text, "/")) + t := strings.TrimSpace(strings.TrimLeft(c.Text, "//")) if strings.HasPrefix(t, "@Filter") { - fv := getparams(strings.TrimSpace(strings.TrimPrefix(t, "@Filter"))) + fv := getparams(strings.TrimSpace(strings.TrimLeft(t, "@Filter"))) if len(fv) < 3 { logs.Error("Invalid @Filter format. Needs at least 3 parameters") continue filterLoop @@ -349,9 +349,9 @@ filterLoop: pc.filters = filters pc.imports = imports - t := strings.TrimSpace(strings.TrimLeft(c.Text, "/")) + t := strings.TrimSpace(strings.TrimLeft(c.Text, "//")) if strings.HasPrefix(t, "@router") { - t := strings.TrimSpace(strings.TrimLeft(c.Text, "/")) + t := strings.TrimSpace(strings.TrimLeft(c.Text, "//")) matches := routeRegex.FindStringSubmatch(t) if len(matches) == 3 { pc.routerPath = matches[1] From a9ffc2a0783b6f8838028073c781a4b5fa56e04a Mon Sep 17 00:00:00 2001 From: JessonChan Date: Wed, 23 Jan 2019 12:30:57 +0800 Subject: [PATCH 36/80] https://github.com/astaxie/beego/issues/3446 Use UTF-8 as the encoding of the "filename*" parameter, when present, because at least one existing implementation only implements that encoding. --- context/output.go | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/context/output.go b/context/output.go index 3e277ab2..8a1a1628 100644 --- a/context/output.go +++ b/context/output.go @@ -30,7 +30,8 @@ import ( "strconv" "strings" "time" - "gopkg.in/yaml.v2" + + yaml "gopkg.in/yaml.v2" ) // BeegoOutput does work for sending response header. @@ -203,7 +204,6 @@ func (output *BeegoOutput) JSON(data interface{}, hasIndent bool, encoding bool) return output.Body(content) } - // YAML writes yaml to response body. func (output *BeegoOutput) YAML(data interface{}) error { output.Header("Content-Type", "application/x-yaml; charset=utf-8") @@ -288,7 +288,19 @@ func (output *BeegoOutput) Download(file string, filename ...string) { } else { fName = filepath.Base(file) } - output.Header("Content-Disposition", "attachment; filename="+url.PathEscape(fName)) + //https://tools.ietf.org/html/rfc6266#section-4.3 + fn := url.PathEscape(fName) + if fName == fn { + output.Header("Content-Disposition", "attachment; filename="+fn) + } else { + /** + The parameters "filename" and "filename*" differ only in that + "filename*" uses the encoding defined in [RFC5987], allowing the use + of characters not present in the ISO-8859-1 character set + ([ISO-8859-1]). + */ + output.Header("Content-Disposition", "attachment; filename*=utf-8''"+fn) + } output.Header("Content-Description", "File Transfer") output.Header("Content-Type", "application/octet-stream") output.Header("Content-Transfer-Encoding", "binary") From 1c893996c0af969d529274ecacaf0eb21fef424b Mon Sep 17 00:00:00 2001 From: JessonChan Date: Wed, 23 Jan 2019 12:36:14 +0800 Subject: [PATCH 37/80] improve the download func code --- context/output.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/context/output.go b/context/output.go index 8a1a1628..238dcf45 100644 --- a/context/output.go +++ b/context/output.go @@ -291,7 +291,7 @@ func (output *BeegoOutput) Download(file string, filename ...string) { //https://tools.ietf.org/html/rfc6266#section-4.3 fn := url.PathEscape(fName) if fName == fn { - output.Header("Content-Disposition", "attachment; filename="+fn) + fn = "filename=" + fn } else { /** The parameters "filename" and "filename*" differ only in that @@ -299,8 +299,9 @@ func (output *BeegoOutput) Download(file string, filename ...string) { of characters not present in the ISO-8859-1 character set ([ISO-8859-1]). */ - output.Header("Content-Disposition", "attachment; filename*=utf-8''"+fn) + fn = "filename=" + fName + "; filename*=utf-8''" + fn } + output.Header("Content-Disposition", "attachment; "+fn) output.Header("Content-Description", "File Transfer") output.Header("Content-Type", "application/octet-stream") output.Header("Content-Transfer-Encoding", "binary") From dc07fa70851f7784f1c9f88c8dc0c39694dc32aa Mon Sep 17 00:00:00 2001 From: "Iskander (Alex) Sharipov" Date: Thu, 24 Jan 2019 08:52:30 +0300 Subject: [PATCH 38/80] cache: remove excessive type assertions Assign type switch variable to get properly-typed value inside case clauses. Signed-off-by: Iskander Sharipov --- cache/memory.go | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/cache/memory.go b/cache/memory.go index cb9802ab..e5b562f0 100644 --- a/cache/memory.go +++ b/cache/memory.go @@ -116,19 +116,19 @@ func (bc *MemoryCache) Incr(key string) error { if !ok { return errors.New("key not exist") } - switch itm.val.(type) { + switch val := itm.val.(type) { case int: - itm.val = itm.val.(int) + 1 + itm.val = val + 1 case int32: - itm.val = itm.val.(int32) + 1 + itm.val = val + 1 case int64: - itm.val = itm.val.(int64) + 1 + itm.val = val + 1 case uint: - itm.val = itm.val.(uint) + 1 + itm.val = val + 1 case uint32: - itm.val = itm.val.(uint32) + 1 + itm.val = val + 1 case uint64: - itm.val = itm.val.(uint64) + 1 + itm.val = val + 1 default: return errors.New("item val is not (u)int (u)int32 (u)int64") } @@ -143,28 +143,28 @@ func (bc *MemoryCache) Decr(key string) error { if !ok { return errors.New("key not exist") } - switch itm.val.(type) { + switch val := itm.val.(type) { case int: - itm.val = itm.val.(int) - 1 + itm.val = val - 1 case int64: - itm.val = itm.val.(int64) - 1 + itm.val = val - 1 case int32: - itm.val = itm.val.(int32) - 1 + itm.val = val - 1 case uint: - if itm.val.(uint) > 0 { - itm.val = itm.val.(uint) - 1 + if val > 0 { + itm.val = val - 1 } else { return errors.New("item val is less than 0") } case uint32: - if itm.val.(uint32) > 0 { - itm.val = itm.val.(uint32) - 1 + if val > 0 { + itm.val = val - 1 } else { return errors.New("item val is less than 0") } case uint64: - if itm.val.(uint64) > 0 { - itm.val = itm.val.(uint64) - 1 + if val > 0 { + itm.val = val - 1 } else { return errors.New("item val is less than 0") } From 12fdc04f1b2c9e9ea1c9c2a636ef71141f342818 Mon Sep 17 00:00:00 2001 From: Witaya Tospitakkul Date: Fri, 25 Jan 2019 00:15:40 +0700 Subject: [PATCH 39/80] fix: when parse post form it didnt parse fields which have same name but the first index is empty but another is not --- go.mod | 2 +- go.sum | 1 + templatefunc.go | 29 +++++++++++++++++++++-------- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index a7e1194b..fbdec124 100644 --- a/go.mod +++ b/go.mod @@ -2,9 +2,9 @@ module github.com/astaxie/beego require ( github.com/Knetic/govaluate v3.0.0+incompatible // indirect + github.com/OwnLocal/goes v1.0.0 github.com/beego/goyaml2 v0.0.0-20130207012346-5545475820dd github.com/beego/x2j v0.0.0-20131220205130-a0352aadc542 - github.com/OwnLocal/goes v1.0.0 github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737 github.com/casbin/casbin v1.7.0 github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58 diff --git a/go.sum b/go.sum index fbe3a8c3..ab233162 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,6 @@ github.com/Knetic/govaluate v3.0.0+incompatible h1:7o6+MAPhYTCF0+fdvoz1xDedhRb4f6s9Tn1Tt7/WTEg= github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/OwnLocal/goes v1.0.0/go.mod h1:8rIFjBGTue3lCU0wplczcUgt9Gxgrkkrw7etMIcn8TM= github.com/beego/goyaml2 v0.0.0-20130207012346-5545475820dd h1:jZtX5jh5IOMu0fpOTC3ayh6QGSPJ/KWOv1lgPvbRw1M= github.com/beego/goyaml2 v0.0.0-20130207012346-5545475820dd/go.mod h1:1b+Y/CofkYwXMUU0OhQqGvsY2Bvgr4j6jfT699wyZKQ= github.com/beego/x2j v0.0.0-20131220205130-a0352aadc542 h1:nYXb+3jF6Oq/j8R/y90XrKpreCxIalBWfeyeKymgOPk= diff --git a/templatefunc.go b/templatefunc.go index 9ec2a9e8..eeb34cc6 100644 --- a/templatefunc.go +++ b/templatefunc.go @@ -85,24 +85,24 @@ func DateFormat(t time.Time, layout string) (datestring string) { var datePatterns = []string{ // year "Y", "2006", // A full numeric representation of a year, 4 digits Examples: 1999 or 2003 - "y", "06", //A two digit representation of a year Examples: 99 or 03 + "y", "06", //A two digit representation of a year Examples: 99 or 03 // month - "m", "01", // Numeric representation of a month, with leading zeros 01 through 12 - "n", "1", // Numeric representation of a month, without leading zeros 1 through 12 - "M", "Jan", // A short textual representation of a month, three letters Jan through Dec + "m", "01", // Numeric representation of a month, with leading zeros 01 through 12 + "n", "1", // Numeric representation of a month, without leading zeros 1 through 12 + "M", "Jan", // A short textual representation of a month, three letters Jan through Dec "F", "January", // A full textual representation of a month, such as January or March January through December // day "d", "02", // Day of the month, 2 digits with leading zeros 01 to 31 - "j", "2", // Day of the month without leading zeros 1 to 31 + "j", "2", // Day of the month without leading zeros 1 to 31 // week - "D", "Mon", // A textual representation of a day, three letters Mon through Sun + "D", "Mon", // A textual representation of a day, three letters Mon through Sun "l", "Monday", // A full textual representation of the day of the week Sunday through Saturday // time - "g", "3", // 12-hour format of an hour without leading zeros 1 through 12 + "g", "3", // 12-hour format of an hour without leading zeros 1 through 12 "G", "15", // 24-hour format of an hour without leading zeros 0 through 23 "h", "03", // 12-hour format of an hour with leading zeros 01 through 12 "H", "15", // 24-hour format of an hour with leading zeros 00 through 23 @@ -297,8 +297,21 @@ func parseFormToStruct(form url.Values, objT reflect.Type, objV reflect.Value) e tag = tags[0] } + if fieldT.Type.Kind() == reflect.Slice { + found := false + for _, v := range form[tag] { + if len(v) != 0 { + found = true + break + } + } + if !found { + continue + } + } + value := form.Get(tag) - if len(value) == 0 { + if (fieldT.Type.Kind() != reflect.Slice) && len(value) == 0 { continue } From 920207f72c20161bbb45e0fb8d509d2165601df7 Mon Sep 17 00:00:00 2001 From: Witaya Tospitakkul Date: Fri, 25 Jan 2019 00:38:14 +0700 Subject: [PATCH 40/80] add testing for ParseForm when form post has a slice in body --- templatefunc_test.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/templatefunc_test.go b/templatefunc_test.go index e99ff880..6c1d9d72 100644 --- a/templatefunc_test.go +++ b/templatefunc_test.go @@ -111,7 +111,7 @@ func TestHtmlunquote(t *testing.T) { func TestParseForm(t *testing.T) { type ExtendInfo struct { - Hobby string `form:"hobby"` + Hobby []string `form:"hobby"` Memo string } @@ -146,7 +146,7 @@ func TestParseForm(t *testing.T) { "date": []string{"2014-11-12"}, "organization": []string{"beego"}, "title": []string{"CXO"}, - "hobby": []string{"Basketball"}, + "hobby": []string{"Basketball", "Football"}, "memo": []string{"nothing"}, } if err := ParseForm(form, u); err == nil { @@ -186,8 +186,11 @@ func TestParseForm(t *testing.T) { if u.Title != "CXO" { t.Errorf("Title should equal `CXO`, but got `%v`", u.Title) } - if u.Hobby != "Basketball" { - t.Errorf("Hobby should equal `Basketball`, but got `%v`", u.Hobby) + if u.Hobby[0] != "Basketball" { + t.Errorf("Hobby should equal `Basketball`, but got `%v`", u.Hobby[0]) + } + if u.Hobby[1] != "Football" { + t.Errorf("Hobby should equal `Football`, but got `%v`", u.Hobby[1]) } if len(u.Memo) != 0 { t.Errorf("Memo's length should equal 0 but got %v", len(u.Memo)) From bd1b421491d1d79f92b55344fc45341a264be624 Mon Sep 17 00:00:00 2001 From: Witaya Tospitakkul Date: Fri, 25 Jan 2019 09:04:01 +0700 Subject: [PATCH 41/80] fix: adding test for issue due to testing is not reflect changed --- templatefunc_test.go | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/templatefunc_test.go b/templatefunc_test.go index 6c1d9d72..b4c19c2e 100644 --- a/templatefunc_test.go +++ b/templatefunc_test.go @@ -146,7 +146,7 @@ func TestParseForm(t *testing.T) { "date": []string{"2014-11-12"}, "organization": []string{"beego"}, "title": []string{"CXO"}, - "hobby": []string{"Basketball", "Football"}, + "hobby": []string{"", "Basketball", "Football"}, "memo": []string{"nothing"}, } if err := ParseForm(form, u); err == nil { @@ -186,11 +186,14 @@ func TestParseForm(t *testing.T) { if u.Title != "CXO" { t.Errorf("Title should equal `CXO`, but got `%v`", u.Title) } - if u.Hobby[0] != "Basketball" { - t.Errorf("Hobby should equal `Basketball`, but got `%v`", u.Hobby[0]) + if u.Hobby[0] != "" { + t.Errorf("Hobby should equal ``, but got `%v`", u.Hobby[0]) } - if u.Hobby[1] != "Football" { - t.Errorf("Hobby should equal `Football`, but got `%v`", u.Hobby[1]) + if u.Hobby[1] != "Basketball" { + t.Errorf("Hobby should equal `Basketball`, but got `%v`", u.Hobby[1]) + } + if u.Hobby[2] != "Football" { + t.Errorf("Hobby should equal `Football`, but got `%v`", u.Hobby[2]) } if len(u.Memo) != 0 { t.Errorf("Memo's length should equal 0 but got %v", len(u.Memo)) From 3bd7614ade4f0b9d5cd9d7f2da972a4c370805b8 Mon Sep 17 00:00:00 2001 From: Witaya Tospitakkul Date: Fri, 25 Jan 2019 11:00:24 +0700 Subject: [PATCH 42/80] refactoring code after discussion --- templatefunc.go | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/templatefunc.go b/templatefunc.go index eeb34cc6..d302cb64 100644 --- a/templatefunc.go +++ b/templatefunc.go @@ -297,24 +297,18 @@ func parseFormToStruct(form url.Values, objT reflect.Type, objV reflect.Value) e tag = tags[0] } - if fieldT.Type.Kind() == reflect.Slice { - found := false - for _, v := range form[tag] { - if len(v) != 0 { - found = true - break - } - } - if !found { + formValues := form[tag] + var value string + if len(formValues) == 0 { + continue + } + if len(formValues) == 1 { + value = formValues[0] + if value == "" { continue } } - value := form.Get(tag) - if (fieldT.Type.Kind() != reflect.Slice) && len(value) == 0 { - continue - } - switch fieldT.Type.Kind() { case reflect.Bool: if strings.ToLower(value) == "on" || strings.ToLower(value) == "1" || strings.ToLower(value) == "yes" { From 8506194d2c887bb1b56fb639cb6c2da7a5c9d8df Mon Sep 17 00:00:00 2001 From: DennisMao Date: Fri, 25 Jan 2019 19:08:39 +0800 Subject: [PATCH 43/80] fix panic cause by the map --- cache/file.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cache/file.go b/cache/file.go index 691ce7cd..1926268a 100644 --- a/cache/file.go +++ b/cache/file.go @@ -65,7 +65,7 @@ func NewFileCache() Cache { // the config need to be like {CachePath:"/cache","FileSuffix":".bin","DirectoryLevel":2,"EmbedExpiry":0} func (fc *FileCache) StartAndGC(config string) error { - var cfg map[string]string + cfg := make(map[string]string) json.Unmarshal([]byte(config), &cfg) if _, ok := cfg["CachePath"]; !ok { cfg["CachePath"] = FileCachePath From 6ca0978777bd8e796376162520fc3ea561b644c8 Mon Sep 17 00:00:00 2001 From: "Iskander (Alex) Sharipov" Date: Sat, 26 Jan 2019 14:13:53 +0300 Subject: [PATCH 44/80] replace unchecked Compile calls with MustCompile For constant patterns and especially when errors are ignored, `regexp.MustCompile` is a better choice than `regexp.Compile`. Signed-off-by: Iskander Sharipov --- templatefunc.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/templatefunc.go b/templatefunc.go index 9ec2a9e8..7a8d5588 100644 --- a/templatefunc.go +++ b/templatefunc.go @@ -55,21 +55,21 @@ func Substr(s string, start, length int) string { // HTML2str returns escaping text convert from html. func HTML2str(html string) string { - re, _ := regexp.Compile(`\<[\S\s]+?\>`) + re := regexp.MustCompile(`\<[\S\s]+?\>`) html = re.ReplaceAllStringFunc(html, strings.ToLower) //remove STYLE - re, _ = regexp.Compile(`\`) + re = regexp.MustCompile(`\`) html = re.ReplaceAllString(html, "") //remove SCRIPT - re, _ = regexp.Compile(`\`) + re = regexp.MustCompile(`\`) html = re.ReplaceAllString(html, "") - re, _ = regexp.Compile(`\<[\S\s]+?\>`) + re = regexp.MustCompile(`\<[\S\s]+?\>`) html = re.ReplaceAllString(html, "\n") - re, _ = regexp.Compile(`\s{2,}`) + re = regexp.MustCompile(`\s{2,}`) html = re.ReplaceAllString(html, "\n") return strings.TrimSpace(html) From af4464ce585434015ab51bcf21ab9da8a7a448f4 Mon Sep 17 00:00:00 2001 From: zav8 Date: Fri, 1 Feb 2019 15:27:10 +0800 Subject: [PATCH 45/80] add support for pointer fields of structs to method QueryRows() --- orm/orm_raw.go | 8 ++++++++ orm/orm_test.go | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/orm/orm_raw.go b/orm/orm_raw.go index 27651fe4..3325a7ea 100644 --- a/orm/orm_raw.go +++ b/orm/orm_raw.go @@ -191,6 +191,14 @@ func (o *rawSet) setFieldValue(ind reflect.Value, value interface{}) { ind.Set(reflect.Indirect(reflect.ValueOf(sc))) } } + + case reflect.Ptr: + if value == nil { + ind.Set(reflect.Zero(ind.Type())) + break + } + ind.Set(reflect.New(ind.Type().Elem())) + o.setFieldValue(reflect.Indirect(ind), value) } } diff --git a/orm/orm_test.go b/orm/orm_test.go index 4f499a7c..0e2bf732 100644 --- a/orm/orm_test.go +++ b/orm/orm_test.go @@ -458,6 +458,14 @@ func TestNullDataTypes(t *testing.T) { throwFail(t, AssertIs((*d.TimePtr).UTC().Format(testTime), timePtr.UTC().Format(testTime))) throwFail(t, AssertIs((*d.DatePtr).UTC().Format(testDate), datePtr.UTC().Format(testDate))) throwFail(t, AssertIs((*d.DateTimePtr).UTC().Format(testDateTime), dateTimePtr.UTC().Format(testDateTime))) + + // test support for pointer fields using RawSeter.QueryRows() + var dnList []*DataNull + Q := dDbBaser.TableQuote() + num, err = dORM.Raw(fmt.Sprintf("SELECT * FROM %sdata_null%s where id=?", Q, Q), 3).QueryRows(&dnList) + throwFailNow(t, err) + equal := reflect.DeepEqual(*dnList[0], d) + throwFailNow(t, AssertIs(equal, true)) } func TestDataCustomTypes(t *testing.T) { From 7abdb05f913424ee0ce21e736eec3e3dc20d42d8 Mon Sep 17 00:00:00 2001 From: zav8 Date: Fri, 1 Feb 2019 15:39:40 +0800 Subject: [PATCH 46/80] little fix --- orm/orm_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/orm/orm_test.go b/orm/orm_test.go index 0e2bf732..bdb430b6 100644 --- a/orm/orm_test.go +++ b/orm/orm_test.go @@ -464,6 +464,7 @@ func TestNullDataTypes(t *testing.T) { Q := dDbBaser.TableQuote() num, err = dORM.Raw(fmt.Sprintf("SELECT * FROM %sdata_null%s where id=?", Q, Q), 3).QueryRows(&dnList) throwFailNow(t, err) + throwFailNow(t, AssertIs(num, 1)) equal := reflect.DeepEqual(*dnList[0], d) throwFailNow(t, AssertIs(equal, true)) } From d7430eb92171f6066745705090cf617b3eea3870 Mon Sep 17 00:00:00 2001 From: Sergey Date: Mon, 4 Feb 2019 11:03:27 +0500 Subject: [PATCH 47/80] SessionRead: check of the length for input sid variable --- session/sess_file.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/session/sess_file.go b/session/sess_file.go index c089dade..db143522 100644 --- a/session/sess_file.go +++ b/session/sess_file.go @@ -19,6 +19,7 @@ import ( "io/ioutil" "net/http" "os" + "errors" "path" "path/filepath" "strings" @@ -131,6 +132,9 @@ func (fp *FileProvider) SessionRead(sid string) (Store, error) { if strings.ContainsAny(sid, "./") { return nil, nil } + if len(sid) < 2 { + return nil, errors.New("length of the sid is less than 2") + } filepder.lock.Lock() defer filepder.lock.Unlock() From 67666dbe0f982a8edd1bb9a03234a2a4297ac614 Mon Sep 17 00:00:00 2001 From: Iskander Sharipov Date: Sat, 9 Feb 2019 17:18:59 +0300 Subject: [PATCH 48/80] all: simplify boolean expressions - !(a == b) => a != b - !(a != b) => a == b Signed-off-by: Iskander Sharipov --- cache/memcache/memcache.go | 2 +- session/ledis/ledis_session.go | 2 +- session/mysql/sess_mysql.go | 2 +- session/postgres/sess_postgresql.go | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cache/memcache/memcache.go b/cache/memcache/memcache.go index 0624f5fa..19116bfa 100644 --- a/cache/memcache/memcache.go +++ b/cache/memcache/memcache.go @@ -146,7 +146,7 @@ func (rc *Cache) IsExist(key string) bool { } } _, err := rc.conn.Get(key) - return !(err != nil) + return err == nil } // ClearAll clear all cached in memcache. diff --git a/session/ledis/ledis_session.go b/session/ledis/ledis_session.go index 77685d1e..c0d4bf82 100644 --- a/session/ledis/ledis_session.go +++ b/session/ledis/ledis_session.go @@ -133,7 +133,7 @@ func (lp *Provider) SessionRead(sid string) (session.Store, error) { // SessionExist check ledis session exist by sid func (lp *Provider) SessionExist(sid string) bool { count, _ := c.Exists([]byte(sid)) - return !(count == 0) + return count != 0 } // SessionRegenerate generate new sid for ledis session diff --git a/session/mysql/sess_mysql.go b/session/mysql/sess_mysql.go index 4c9251e7..301353ab 100644 --- a/session/mysql/sess_mysql.go +++ b/session/mysql/sess_mysql.go @@ -170,7 +170,7 @@ func (mp *Provider) SessionExist(sid string) bool { row := c.QueryRow("select session_data from "+TableName+" where session_key=?", sid) var sessiondata []byte err := row.Scan(&sessiondata) - return !(err == sql.ErrNoRows) + return err != sql.ErrNoRows } // SessionRegenerate generate new sid for mysql session diff --git a/session/postgres/sess_postgresql.go b/session/postgres/sess_postgresql.go index ffc27def..0b8b9645 100644 --- a/session/postgres/sess_postgresql.go +++ b/session/postgres/sess_postgresql.go @@ -184,7 +184,7 @@ func (mp *Provider) SessionExist(sid string) bool { row := c.QueryRow("select session_data from session where session_key=$1", sid) var sessiondata []byte err := row.Scan(&sessiondata) - return !(err == sql.ErrNoRows) + return err != sql.ErrNoRows } // SessionRegenerate generate new sid for postgresql session From c998e52cc03dc244b4d6f6fdf60b5a886d9598a9 Mon Sep 17 00:00:00 2001 From: Iskander Sharipov Date: Sun, 10 Feb 2019 20:37:43 +0300 Subject: [PATCH 49/80] config/yaml: s/bytes.NewBuffer/bytes.NewReader/ When io.Reader is required out of []byte, it's better to use bytes.NewReader than bytes.NewBuffer. Signed-off-by: Iskander Sharipov --- config/yaml/yaml.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/yaml/yaml.go b/config/yaml/yaml.go index 7bf1335c..5def2da3 100644 --- a/config/yaml/yaml.go +++ b/config/yaml/yaml.go @@ -97,7 +97,7 @@ func parseYML(buf []byte) (cnf map[string]interface{}, err error) { } } - data, err := goyaml2.Read(bytes.NewBuffer(buf)) + data, err := goyaml2.Read(bytes.NewReader(buf)) if err != nil { log.Println("Goyaml2 ERR>", string(buf), err) return From ba17bdd3669b359f291abb880a8e2a2fdc329f11 Mon Sep 17 00:00:00 2001 From: BaoyangChai Date: Tue, 12 Feb 2019 18:05:29 +0800 Subject: [PATCH 50/80] add ignore auto_now_add field when update --- orm/db.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/orm/db.go b/orm/db.go index dfaa5f1d..e488a5ab 100644 --- a/orm/db.go +++ b/orm/db.go @@ -621,6 +621,25 @@ func (d *dbBase) Update(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time. return 0, err } + var find bool + var index int + for i, col := range setNames { + if mi.fields.GetByColumn(col).autoNowAdd { + index = i + find = true + } + } + + if find { + newSetNames := make([]string, 0, 0) + newSetNames = append(setNames[0:index], setNames[index+1:]...) + setNames = newSetNames + newSetValues := make([]interface{}, 0, 0) + newSetValues = append(setValues[0:index], setValues[index+1:]...) + setValues = newSetValues + + } + setValues = append(setValues, pkValue) Q := d.ins.TableQuote() From 2fefd8cbbfd2141361f4d74bad24c19b724d8fbd Mon Sep 17 00:00:00 2001 From: BaoyangChai Date: Tue, 12 Feb 2019 18:53:34 +0800 Subject: [PATCH 51/80] update len --- orm/db.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/orm/db.go b/orm/db.go index e488a5ab..8e7e93bb 100644 --- a/orm/db.go +++ b/orm/db.go @@ -631,10 +631,10 @@ func (d *dbBase) Update(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time. } if find { - newSetNames := make([]string, 0, 0) + newSetNames := make([]string, 0, len(setNames)-1) newSetNames = append(setNames[0:index], setNames[index+1:]...) setNames = newSetNames - newSetValues := make([]interface{}, 0, 0) + newSetValues := make([]interface{}, 0, len(setNames)-1) newSetValues = append(setValues[0:index], setValues[index+1:]...) setValues = newSetValues From 65f587d5e96f34f91e7b576e7890b98bc56d3553 Mon Sep 17 00:00:00 2001 From: BaoyangChai Date: Tue, 12 Feb 2019 19:05:22 +0800 Subject: [PATCH 52/80] fix ineffectual assignment --- orm/db.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/orm/db.go b/orm/db.go index 8e7e93bb..2719dff7 100644 --- a/orm/db.go +++ b/orm/db.go @@ -632,10 +632,12 @@ func (d *dbBase) Update(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time. if find { newSetNames := make([]string, 0, len(setNames)-1) - newSetNames = append(setNames[0:index], setNames[index+1:]...) + newSetNames = append(newSetNames, setNames[0:index]...) + newSetNames = append(newSetNames, setNames[index+1:]...) setNames = newSetNames newSetValues := make([]interface{}, 0, len(setNames)-1) - newSetValues = append(setValues[0:index], setValues[index+1:]...) + newSetValues = append(newSetValues, setValues[0:index]...) + newSetValues = append(newSetValues, setValues[index+1:]...) setValues = newSetValues } From ddcd28e67f23da83eb8e64fa3e45b16451c82291 Mon Sep 17 00:00:00 2001 From: Joseph Edwards Van Riper III Date: Tue, 12 Feb 2019 13:00:11 -0500 Subject: [PATCH 53/80] APIBaiscAuth is misspelling of APIBasicAuth Corrected APIBaiscAuth to APIBasicAuth. Maintained old name (forwarding to new one) for those still using the previous API function name. --- plugins/apiauth/apiauth.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/plugins/apiauth/apiauth.go b/plugins/apiauth/apiauth.go index f816029c..aa8c1960 100644 --- a/plugins/apiauth/apiauth.go +++ b/plugins/apiauth/apiauth.go @@ -72,8 +72,8 @@ import ( // 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 { +// APIBasicAuth use the basic appid/appkey as the AppIdToAppSecret +func APIBasicAuth(appid, appkey string) beego.FilterFunc { ft := func(aid string) string { if aid == appid { return appkey @@ -83,6 +83,11 @@ func APIBaiscAuth(appid, appkey string) beego.FilterFunc { return APISecretAuth(ft, 300) } +// APIBaiscAuth calls APIBasicAuth for previous callers +func APIBaiscAuth(appid, appkey string) beego.FilterFunc { + return APIBaiscAuth(appid, appkey) +} + // APISecretAuth use AppIdToAppSecret verify and func APISecretAuth(f AppIDToAppSecret, timeout int) beego.FilterFunc { return func(ctx *context.Context) { From 8995b291a9ca44029f590f79525cfeeee29ff126 Mon Sep 17 00:00:00 2001 From: Waleed Gadelkareem Date: Thu, 14 Feb 2019 16:29:26 +0100 Subject: [PATCH 54/80] Make LogAccess public --- controller.go | 2 +- error.go | 2 +- router.go | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/controller.go b/controller.go index 7859681f..9c605760 100644 --- a/controller.go +++ b/controller.go @@ -291,7 +291,7 @@ func (c *Controller) viewPath() string { // Redirect sends the redirection response to url with status code. func (c *Controller) Redirect(url string, code int) { - logAccess(c.Ctx, nil, code) + LogAccess(c.Ctx, nil, code) c.Ctx.Redirect(code, url) } diff --git a/error.go b/error.go index 727830df..e5e9fd47 100644 --- a/error.go +++ b/error.go @@ -435,7 +435,7 @@ func exception(errCode string, ctx *context.Context) { func executeError(err *errorInfo, ctx *context.Context, code int) { //make sure to log the error in the access log - logAccess(ctx, nil, code) + LogAccess(ctx, nil, code) if err.errorType == errorTypeHandler { ctx.ResponseWriter.WriteHeader(code) diff --git a/router.go b/router.go index 851934a8..c5d0cda4 100644 --- a/router.go +++ b/router.go @@ -889,7 +889,7 @@ Admin: statusCode = 200 } - logAccess(context, &startTime, statusCode) + LogAccess(context, &startTime, statusCode) timeDur := time.Since(startTime) context.ResponseWriter.Elapsed = timeDur @@ -980,7 +980,7 @@ func toURL(params map[string]string) string { return strings.TrimRight(u, "&") } -func logAccess(ctx *beecontext.Context, startTime *time.Time, statusCode int) { +func LogAccess(ctx *beecontext.Context, startTime *time.Time, statusCode int) { //Skip logging if AccessLogs config is false if !BConfig.Log.AccessLogs { return From 94ed35e781d54833b27c13c2e4ba0f48932f604f Mon Sep 17 00:00:00 2001 From: Nedzad Smajic Date: Sat, 23 Feb 2019 22:49:32 +0100 Subject: [PATCH 55/80] Register .gohtml extension Goland as of 2018.3 seems to support only '.tpl.gohtml" and ".gohtml" templates. The regular ".tpl" templates will be rendered as plain text files which is not acceptable. --- template.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/template.go b/template.go index 264ce931..59875be7 100644 --- a/template.go +++ b/template.go @@ -38,7 +38,7 @@ var ( beeViewPathTemplates = make(map[string]map[string]*template.Template) templatesLock sync.RWMutex // beeTemplateExt stores the template extension which will build - beeTemplateExt = []string{"tpl", "html"} + beeTemplateExt = []string{"tpl", "html", "gohtml"} // beeTemplatePreprocessors stores associations of extension -> preprocessor handler beeTemplateEngines = map[string]templatePreProcessor{} beeTemplateFS = defaultFSFunc From 8454e8417e63125417a80f349f6528d4d234b885 Mon Sep 17 00:00:00 2001 From: grahamjamesaddis Date: Fri, 1 Mar 2019 11:27:32 +0000 Subject: [PATCH 56/80] Allow forked beego project to pass travis ci builds --- .travis.yml | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3a3a6f66..2bd0f004 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,9 +9,19 @@ services: - postgresql - memcached env: - - ORM_DRIVER=sqlite3 ORM_SOURCE=$TRAVIS_BUILD_DIR/orm_test.db - - ORM_DRIVER=postgres ORM_SOURCE="user=postgres dbname=orm_test sslmode=disable" + global: + - GO_REPO_FULLNAME="github.com/astaxie/beego" + matrix: + - ORM_DRIVER=sqlite3 ORM_SOURCE=$TRAVIS_BUILD_DIR/orm_test.db + - ORM_DRIVER=postgres ORM_SOURCE="user=postgres dbname=orm_test sslmode=disable" before_install: + # link the local repo with ${GOPATH}/src// + - GO_REPO_NAMESPACE=${GO_REPO_FULLNAME%/*} + # relies on GOPATH to contain only one directory... + - mkdir -p ${GOPATH}/src/${GO_REPO_NAMESPACE} + - ln -sv ${TRAVIS_BUILD_DIR} ${GOPATH}/src/${GO_REPO_FULLNAME} + - cd ${GOPATH}/src/${GO_REPO_FULLNAME} + # get and build ssdb - git clone git://github.com/ideawu/ssdb.git - cd ssdb - make From aba51d99a18eede16aba81def3de68d1a6c4c5db Mon Sep 17 00:00:00 2001 From: hellomrlee Date: Mon, 4 Mar 2019 11:05:29 +0800 Subject: [PATCH 57/80] spelling mistake of word "Header" --- grace/grace.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grace/grace.go b/grace/grace.go index 5a8bc3b8..fb0cb7bb 100644 --- a/grace/grace.go +++ b/grace/grace.go @@ -78,7 +78,7 @@ var ( DefaultReadTimeOut time.Duration // DefaultWriteTimeOut is the HTTP Write timeout DefaultWriteTimeOut time.Duration - // DefaultMaxHeaderBytes is the Max HTTP Herder size, default is 0, no limit + // DefaultMaxHeaderBytes is the Max HTTP Header size, default is 0, no limit DefaultMaxHeaderBytes int // DefaultTimeout is the shutdown server's timeout. default is 60s DefaultTimeout = 60 * time.Second From 52f8ccd06c034d61fb2038997211ce8d6d4fa609 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Thu, 7 Mar 2019 17:15:30 +0800 Subject: [PATCH 58/80] TestToJson bug fixed --- httplib/httplib_test.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/httplib/httplib_test.go b/httplib/httplib_test.go index 8970b764..7314ae01 100644 --- a/httplib/httplib_test.go +++ b/httplib/httplib_test.go @@ -206,10 +206,16 @@ func TestToJson(t *testing.T) { t.Fatal(err) } t.Log(ip.Origin) - - if n := strings.Count(ip.Origin, "."); n != 3 { + ips := strings.Split(ip.Origin, ",") + if len(ips) == 0 { t.Fatal("response is not valid ip") } + for i := range ips { + if net.ParseIP(strings.TrimSpace(ips[i])).To4() == nil { + t.Fatal("response is not valid ip") + } + } + } func TestToFile(t *testing.T) { From 6dd5171fdfd9fd2e002cb4ce1372d75cfaf6032a Mon Sep 17 00:00:00 2001 From: JessonChan Date: Fri, 8 Mar 2019 11:08:39 +0800 Subject: [PATCH 59/80] logger color function refactor,easy to read and run more quickly --- logs/logger.go | 61 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 22 deletions(-) diff --git a/logs/logger.go b/logs/logger.go index 428d3aa0..b6f0c86b 100644 --- a/logs/logger.go +++ b/logs/logger.go @@ -18,6 +18,7 @@ import ( "fmt" "io" "os" + "runtime" "sync" "time" ) @@ -33,7 +34,7 @@ func newLogWriter(wr io.Writer) *logWriter { func (lg *logWriter) println(when time.Time, msg string) { lg.Lock() - h, _, _:= formatTimeHeader(when) + h, _, _ := formatTimeHeader(when) lg.writer.Write(append(append(h, msg...), '\n')) lg.Unlock() } @@ -146,21 +147,50 @@ var ( reset = string([]byte{27, 91, 48, 109}) ) +var once sync.Once +var colorMap map[string]string + +func initColor() { + if runtime.GOOS == "windows" { + green = w32Green + white = w32White + yellow = w32Yellow + red = w32Red + blue = w32Blue + magenta = w32Magenta + cyan = w32Cyan + } + colorMap = map[string]string{ + "green": green, + "white": white, + "yellow": yellow, + "red": red, + "GET": blue, + "POST": cyan, + "PUT": yellow, + "DELETE": red, + "PATCH": green, + "HEAD": magenta, + "OPTIONS": white, + } +} + // ColorByStatus return color by http code // 2xx return Green // 3xx return White // 4xx return Yellow // 5xx return Red func ColorByStatus(cond bool, code int) string { + once.Do(initColor) switch { case code >= 200 && code < 300: - return map[bool]string{true: green, false: w32Green}[cond] + return colorMap["green"] case code >= 300 && code < 400: - return map[bool]string{true: white, false: w32White}[cond] + return colorMap["white"] case code >= 400 && code < 500: - return map[bool]string{true: yellow, false: w32Yellow}[cond] + return colorMap["yellow"] default: - return map[bool]string{true: red, false: w32Red}[cond] + return colorMap["red"] } } @@ -173,24 +203,11 @@ func ColorByStatus(cond bool, code int) string { // HEAD return Magenta // OPTIONS return WHITE func ColorByMethod(cond bool, method string) string { - switch method { - case "GET": - return map[bool]string{true: blue, false: w32Blue}[cond] - case "POST": - return map[bool]string{true: cyan, false: w32Cyan}[cond] - case "PUT": - return map[bool]string{true: yellow, false: w32Yellow}[cond] - case "DELETE": - return map[bool]string{true: red, false: w32Red}[cond] - case "PATCH": - return map[bool]string{true: green, false: w32Green}[cond] - case "HEAD": - return map[bool]string{true: magenta, false: w32Magenta}[cond] - case "OPTIONS": - return map[bool]string{true: white, false: w32White}[cond] - default: - return reset + once.Do(initColor) + if c := colorMap[method]; c != "" { + return c } + return reset } // Guard Mutex to guarantee atomic of W32Debug(string) function From 4a5e10852775164ae03a8cfffe5b86a1f11f018a Mon Sep 17 00:00:00 2001 From: JessonChan Date: Fri, 8 Mar 2019 11:50:30 +0800 Subject: [PATCH 60/80] logger color function refactor,easy to read and run more quickly --- logs/logger.go | 8 ++++++-- router.go | 37 ++++++++++++++++--------------------- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/logs/logger.go b/logs/logger.go index b6f0c86b..c744d45c 100644 --- a/logs/logger.go +++ b/logs/logger.go @@ -180,7 +180,7 @@ func initColor() { // 3xx return White // 4xx return Yellow // 5xx return Red -func ColorByStatus(cond bool, code int) string { +func ColorByStatus(code int) string { once.Do(initColor) switch { case code >= 200 && code < 300: @@ -202,7 +202,7 @@ func ColorByStatus(cond bool, code int) string { // PATCH return Green // HEAD return Magenta // OPTIONS return WHITE -func ColorByMethod(cond bool, method string) string { +func ColorByMethod(method string) string { once.Do(initColor) if c := colorMap[method]; c != "" { return c @@ -210,6 +210,10 @@ func ColorByMethod(cond bool, method string) string { return reset } +func ResetColor() string { + return reset +} + // Guard Mutex to guarantee atomic of W32Debug(string) function var mu sync.Mutex diff --git a/router.go b/router.go index c5d0cda4..946635d9 100644 --- a/router.go +++ b/router.go @@ -900,34 +900,29 @@ Admin: } if FilterMonitorFunc(r.Method, r.URL.Path, timeDur, pattern, statusCode) { + routerName := "" if runRouter != nil { - go toolbox.StatisticsMap.AddStatistics(r.Method, r.URL.Path, runRouter.Name(), timeDur) - } else { - go toolbox.StatisticsMap.AddStatistics(r.Method, r.URL.Path, "", timeDur) + routerName = runRouter.Name() } + go toolbox.StatisticsMap.AddStatistics(r.Method, r.URL.Path, routerName, timeDur) } } if BConfig.RunMode == DEV && !BConfig.Log.AccessLogs { - var devInfo string - iswin := (runtime.GOOS == "windows") - statusColor := logs.ColorByStatus(iswin, statusCode) - methodColor := logs.ColorByMethod(iswin, r.Method) - resetColor := logs.ColorByMethod(iswin, "") - if findRouter { - if routerInfo != nil { - devInfo = fmt.Sprintf("|%15s|%s %3d %s|%13s|%8s|%s %-7s %s %-3s r:%s", context.Input.IP(), statusColor, statusCode, - resetColor, timeDur.String(), "match", methodColor, r.Method, resetColor, r.URL.Path, - routerInfo.pattern) - } else { - devInfo = fmt.Sprintf("|%15s|%s %3d %s|%13s|%8s|%s %-7s %s %-3s", context.Input.IP(), statusColor, statusCode, resetColor, - timeDur.String(), "match", methodColor, r.Method, resetColor, r.URL.Path) - } - } else { - devInfo = fmt.Sprintf("|%15s|%s %3d %s|%13s|%8s|%s %-7s %s %-3s", context.Input.IP(), statusColor, statusCode, resetColor, - timeDur.String(), "nomatch", methodColor, r.Method, resetColor, r.URL.Path) + match := map[bool]string{true: "match", false: "nomatch"} + devInfo := fmt.Sprintf("|%15s|%s %3d %s|%13s|%8s|%s %-7s %s %-3s", + context.Input.IP(), + logs.ColorByStatus(statusCode), statusCode, logs.ResetColor(), + timeDur.String(), + match[findRouter], + logs.ColorByMethod(r.Method), r.Method, logs.ResetColor(), + r.URL.Path) + if routerInfo != nil { + devInfo += fmt.Sprintf(" r:%s", routerInfo.pattern) } - if iswin { + + //todo one logger enough,in fact no need to separate logger into windows and others + if runtime.GOOS == "windows" { logs.W32Debug(devInfo) } else { logs.Debug(devInfo) From 8432a1c758eef59cfd1f3ebda8209a5e9bf3a377 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Fri, 8 Mar 2019 12:10:57 +0800 Subject: [PATCH 61/80] better comment for color map --- logs/logger.go | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/logs/logger.go b/logs/logger.go index c744d45c..cf793cc0 100644 --- a/logs/logger.go +++ b/logs/logger.go @@ -161,10 +161,12 @@ func initColor() { cyan = w32Cyan } colorMap = map[string]string{ - "green": green, - "white": white, - "yellow": yellow, - "red": red, + //by color + "green": green, + "white": white, + "yellow": yellow, + "red": red, + //by method "GET": blue, "POST": cyan, "PUT": yellow, @@ -195,13 +197,6 @@ func ColorByStatus(code int) string { } // ColorByMethod return color by http code -// GET return Blue -// POST return Cyan -// PUT return Yellow -// DELETE return Red -// PATCH return Green -// HEAD return Magenta -// OPTIONS return WHITE func ColorByMethod(method string) string { once.Do(initColor) if c := colorMap[method]; c != "" { From 121fab61f1afc3434544dba303027d48abf2b092 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Fri, 8 Mar 2019 12:18:45 +0800 Subject: [PATCH 62/80] ResetColor function --- logs/logger.go | 1 + 1 file changed, 1 insertion(+) diff --git a/logs/logger.go b/logs/logger.go index cf793cc0..cdcd63e9 100644 --- a/logs/logger.go +++ b/logs/logger.go @@ -205,6 +205,7 @@ func ColorByMethod(method string) string { return reset } +// ResetColor return reset color func ResetColor() string { return reset } From 93485df3d2e193d42d411349c998598bd2155734 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Fri, 8 Mar 2019 14:42:06 +0800 Subject: [PATCH 63/80] color should be false by default otherwise the http logger's color would be wrong --- logs/console.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/logs/console.go b/logs/console.go index e75f2a1b..43ff417a 100644 --- a/logs/console.go +++ b/logs/console.go @@ -56,7 +56,7 @@ func NewConsole() Logger { cw := &consoleWriter{ lg: newLogWriter(os.Stdout), Level: LevelDebug, - Colorful: runtime.GOOS != "windows", + Colorful: false, } return cw } From 578440a18de7990e37a47e9b13349387952f9b9c Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 12 Mar 2019 12:09:41 +0800 Subject: [PATCH 64/80] add ansicolor to beego --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 3a3a6f66..92e53577 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,6 +36,7 @@ install: - go get github.com/casbin/casbin - go get github.com/elazarl/go-bindata-assetfs - go get github.com/OwnLocal/goes + - go get github.com/shiena/ansicolor - go get -u honnef.co/go/tools/cmd/staticcheck - go get -u github.com/mdempsky/unconvert - go get -u github.com/gordonklaus/ineffassign From 661dcbb6cafeeb9e7451f23da1fae227ba3260e7 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 12 Mar 2019 12:11:25 +0800 Subject: [PATCH 65/80] router logger modify --- router.go | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/router.go b/router.go index 946635d9..7fae248e 100644 --- a/router.go +++ b/router.go @@ -21,7 +21,6 @@ import ( "path" "path/filepath" "reflect" - "runtime" "strconv" "strings" "sync" @@ -921,12 +920,7 @@ Admin: devInfo += fmt.Sprintf(" r:%s", routerInfo.pattern) } - //todo one logger enough,in fact no need to separate logger into windows and others - if runtime.GOOS == "windows" { - logs.W32Debug(devInfo) - } else { - logs.Debug(devInfo) - } + logs.Debug(devInfo) } // Call WriteHeader if status code has been set changed if context.Output.Status != 0 { From 0ba77a0d8725d62980b25e7acd4ec40f0c9945cd Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 12 Mar 2019 12:12:59 +0800 Subject: [PATCH 66/80] colorful is the switch to level label --- logs/console.go | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/logs/console.go b/logs/console.go index 43ff417a..73c623f5 100644 --- a/logs/console.go +++ b/logs/console.go @@ -17,8 +17,10 @@ package logs import ( "encoding/json" "os" - "runtime" + "strings" "time" + + "github.com/shiena/ansicolor" ) // brush is a color join function @@ -54,9 +56,9 @@ type consoleWriter struct { // NewConsole create ConsoleWriter returning as LoggerInterface. func NewConsole() Logger { cw := &consoleWriter{ - lg: newLogWriter(os.Stdout), + lg: newLogWriter(ansicolor.NewAnsiColorWriter(os.Stdout)), Level: LevelDebug, - Colorful: false, + Colorful: true, } return cw } @@ -67,11 +69,7 @@ func (c *consoleWriter) Init(jsonConfig string) error { if len(jsonConfig) == 0 { return nil } - err := json.Unmarshal([]byte(jsonConfig), c) - if runtime.GOOS == "windows" { - c.Colorful = false - } - return err + return json.Unmarshal([]byte(jsonConfig), c) } // WriteMsg write message in console. @@ -80,7 +78,7 @@ func (c *consoleWriter) WriteMsg(when time.Time, msg string, level int) error { return nil } if c.Colorful { - msg = colors[level](msg) + msg = strings.Replace(msg, levelPrefix[level], colors[level](levelPrefix[level]), 1) } c.lg.println(when, msg) return nil From c0fae547e9f204c9b5e191ad8ff99a58de17cc21 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 12 Mar 2019 12:14:09 +0800 Subject: [PATCH 67/80] remove ansicolor code,import ansicolor package --- logs/color.go | 28 --- logs/color_windows.go | 428 ------------------------------------- logs/color_windows_test.go | 294 ------------------------- logs/log.go | 8 +- logs/logger.go | 50 ----- 5 files changed, 4 insertions(+), 804 deletions(-) delete mode 100644 logs/color.go delete mode 100644 logs/color_windows.go delete mode 100644 logs/color_windows_test.go diff --git a/logs/color.go b/logs/color.go deleted file mode 100644 index 41d23638..00000000 --- a/logs/color.go +++ /dev/null @@ -1,28 +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. - -// +build !windows - -package logs - -import "io" - -type ansiColorWriter struct { - w io.Writer - mode outputMode -} - -func (cw *ansiColorWriter) Write(p []byte) (int, error) { - return cw.w.Write(p) -} diff --git a/logs/color_windows.go b/logs/color_windows.go deleted file mode 100644 index 4e28f188..00000000 --- a/logs/color_windows.go +++ /dev/null @@ -1,428 +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. - -// +build windows - -package logs - -import ( - "bytes" - "io" - "strings" - "syscall" - "unsafe" -) - -type ( - csiState int - parseResult int -) - -const ( - outsideCsiCode csiState = iota - firstCsiCode - secondCsiCode -) - -const ( - noConsole parseResult = iota - changedColor - unknown -) - -type ansiColorWriter struct { - w io.Writer - mode outputMode - state csiState - paramStartBuf bytes.Buffer - paramBuf bytes.Buffer -} - -const ( - firstCsiChar byte = '\x1b' - secondeCsiChar byte = '[' - separatorChar byte = ';' - sgrCode byte = 'm' -) - -const ( - foregroundBlue = uint16(0x0001) - foregroundGreen = uint16(0x0002) - foregroundRed = uint16(0x0004) - foregroundIntensity = uint16(0x0008) - backgroundBlue = uint16(0x0010) - backgroundGreen = uint16(0x0020) - backgroundRed = uint16(0x0040) - backgroundIntensity = uint16(0x0080) - underscore = uint16(0x8000) - - foregroundMask = foregroundBlue | foregroundGreen | foregroundRed | foregroundIntensity - backgroundMask = backgroundBlue | backgroundGreen | backgroundRed | backgroundIntensity -) - -const ( - ansiReset = "0" - ansiIntensityOn = "1" - ansiIntensityOff = "21" - ansiUnderlineOn = "4" - ansiUnderlineOff = "24" - ansiBlinkOn = "5" - ansiBlinkOff = "25" - - ansiForegroundBlack = "30" - ansiForegroundRed = "31" - ansiForegroundGreen = "32" - ansiForegroundYellow = "33" - ansiForegroundBlue = "34" - ansiForegroundMagenta = "35" - ansiForegroundCyan = "36" - ansiForegroundWhite = "37" - ansiForegroundDefault = "39" - - ansiBackgroundBlack = "40" - ansiBackgroundRed = "41" - ansiBackgroundGreen = "42" - ansiBackgroundYellow = "43" - ansiBackgroundBlue = "44" - ansiBackgroundMagenta = "45" - ansiBackgroundCyan = "46" - ansiBackgroundWhite = "47" - ansiBackgroundDefault = "49" - - ansiLightForegroundGray = "90" - ansiLightForegroundRed = "91" - ansiLightForegroundGreen = "92" - ansiLightForegroundYellow = "93" - ansiLightForegroundBlue = "94" - ansiLightForegroundMagenta = "95" - ansiLightForegroundCyan = "96" - ansiLightForegroundWhite = "97" - - ansiLightBackgroundGray = "100" - ansiLightBackgroundRed = "101" - ansiLightBackgroundGreen = "102" - ansiLightBackgroundYellow = "103" - ansiLightBackgroundBlue = "104" - ansiLightBackgroundMagenta = "105" - ansiLightBackgroundCyan = "106" - ansiLightBackgroundWhite = "107" -) - -type drawType int - -const ( - foreground drawType = iota - background -) - -type winColor struct { - code uint16 - drawType drawType -} - -var colorMap = map[string]winColor{ - ansiForegroundBlack: {0, foreground}, - ansiForegroundRed: {foregroundRed, foreground}, - ansiForegroundGreen: {foregroundGreen, foreground}, - ansiForegroundYellow: {foregroundRed | foregroundGreen, foreground}, - ansiForegroundBlue: {foregroundBlue, foreground}, - ansiForegroundMagenta: {foregroundRed | foregroundBlue, foreground}, - ansiForegroundCyan: {foregroundGreen | foregroundBlue, foreground}, - ansiForegroundWhite: {foregroundRed | foregroundGreen | foregroundBlue, foreground}, - ansiForegroundDefault: {foregroundRed | foregroundGreen | foregroundBlue, foreground}, - - ansiBackgroundBlack: {0, background}, - ansiBackgroundRed: {backgroundRed, background}, - ansiBackgroundGreen: {backgroundGreen, background}, - ansiBackgroundYellow: {backgroundRed | backgroundGreen, background}, - ansiBackgroundBlue: {backgroundBlue, background}, - ansiBackgroundMagenta: {backgroundRed | backgroundBlue, background}, - ansiBackgroundCyan: {backgroundGreen | backgroundBlue, background}, - ansiBackgroundWhite: {backgroundRed | backgroundGreen | backgroundBlue, background}, - ansiBackgroundDefault: {0, background}, - - ansiLightForegroundGray: {foregroundIntensity, foreground}, - ansiLightForegroundRed: {foregroundIntensity | foregroundRed, foreground}, - ansiLightForegroundGreen: {foregroundIntensity | foregroundGreen, foreground}, - ansiLightForegroundYellow: {foregroundIntensity | foregroundRed | foregroundGreen, foreground}, - ansiLightForegroundBlue: {foregroundIntensity | foregroundBlue, foreground}, - ansiLightForegroundMagenta: {foregroundIntensity | foregroundRed | foregroundBlue, foreground}, - ansiLightForegroundCyan: {foregroundIntensity | foregroundGreen | foregroundBlue, foreground}, - ansiLightForegroundWhite: {foregroundIntensity | foregroundRed | foregroundGreen | foregroundBlue, foreground}, - - ansiLightBackgroundGray: {backgroundIntensity, background}, - ansiLightBackgroundRed: {backgroundIntensity | backgroundRed, background}, - ansiLightBackgroundGreen: {backgroundIntensity | backgroundGreen, background}, - ansiLightBackgroundYellow: {backgroundIntensity | backgroundRed | backgroundGreen, background}, - ansiLightBackgroundBlue: {backgroundIntensity | backgroundBlue, background}, - ansiLightBackgroundMagenta: {backgroundIntensity | backgroundRed | backgroundBlue, background}, - ansiLightBackgroundCyan: {backgroundIntensity | backgroundGreen | backgroundBlue, background}, - ansiLightBackgroundWhite: {backgroundIntensity | backgroundRed | backgroundGreen | backgroundBlue, background}, -} - -var ( - kernel32 = syscall.NewLazyDLL("kernel32.dll") - procSetConsoleTextAttribute = kernel32.NewProc("SetConsoleTextAttribute") - procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo") - defaultAttr *textAttributes -) - -func init() { - screenInfo := getConsoleScreenBufferInfo(uintptr(syscall.Stdout)) - if screenInfo != nil { - colorMap[ansiForegroundDefault] = winColor{ - screenInfo.WAttributes & (foregroundRed | foregroundGreen | foregroundBlue), - foreground, - } - colorMap[ansiBackgroundDefault] = winColor{ - screenInfo.WAttributes & (backgroundRed | backgroundGreen | backgroundBlue), - background, - } - defaultAttr = convertTextAttr(screenInfo.WAttributes) - } -} - -type coord struct { - X, Y int16 -} - -type smallRect struct { - Left, Top, Right, Bottom int16 -} - -type consoleScreenBufferInfo struct { - DwSize coord - DwCursorPosition coord - WAttributes uint16 - SrWindow smallRect - DwMaximumWindowSize coord -} - -func getConsoleScreenBufferInfo(hConsoleOutput uintptr) *consoleScreenBufferInfo { - var csbi consoleScreenBufferInfo - ret, _, _ := procGetConsoleScreenBufferInfo.Call( - hConsoleOutput, - uintptr(unsafe.Pointer(&csbi))) - if ret == 0 { - return nil - } - return &csbi -} - -func setConsoleTextAttribute(hConsoleOutput uintptr, wAttributes uint16) bool { - ret, _, _ := procSetConsoleTextAttribute.Call( - hConsoleOutput, - uintptr(wAttributes)) - return ret != 0 -} - -type textAttributes struct { - foregroundColor uint16 - backgroundColor uint16 - foregroundIntensity uint16 - backgroundIntensity uint16 - underscore uint16 - otherAttributes uint16 -} - -func convertTextAttr(winAttr uint16) *textAttributes { - fgColor := winAttr & (foregroundRed | foregroundGreen | foregroundBlue) - bgColor := winAttr & (backgroundRed | backgroundGreen | backgroundBlue) - fgIntensity := winAttr & foregroundIntensity - bgIntensity := winAttr & backgroundIntensity - underline := winAttr & underscore - otherAttributes := winAttr &^ (foregroundMask | backgroundMask | underscore) - return &textAttributes{fgColor, bgColor, fgIntensity, bgIntensity, underline, otherAttributes} -} - -func convertWinAttr(textAttr *textAttributes) uint16 { - var winAttr uint16 - winAttr |= textAttr.foregroundColor - winAttr |= textAttr.backgroundColor - winAttr |= textAttr.foregroundIntensity - winAttr |= textAttr.backgroundIntensity - winAttr |= textAttr.underscore - winAttr |= textAttr.otherAttributes - return winAttr -} - -func changeColor(param []byte) parseResult { - screenInfo := getConsoleScreenBufferInfo(uintptr(syscall.Stdout)) - if screenInfo == nil { - return noConsole - } - - winAttr := convertTextAttr(screenInfo.WAttributes) - strParam := string(param) - if len(strParam) <= 0 { - strParam = "0" - } - csiParam := strings.Split(strParam, string(separatorChar)) - for _, p := range csiParam { - c, ok := colorMap[p] - switch { - case !ok: - switch p { - case ansiReset: - winAttr.foregroundColor = defaultAttr.foregroundColor - winAttr.backgroundColor = defaultAttr.backgroundColor - winAttr.foregroundIntensity = defaultAttr.foregroundIntensity - winAttr.backgroundIntensity = defaultAttr.backgroundIntensity - winAttr.underscore = 0 - winAttr.otherAttributes = 0 - case ansiIntensityOn: - winAttr.foregroundIntensity = foregroundIntensity - case ansiIntensityOff: - winAttr.foregroundIntensity = 0 - case ansiUnderlineOn: - winAttr.underscore = underscore - case ansiUnderlineOff: - winAttr.underscore = 0 - case ansiBlinkOn: - winAttr.backgroundIntensity = backgroundIntensity - case ansiBlinkOff: - winAttr.backgroundIntensity = 0 - default: - // unknown code - } - case c.drawType == foreground: - winAttr.foregroundColor = c.code - case c.drawType == background: - winAttr.backgroundColor = c.code - } - } - winTextAttribute := convertWinAttr(winAttr) - setConsoleTextAttribute(uintptr(syscall.Stdout), winTextAttribute) - - return changedColor -} - -func parseEscapeSequence(command byte, param []byte) parseResult { - if defaultAttr == nil { - return noConsole - } - - switch command { - case sgrCode: - return changeColor(param) - default: - return unknown - } -} - -func (cw *ansiColorWriter) flushBuffer() (int, error) { - return cw.flushTo(cw.w) -} - -func (cw *ansiColorWriter) resetBuffer() (int, error) { - return cw.flushTo(nil) -} - -func (cw *ansiColorWriter) flushTo(w io.Writer) (int, error) { - var n1, n2 int - var err error - - startBytes := cw.paramStartBuf.Bytes() - cw.paramStartBuf.Reset() - if w != nil { - n1, err = cw.w.Write(startBytes) - if err != nil { - return n1, err - } - } else { - n1 = len(startBytes) - } - paramBytes := cw.paramBuf.Bytes() - cw.paramBuf.Reset() - if w != nil { - n2, err = cw.w.Write(paramBytes) - if err != nil { - return n1 + n2, err - } - } else { - n2 = len(paramBytes) - } - return n1 + n2, nil -} - -func isParameterChar(b byte) bool { - return ('0' <= b && b <= '9') || b == separatorChar -} - -func (cw *ansiColorWriter) Write(p []byte) (int, error) { - var r, nw, first, last int - if cw.mode != DiscardNonColorEscSeq { - cw.state = outsideCsiCode - cw.resetBuffer() - } - - var err error - for i, ch := range p { - switch cw.state { - case outsideCsiCode: - if ch == firstCsiChar { - cw.paramStartBuf.WriteByte(ch) - cw.state = firstCsiCode - } - case firstCsiCode: - switch ch { - case firstCsiChar: - cw.paramStartBuf.WriteByte(ch) - break - case secondeCsiChar: - cw.paramStartBuf.WriteByte(ch) - cw.state = secondCsiCode - last = i - 1 - default: - cw.resetBuffer() - cw.state = outsideCsiCode - } - case secondCsiCode: - if isParameterChar(ch) { - cw.paramBuf.WriteByte(ch) - } else { - nw, err = cw.w.Write(p[first:last]) - r += nw - if err != nil { - return r, err - } - first = i + 1 - result := parseEscapeSequence(ch, cw.paramBuf.Bytes()) - if result == noConsole || (cw.mode == OutputNonColorEscSeq && result == unknown) { - cw.paramBuf.WriteByte(ch) - nw, err := cw.flushBuffer() - if err != nil { - return r, err - } - r += nw - } else { - n, _ := cw.resetBuffer() - // Add one more to the size of the buffer for the last ch - r += n + 1 - } - - cw.state = outsideCsiCode - } - default: - cw.state = outsideCsiCode - } - } - - if cw.mode != DiscardNonColorEscSeq || cw.state == outsideCsiCode { - nw, err = cw.w.Write(p[first:]) - r += nw - } - - return r, err -} diff --git a/logs/color_windows_test.go b/logs/color_windows_test.go deleted file mode 100644 index 5074841a..00000000 --- a/logs/color_windows_test.go +++ /dev/null @@ -1,294 +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. - -// +build windows - -package logs - -import ( - "bytes" - "fmt" - "syscall" - "testing" -) - -var GetConsoleScreenBufferInfo = getConsoleScreenBufferInfo - -func ChangeColor(color uint16) { - setConsoleTextAttribute(uintptr(syscall.Stdout), color) -} - -func ResetColor() { - ChangeColor(uint16(0x0007)) -} - -func TestWritePlanText(t *testing.T) { - inner := bytes.NewBufferString("") - w := NewAnsiColorWriter(inner) - expected := "plain text" - fmt.Fprintf(w, expected) - actual := inner.String() - if actual != expected { - t.Errorf("Get %q, want %q", actual, expected) - } -} - -func TestWriteParseText(t *testing.T) { - inner := bytes.NewBufferString("") - w := NewAnsiColorWriter(inner) - - inputTail := "\x1b[0mtail text" - expectedTail := "tail text" - fmt.Fprintf(w, inputTail) - actualTail := inner.String() - inner.Reset() - if actualTail != expectedTail { - t.Errorf("Get %q, want %q", actualTail, expectedTail) - } - - inputHead := "head text\x1b[0m" - expectedHead := "head text" - fmt.Fprintf(w, inputHead) - actualHead := inner.String() - inner.Reset() - if actualHead != expectedHead { - t.Errorf("Get %q, want %q", actualHead, expectedHead) - } - - inputBothEnds := "both ends \x1b[0m text" - expectedBothEnds := "both ends text" - fmt.Fprintf(w, inputBothEnds) - actualBothEnds := inner.String() - inner.Reset() - if actualBothEnds != expectedBothEnds { - t.Errorf("Get %q, want %q", actualBothEnds, expectedBothEnds) - } - - inputManyEsc := "\x1b\x1b\x1b\x1b[0m many esc" - expectedManyEsc := "\x1b\x1b\x1b many esc" - fmt.Fprintf(w, inputManyEsc) - actualManyEsc := inner.String() - inner.Reset() - if actualManyEsc != expectedManyEsc { - t.Errorf("Get %q, want %q", actualManyEsc, expectedManyEsc) - } - - expectedSplit := "split text" - for _, ch := range "split \x1b[0m text" { - fmt.Fprintf(w, string(ch)) - } - actualSplit := inner.String() - inner.Reset() - if actualSplit != expectedSplit { - t.Errorf("Get %q, want %q", actualSplit, expectedSplit) - } -} - -type screenNotFoundError struct { - error -} - -func writeAnsiColor(expectedText, colorCode string) (actualText string, actualAttributes uint16, err error) { - inner := bytes.NewBufferString("") - w := NewAnsiColorWriter(inner) - fmt.Fprintf(w, "\x1b[%sm%s", colorCode, expectedText) - - actualText = inner.String() - screenInfo := GetConsoleScreenBufferInfo(uintptr(syscall.Stdout)) - if screenInfo != nil { - actualAttributes = screenInfo.WAttributes - } else { - err = &screenNotFoundError{} - } - return -} - -type testParam struct { - text string - attributes uint16 - ansiColor string -} - -func TestWriteAnsiColorText(t *testing.T) { - screenInfo := GetConsoleScreenBufferInfo(uintptr(syscall.Stdout)) - if screenInfo == nil { - t.Fatal("Could not get ConsoleScreenBufferInfo") - } - defer ChangeColor(screenInfo.WAttributes) - defaultFgColor := screenInfo.WAttributes & uint16(0x0007) - defaultBgColor := screenInfo.WAttributes & uint16(0x0070) - defaultFgIntensity := screenInfo.WAttributes & uint16(0x0008) - defaultBgIntensity := screenInfo.WAttributes & uint16(0x0080) - - fgParam := []testParam{ - {"foreground black ", uint16(0x0000 | 0x0000), "30"}, - {"foreground red ", uint16(0x0004 | 0x0000), "31"}, - {"foreground green ", uint16(0x0002 | 0x0000), "32"}, - {"foreground yellow ", uint16(0x0006 | 0x0000), "33"}, - {"foreground blue ", uint16(0x0001 | 0x0000), "34"}, - {"foreground magenta", uint16(0x0005 | 0x0000), "35"}, - {"foreground cyan ", uint16(0x0003 | 0x0000), "36"}, - {"foreground white ", uint16(0x0007 | 0x0000), "37"}, - {"foreground default", defaultFgColor | 0x0000, "39"}, - {"foreground light gray ", uint16(0x0000 | 0x0008 | 0x0000), "90"}, - {"foreground light red ", uint16(0x0004 | 0x0008 | 0x0000), "91"}, - {"foreground light green ", uint16(0x0002 | 0x0008 | 0x0000), "92"}, - {"foreground light yellow ", uint16(0x0006 | 0x0008 | 0x0000), "93"}, - {"foreground light blue ", uint16(0x0001 | 0x0008 | 0x0000), "94"}, - {"foreground light magenta", uint16(0x0005 | 0x0008 | 0x0000), "95"}, - {"foreground light cyan ", uint16(0x0003 | 0x0008 | 0x0000), "96"}, - {"foreground light white ", uint16(0x0007 | 0x0008 | 0x0000), "97"}, - } - - bgParam := []testParam{ - {"background black ", uint16(0x0007 | 0x0000), "40"}, - {"background red ", uint16(0x0007 | 0x0040), "41"}, - {"background green ", uint16(0x0007 | 0x0020), "42"}, - {"background yellow ", uint16(0x0007 | 0x0060), "43"}, - {"background blue ", uint16(0x0007 | 0x0010), "44"}, - {"background magenta", uint16(0x0007 | 0x0050), "45"}, - {"background cyan ", uint16(0x0007 | 0x0030), "46"}, - {"background white ", uint16(0x0007 | 0x0070), "47"}, - {"background default", uint16(0x0007) | defaultBgColor, "49"}, - {"background light gray ", uint16(0x0007 | 0x0000 | 0x0080), "100"}, - {"background light red ", uint16(0x0007 | 0x0040 | 0x0080), "101"}, - {"background light green ", uint16(0x0007 | 0x0020 | 0x0080), "102"}, - {"background light yellow ", uint16(0x0007 | 0x0060 | 0x0080), "103"}, - {"background light blue ", uint16(0x0007 | 0x0010 | 0x0080), "104"}, - {"background light magenta", uint16(0x0007 | 0x0050 | 0x0080), "105"}, - {"background light cyan ", uint16(0x0007 | 0x0030 | 0x0080), "106"}, - {"background light white ", uint16(0x0007 | 0x0070 | 0x0080), "107"}, - } - - resetParam := []testParam{ - {"all reset", defaultFgColor | defaultBgColor | defaultFgIntensity | defaultBgIntensity, "0"}, - {"all reset", defaultFgColor | defaultBgColor | defaultFgIntensity | defaultBgIntensity, ""}, - } - - boldParam := []testParam{ - {"bold on", uint16(0x0007 | 0x0008), "1"}, - {"bold off", uint16(0x0007), "21"}, - } - - underscoreParam := []testParam{ - {"underscore on", uint16(0x0007 | 0x8000), "4"}, - {"underscore off", uint16(0x0007), "24"}, - } - - blinkParam := []testParam{ - {"blink on", uint16(0x0007 | 0x0080), "5"}, - {"blink off", uint16(0x0007), "25"}, - } - - mixedParam := []testParam{ - {"both black, bold, underline, blink", uint16(0x0000 | 0x0000 | 0x0008 | 0x8000 | 0x0080), "30;40;1;4;5"}, - {"both red, bold, underline, blink", uint16(0x0004 | 0x0040 | 0x0008 | 0x8000 | 0x0080), "31;41;1;4;5"}, - {"both green, bold, underline, blink", uint16(0x0002 | 0x0020 | 0x0008 | 0x8000 | 0x0080), "32;42;1;4;5"}, - {"both yellow, bold, underline, blink", uint16(0x0006 | 0x0060 | 0x0008 | 0x8000 | 0x0080), "33;43;1;4;5"}, - {"both blue, bold, underline, blink", uint16(0x0001 | 0x0010 | 0x0008 | 0x8000 | 0x0080), "34;44;1;4;5"}, - {"both magenta, bold, underline, blink", uint16(0x0005 | 0x0050 | 0x0008 | 0x8000 | 0x0080), "35;45;1;4;5"}, - {"both cyan, bold, underline, blink", uint16(0x0003 | 0x0030 | 0x0008 | 0x8000 | 0x0080), "36;46;1;4;5"}, - {"both white, bold, underline, blink", uint16(0x0007 | 0x0070 | 0x0008 | 0x8000 | 0x0080), "37;47;1;4;5"}, - {"both default, bold, underline, blink", uint16(defaultFgColor | defaultBgColor | 0x0008 | 0x8000 | 0x0080), "39;49;1;4;5"}, - } - - assertTextAttribute := func(expectedText string, expectedAttributes uint16, ansiColor string) { - actualText, actualAttributes, err := writeAnsiColor(expectedText, ansiColor) - if actualText != expectedText { - t.Errorf("Get %q, want %q", actualText, expectedText) - } - if err != nil { - t.Fatal("Could not get ConsoleScreenBufferInfo") - } - if actualAttributes != expectedAttributes { - t.Errorf("Text: %q, Get 0x%04x, want 0x%04x", expectedText, actualAttributes, expectedAttributes) - } - } - - for _, v := range fgParam { - ResetColor() - assertTextAttribute(v.text, v.attributes, v.ansiColor) - } - - for _, v := range bgParam { - ChangeColor(uint16(0x0070 | 0x0007)) - assertTextAttribute(v.text, v.attributes, v.ansiColor) - } - - for _, v := range resetParam { - ChangeColor(uint16(0x0000 | 0x0070 | 0x0008)) - assertTextAttribute(v.text, v.attributes, v.ansiColor) - } - - ResetColor() - for _, v := range boldParam { - assertTextAttribute(v.text, v.attributes, v.ansiColor) - } - - ResetColor() - for _, v := range underscoreParam { - assertTextAttribute(v.text, v.attributes, v.ansiColor) - } - - ResetColor() - for _, v := range blinkParam { - assertTextAttribute(v.text, v.attributes, v.ansiColor) - } - - for _, v := range mixedParam { - ResetColor() - assertTextAttribute(v.text, v.attributes, v.ansiColor) - } -} - -func TestIgnoreUnknownSequences(t *testing.T) { - inner := bytes.NewBufferString("") - w := NewModeAnsiColorWriter(inner, OutputNonColorEscSeq) - - inputText := "\x1b[=decpath mode" - expectedTail := inputText - fmt.Fprintf(w, inputText) - actualTail := inner.String() - inner.Reset() - if actualTail != expectedTail { - t.Errorf("Get %q, want %q", actualTail, expectedTail) - } - - inputText = "\x1b[=tailing esc and bracket\x1b[" - expectedTail = inputText - fmt.Fprintf(w, inputText) - actualTail = inner.String() - inner.Reset() - if actualTail != expectedTail { - t.Errorf("Get %q, want %q", actualTail, expectedTail) - } - - inputText = "\x1b[?tailing esc\x1b" - expectedTail = inputText - fmt.Fprintf(w, inputText) - actualTail = inner.String() - inner.Reset() - if actualTail != expectedTail { - t.Errorf("Get %q, want %q", actualTail, expectedTail) - } - - inputText = "\x1b[1h;3punended color code invalid\x1b3" - expectedTail = inputText - fmt.Fprintf(w, inputText) - actualTail = inner.String() - inner.Reset() - if actualTail != expectedTail { - t.Errorf("Get %q, want %q", actualTail, expectedTail) - } -} diff --git a/logs/log.go b/logs/log.go index a3614165..3bf9c5f4 100644 --- a/logs/log.go +++ b/logs/log.go @@ -47,7 +47,7 @@ import ( // RFC5424 log message levels. const ( - LevelEmergency = iota + LevelEmergency = iota LevelAlert LevelCritical LevelError @@ -92,7 +92,7 @@ type Logger interface { } var adapters = make(map[string]newLoggerFunc) -var levelPrefix = [LevelDebug + 1]string{"[M] ", "[A] ", "[C] ", "[E] ", "[W] ", "[N] ", "[I] ", "[D] "} +var levelPrefix = [LevelDebug + 1]string{"[M]", "[A]", "[C]", "[E]", "[W]", "[N]", "[I]", "[D]"} // Register makes a log provide available by the provided name. // If Register is called twice with the same name or if driver is nil, @@ -248,7 +248,7 @@ func (bl *BeeLogger) Write(p []byte) (n int, err error) { } // writeMsg will always add a '\n' character if p[len(p)-1] == '\n' { - p = p[0: len(p)-1] + p = p[0 : len(p)-1] } // set levelLoggerImpl to ensure all log message will be write out err = bl.writeMsg(levelLoggerImpl, string(p)) @@ -287,7 +287,7 @@ func (bl *BeeLogger) writeMsg(logLevel int, msg string, v ...interface{}) error // set to emergency to ensure all log will be print out correctly logLevel = LevelEmergency } else { - msg = levelPrefix[logLevel] + msg + msg = levelPrefix[logLevel] + " " + msg } if bl.asynchronous { diff --git a/logs/logger.go b/logs/logger.go index cdcd63e9..06bf0f69 100644 --- a/logs/logger.go +++ b/logs/logger.go @@ -15,9 +15,7 @@ package logs import ( - "fmt" "io" - "os" "runtime" "sync" "time" @@ -39,40 +37,6 @@ func (lg *logWriter) println(when time.Time, msg string) { lg.Unlock() } -type outputMode int - -// DiscardNonColorEscSeq supports the divided color escape sequence. -// But non-color escape sequence is not output. -// Please use the OutputNonColorEscSeq If you want to output a non-color -// escape sequences such as ncurses. However, it does not support the divided -// color escape sequence. -const ( - _ outputMode = iota - DiscardNonColorEscSeq - OutputNonColorEscSeq -) - -// NewAnsiColorWriter creates and initializes a new ansiColorWriter -// using io.Writer w as its initial contents. -// In the console of Windows, which change the foreground and background -// colors of the text by the escape sequence. -// In the console of other systems, which writes to w all text. -func NewAnsiColorWriter(w io.Writer) io.Writer { - return NewModeAnsiColorWriter(w, DiscardNonColorEscSeq) -} - -// NewModeAnsiColorWriter create and initializes a new ansiColorWriter -// by specifying the outputMode. -func NewModeAnsiColorWriter(w io.Writer, mode outputMode) io.Writer { - if _, ok := w.(*ansiColorWriter); !ok { - return &ansiColorWriter{ - w: w, - mode: mode, - } - } - return w -} - const ( y1 = `0123456789` y2 = `0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789` @@ -209,17 +173,3 @@ func ColorByMethod(method string) string { func ResetColor() string { return reset } - -// Guard Mutex to guarantee atomic of W32Debug(string) function -var mu sync.Mutex - -// W32Debug Helper method to output colored logs in Windows terminals -func W32Debug(msg string) { - mu.Lock() - defer mu.Unlock() - - current := time.Now() - w := NewAnsiColorWriter(os.Stdout) - - fmt.Fprintf(w, "[beego] %v %s\n", current.Format("2006/01/02 - 15:04:05"), msg) -} From 7693502aaa65b2a62e4aea005d2ee21250fa3dc4 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 12 Mar 2019 13:20:13 +0800 Subject: [PATCH 68/80] logAdapter is more readable --- logs/log.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/logs/log.go b/logs/log.go index 3bf9c5f4..49f3794f 100644 --- a/logs/log.go +++ b/logs/log.go @@ -187,12 +187,12 @@ func (bl *BeeLogger) setLogger(adapterName string, configs ...string) error { } } - log, ok := adapters[adapterName] + logAdapter, ok := adapters[adapterName] if !ok { return fmt.Errorf("logs: unknown adaptername %q (forgotten Register?)", adapterName) } - lg := log() + lg := logAdapter() err := lg.Init(config) if err != nil { fmt.Fprintln(os.Stderr, "logs.BeeLogger.SetLogger: "+err.Error()) From 9cecb221703a4b845b50b47abaecf3bd1ecd41cc Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 12 Mar 2019 15:13:54 +0800 Subject: [PATCH 69/80] NewAnsiColorWriter remove --- logs/logger_test.go | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/logs/logger_test.go b/logs/logger_test.go index 78c67737..debe2e90 100644 --- a/logs/logger_test.go +++ b/logs/logger_test.go @@ -57,19 +57,3 @@ func TestFormatHeader_1(t *testing.T) { } } -func TestNewAnsiColor1(t *testing.T) { - inner := bytes.NewBufferString("") - w := NewAnsiColorWriter(inner) - if w == inner { - t.Errorf("Get %#v, want %#v", w, inner) - } -} - -func TestNewAnsiColor2(t *testing.T) { - inner := bytes.NewBufferString("") - w1 := NewAnsiColorWriter(inner) - w2 := NewAnsiColorWriter(w1) - if w1 != w2 { - t.Errorf("Get %#v, want %#v", w1, w2) - } -} From 44a1a8f6bef9008e15be4810a031b495a0b08542 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 12 Mar 2019 15:51:43 +0800 Subject: [PATCH 70/80] println is builtin function --- logs/conn.go | 2 +- logs/console.go | 2 +- logs/logger.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/logs/conn.go b/logs/conn.go index 6d5bf6bf..afe0cbb7 100644 --- a/logs/conn.go +++ b/logs/conn.go @@ -63,7 +63,7 @@ func (c *connWriter) WriteMsg(when time.Time, msg string, level int) error { defer c.innerWriter.Close() } - c.lg.println(when, msg) + c.lg.writeln(when, msg) return nil } diff --git a/logs/console.go b/logs/console.go index 73c623f5..3dcaee1d 100644 --- a/logs/console.go +++ b/logs/console.go @@ -80,7 +80,7 @@ func (c *consoleWriter) WriteMsg(when time.Time, msg string, level int) error { if c.Colorful { msg = strings.Replace(msg, levelPrefix[level], colors[level](levelPrefix[level]), 1) } - c.lg.println(when, msg) + c.lg.writeln(when, msg) return nil } diff --git a/logs/logger.go b/logs/logger.go index 06bf0f69..c7cf8a56 100644 --- a/logs/logger.go +++ b/logs/logger.go @@ -30,7 +30,7 @@ func newLogWriter(wr io.Writer) *logWriter { return &logWriter{writer: wr} } -func (lg *logWriter) println(when time.Time, msg string) { +func (lg *logWriter) writeln(when time.Time, msg string) { lg.Lock() h, _, _ := formatTimeHeader(when) lg.writer.Write(append(append(h, msg...), '\n')) From 4564e9810c487ea6c19e8072f0847294442b43f4 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 12 Mar 2019 16:36:00 +0800 Subject: [PATCH 71/80] logger_test imported and not used: "bytes" --- logs/logger_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/logs/logger_test.go b/logs/logger_test.go index debe2e90..15be500d 100644 --- a/logs/logger_test.go +++ b/logs/logger_test.go @@ -15,7 +15,6 @@ package logs import ( - "bytes" "testing" "time" ) @@ -56,4 +55,3 @@ func TestFormatHeader_1(t *testing.T) { tm = tm.Add(dur) } } - From ea91e7638c39ae38cdda9e11918dacc21ff899a0 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 12 Mar 2019 17:01:23 +0800 Subject: [PATCH 72/80] move log function to log package --- app.go | 4 +-- log.go | 111 --------------------------------------------------------- 2 files changed, 2 insertions(+), 113 deletions(-) delete mode 100644 log.go diff --git a/app.go b/app.go index 32ff159d..d9e85e9b 100644 --- a/app.go +++ b/app.go @@ -176,7 +176,7 @@ func (app *App) Run(mws ...MiddleWare) { if BConfig.Listen.HTTPSPort != 0 { app.Server.Addr = fmt.Sprintf("%s:%d", BConfig.Listen.HTTPSAddr, BConfig.Listen.HTTPSPort) } else if BConfig.Listen.EnableHTTP { - BeeLogger.Info("Start https server error, conflict with http. Please reset https port") + logs.Info("Start https server error, conflict with http. Please reset https port") return } logs.Info("https server Running on https://%s", app.Server.Addr) @@ -192,7 +192,7 @@ func (app *App) Run(mws ...MiddleWare) { pool := x509.NewCertPool() data, err := ioutil.ReadFile(BConfig.Listen.TrustCaFile) if err != nil { - BeeLogger.Info("MutualHTTPS should provide TrustCaFile") + logs.Info("MutualHTTPS should provide TrustCaFile") return } pool.AppendCertsFromPEM(data) diff --git a/log.go b/log.go deleted file mode 100644 index e9412f92..00000000 --- a/log.go +++ /dev/null @@ -1,111 +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 beego - -import ( - "strings" - - "github.com/astaxie/beego/logs" -) - -// Log levels to control the logging output. -const ( - LevelEmergency = iota - LevelAlert - LevelCritical - LevelError - LevelWarning - LevelNotice - LevelInformational - LevelDebug -) - -// BeeLogger references the used application logger. -var BeeLogger = logs.GetBeeLogger() - -// SetLevel sets the global log level used by the simple logger. -func SetLevel(l int) { - logs.SetLevel(l) -} - -// SetLogFuncCall set the CallDepth, default is 3 -func SetLogFuncCall(b bool) { - logs.SetLogFuncCall(b) -} - -// SetLogger sets a new logger. -func SetLogger(adaptername string, config string) error { - return logs.SetLogger(adaptername, config) -} - -// Emergency logs a message at emergency level. -func Emergency(v ...interface{}) { - logs.Emergency(generateFmtStr(len(v)), v...) -} - -// Alert logs a message at alert level. -func Alert(v ...interface{}) { - logs.Alert(generateFmtStr(len(v)), v...) -} - -// Critical logs a message at critical level. -func Critical(v ...interface{}) { - logs.Critical(generateFmtStr(len(v)), v...) -} - -// Error logs a message at error level. -func Error(v ...interface{}) { - logs.Error(generateFmtStr(len(v)), v...) -} - -// Warning logs a message at warning level. -func Warning(v ...interface{}) { - logs.Warning(generateFmtStr(len(v)), v...) -} - -// Warn compatibility alias for Warning() -func Warn(v ...interface{}) { - logs.Warn(generateFmtStr(len(v)), v...) -} - -// Notice logs a message at notice level. -func Notice(v ...interface{}) { - logs.Notice(generateFmtStr(len(v)), v...) -} - -// Informational logs a message at info level. -func Informational(v ...interface{}) { - logs.Informational(generateFmtStr(len(v)), v...) -} - -// Info compatibility alias for Warning() -func Info(v ...interface{}) { - logs.Info(generateFmtStr(len(v)), v...) -} - -// Debug logs a message at debug level. -func Debug(v ...interface{}) { - logs.Debug(generateFmtStr(len(v)), v...) -} - -// Trace logs a message at trace level. -// compatibility alias for Warning() -func Trace(v ...interface{}) { - logs.Trace(generateFmtStr(len(v)), v...) -} - -func generateFmtStr(n int) string { - return strings.Repeat("%v ", n) -} From 95ff8170192aa249d97dea1db695a96d2c631466 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Wed, 13 Mar 2019 09:41:13 +0800 Subject: [PATCH 73/80] undefined: beego.BeeLogger fixed --- migration/ddl.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/migration/ddl.go b/migration/ddl.go index 9313acf8..cd2c1c49 100644 --- a/migration/ddl.go +++ b/migration/ddl.go @@ -17,7 +17,7 @@ package migration import ( "fmt" - "github.com/astaxie/beego" + "github.com/astaxie/beego/logs" ) // Index struct defines the structure of Index Columns @@ -316,7 +316,7 @@ func (m *Migration) GetSQL() (sql string) { sql += fmt.Sprintf("ALTER TABLE `%s` ", m.TableName) for index, column := range m.Columns { if !column.remove { - beego.BeeLogger.Info("col") + logs.Info("col") sql += fmt.Sprintf("\n ADD `%s` %s %s %s %s %s", column.Name, column.DataType, column.Unsign, column.Null, column.Inc, column.Default) } else { sql += fmt.Sprintf("\n DROP COLUMN `%s`", column.Name) From be31bd2bbd3c6642a46f6b282b79ceeca4b1dcf1 Mon Sep 17 00:00:00 2001 From: Yanhui Shen Date: Wed, 13 Mar 2019 16:24:04 +0800 Subject: [PATCH 74/80] Ensure custom error handler is called --- router.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/router.go b/router.go index c5d0cda4..52c56632 100644 --- a/router.go +++ b/router.go @@ -690,7 +690,7 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) // filter wrong http method if !HTTPMETHOD[r.Method] { - http.Error(rw, "Method Not Allowed", http.StatusMethodNotAllowed) + exception("405", context) goto Admin } From 914bbfd7105eda78199b3620b3d935495348725d Mon Sep 17 00:00:00 2001 From: Daniel Ramirez Grave de Peralta Date: Thu, 14 Mar 2019 09:14:12 -0400 Subject: [PATCH 75/80] Update apiauth.go fixed infinite recursive call --- plugins/apiauth/apiauth.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/apiauth/apiauth.go b/plugins/apiauth/apiauth.go index aa8c1960..10e25f3f 100644 --- a/plugins/apiauth/apiauth.go +++ b/plugins/apiauth/apiauth.go @@ -85,7 +85,7 @@ func APIBasicAuth(appid, appkey string) beego.FilterFunc { // APIBaiscAuth calls APIBasicAuth for previous callers func APIBaiscAuth(appid, appkey string) beego.FilterFunc { - return APIBaiscAuth(appid, appkey) + return APIBasicAuth(appid, appkey) } // APISecretAuth use AppIdToAppSecret verify and From 005391be81e129fe41477a78a416b690f81f4b75 Mon Sep 17 00:00:00 2001 From: BaoyangChai Date: Sat, 23 Mar 2019 00:33:26 +0800 Subject: [PATCH 76/80] update --- orm/db.go | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/orm/db.go b/orm/db.go index 2719dff7..df69eec3 100644 --- a/orm/db.go +++ b/orm/db.go @@ -631,14 +631,8 @@ func (d *dbBase) Update(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time. } if find { - newSetNames := make([]string, 0, len(setNames)-1) - newSetNames = append(newSetNames, setNames[0:index]...) - newSetNames = append(newSetNames, setNames[index+1:]...) - setNames = newSetNames - newSetValues := make([]interface{}, 0, len(setNames)-1) - newSetValues = append(newSetValues, setValues[0:index]...) - newSetValues = append(newSetValues, setValues[index+1:]...) - setValues = newSetValues + setNames = append(setNames[0:index], setNames[index+1:]...) + setValues = append(setValues[0:index], setValues[index+1:]...) } From 3b00cfccec18dac833c3afddcf1fc7839fc59fd1 Mon Sep 17 00:00:00 2001 From: "Yang, Gao" Date: Sun, 24 Mar 2019 14:41:28 +0800 Subject: [PATCH 77/80] [Fix] Fix the issue that genRouterCode incorrect logic results in @Import annotations getting overwritten --- parser.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/parser.go b/parser.go index a8690274..81990a4a 100644 --- a/parser.go +++ b/parser.go @@ -459,13 +459,17 @@ func genRouterCode(pkgRealpath string) { imports := "" if len(c.ImportComments) > 0 { for _, i := range c.ImportComments { + var s string if i.ImportAlias != "" { - imports += fmt.Sprintf(` + s = fmt.Sprintf(` %s "%s"`, i.ImportAlias, i.ImportPath) } else { - imports += fmt.Sprintf(` + s = fmt.Sprintf(` "%s"`, i.ImportPath) } + if !strings.Contains(globalimport, s) { + imports += s + } } } @@ -490,7 +494,7 @@ func genRouterCode(pkgRealpath string) { }`, filters) } - globalimport = imports + globalimport += imports globalinfo = globalinfo + ` beego.GlobalControllerRouter["` + k + `"] = append(beego.GlobalControllerRouter["` + k + `"], From 0b8ebaf38755bcbfa51443fb6ba55eef3c268a51 Mon Sep 17 00:00:00 2001 From: GeorgeXc Date: Tue, 26 Mar 2019 01:00:04 +0800 Subject: [PATCH 78/80] Update db.go --- orm/db.go | 1 - 1 file changed, 1 deletion(-) diff --git a/orm/db.go b/orm/db.go index df69eec3..20d9c4cd 100644 --- a/orm/db.go +++ b/orm/db.go @@ -633,7 +633,6 @@ func (d *dbBase) Update(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time. if find { setNames = append(setNames[0:index], setNames[index+1:]...) setValues = append(setValues[0:index], setValues[index+1:]...) - } setValues = append(setValues, pkValue) From c0ecf32d177f2bdf251392f9c1c8890bb88ee90f Mon Sep 17 00:00:00 2001 From: astaxie Date: Tue, 2 Apr 2019 21:53:01 +0800 Subject: [PATCH 79/80] update travis --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 6ddcfcf5..1bb121a2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,6 @@ language: go go: - - "1.10.x" - "1.11.x" services: - redis-server From 3086081ec02803c7cb73fc7c40b7c656698b36dc Mon Sep 17 00:00:00 2001 From: astaxie Date: Sat, 6 Apr 2019 13:50:14 +0800 Subject: [PATCH 80/80] v1.11.2 --- beego.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beego.go b/beego.go index ff89f2f5..7ebea8a2 100644 --- a/beego.go +++ b/beego.go @@ -23,7 +23,7 @@ import ( const ( // VERSION represent beego web framework version. - VERSION = "1.11.1" + VERSION = "1.11.2" // DEV is for develop DEV = "dev"