mirror of
https://github.com/astaxie/beego.git
synced 2025-01-15 18:57:13 +00:00
commit
8ef8fd2606
@ -36,8 +36,7 @@ install:
|
||||
- go get github.com/beego/goyaml2
|
||||
- go get gopkg.in/yaml.v2
|
||||
- go get github.com/belogik/goes
|
||||
- go get github.com/siddontang/ledisdb/config
|
||||
- go get github.com/siddontang/ledisdb/ledis
|
||||
- go get github.com/ledisdb/ledisdb
|
||||
- go get github.com/ssdb/gossdb/ssdb
|
||||
- go get github.com/cloudflare/golz4
|
||||
- go get github.com/gogo/protobuf/proto
|
||||
@ -49,7 +48,7 @@ install:
|
||||
- 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
|
||||
- go get -u golang.org/x/lint/golint
|
||||
- go get -u github.com/go-redis/redis
|
||||
before_script:
|
||||
- psql --version
|
||||
|
@ -33,6 +33,8 @@ Congratulations! You've just built your first **beego** app.
|
||||
|
||||
###### Please see [Documentation](http://beego.me/docs) for more.
|
||||
|
||||
###### [beego-example](https://github.com/beego-dev/beego-example)
|
||||
|
||||
## Features
|
||||
|
||||
* RESTful support
|
||||
|
53
admin.go
53
admin.go
@ -24,6 +24,8 @@ import (
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
|
||||
"github.com/astaxie/beego/grace"
|
||||
"github.com/astaxie/beego/logs"
|
||||
"github.com/astaxie/beego/toolbox"
|
||||
@ -55,12 +57,14 @@ func init() {
|
||||
beeAdminApp = &adminApp{
|
||||
routers: make(map[string]http.HandlerFunc),
|
||||
}
|
||||
// keep in mind that all data should be html escaped to avoid XSS attack
|
||||
beeAdminApp.Route("/", adminIndex)
|
||||
beeAdminApp.Route("/qps", qpsIndex)
|
||||
beeAdminApp.Route("/prof", profIndex)
|
||||
beeAdminApp.Route("/healthcheck", healthcheck)
|
||||
beeAdminApp.Route("/task", taskStatus)
|
||||
beeAdminApp.Route("/listconf", listConf)
|
||||
beeAdminApp.Route("/metrics", promhttp.Handler().ServeHTTP)
|
||||
FilterMonitorFunc = func(string, string, time.Duration, string, int) bool { return true }
|
||||
}
|
||||
|
||||
@ -105,8 +109,8 @@ func listConf(rw http.ResponseWriter, r *http.Request) {
|
||||
case "conf":
|
||||
m := make(M)
|
||||
list("BConfig", BConfig, m)
|
||||
m["AppConfigPath"] = appConfigPath
|
||||
m["AppConfigProvider"] = appConfigProvider
|
||||
m["AppConfigPath"] = template.HTMLEscapeString(appConfigPath)
|
||||
m["AppConfigProvider"] = template.HTMLEscapeString(appConfigProvider)
|
||||
tmpl := template.Must(template.New("dashboard").Parse(dashboardTpl))
|
||||
tmpl = template.Must(tmpl.Parse(configTpl))
|
||||
tmpl = template.Must(tmpl.Parse(defaultScriptsTpl))
|
||||
@ -151,8 +155,9 @@ func listConf(rw http.ResponseWriter, r *http.Request) {
|
||||
resultList := new([][]string)
|
||||
for _, f := range bf {
|
||||
var result = []string{
|
||||
f.pattern,
|
||||
utils.GetFuncName(f.filterFunc),
|
||||
// void xss
|
||||
template.HTMLEscapeString(f.pattern),
|
||||
template.HTMLEscapeString(utils.GetFuncName(f.filterFunc)),
|
||||
}
|
||||
*resultList = append(*resultList, result)
|
||||
}
|
||||
@ -207,8 +212,8 @@ func PrintTree() M {
|
||||
|
||||
printTree(resultList, t)
|
||||
|
||||
methods = append(methods, method)
|
||||
methodsData[method] = resultList
|
||||
methods = append(methods, template.HTMLEscapeString(method))
|
||||
methodsData[template.HTMLEscapeString(method)] = resultList
|
||||
}
|
||||
|
||||
content["Data"] = methodsData
|
||||
@ -227,21 +232,21 @@ func printTree(resultList *[][]string, t *Tree) {
|
||||
if v, ok := l.runObject.(*ControllerInfo); ok {
|
||||
if v.routerType == routerTypeBeego {
|
||||
var result = []string{
|
||||
v.pattern,
|
||||
fmt.Sprintf("%s", v.methods),
|
||||
v.controllerType.String(),
|
||||
template.HTMLEscapeString(v.pattern),
|
||||
template.HTMLEscapeString(fmt.Sprintf("%s", v.methods)),
|
||||
template.HTMLEscapeString(v.controllerType.String()),
|
||||
}
|
||||
*resultList = append(*resultList, result)
|
||||
} else if v.routerType == routerTypeRESTFul {
|
||||
var result = []string{
|
||||
v.pattern,
|
||||
fmt.Sprintf("%s", v.methods),
|
||||
template.HTMLEscapeString(v.pattern),
|
||||
template.HTMLEscapeString(fmt.Sprintf("%s", v.methods)),
|
||||
"",
|
||||
}
|
||||
*resultList = append(*resultList, result)
|
||||
} else if v.routerType == routerTypeHandler {
|
||||
var result = []string{
|
||||
v.pattern,
|
||||
template.HTMLEscapeString(v.pattern),
|
||||
"",
|
||||
"",
|
||||
}
|
||||
@ -266,7 +271,7 @@ func profIndex(rw http.ResponseWriter, r *http.Request) {
|
||||
result bytes.Buffer
|
||||
)
|
||||
toolbox.ProcessInput(command, &result)
|
||||
data["Content"] = result.String()
|
||||
data["Content"] = template.HTMLEscapeString(result.String())
|
||||
|
||||
if format == "json" && command == "gc summary" {
|
||||
dataJSON, err := json.Marshal(data)
|
||||
@ -280,7 +285,7 @@ func profIndex(rw http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
data["Title"] = command
|
||||
data["Title"] = template.HTMLEscapeString(command)
|
||||
defaultTpl := defaultScriptsTpl
|
||||
if command == "gc summary" {
|
||||
defaultTpl = gcAjaxTpl
|
||||
@ -304,13 +309,13 @@ func healthcheck(rw http.ResponseWriter, _ *http.Request) {
|
||||
if err := h.Check(); err != nil {
|
||||
result = []string{
|
||||
"error",
|
||||
name,
|
||||
err.Error(),
|
||||
template.HTMLEscapeString(name),
|
||||
template.HTMLEscapeString(err.Error()),
|
||||
}
|
||||
} else {
|
||||
result = []string{
|
||||
"success",
|
||||
name,
|
||||
template.HTMLEscapeString(name),
|
||||
"OK",
|
||||
}
|
||||
}
|
||||
@ -334,11 +339,11 @@ func taskStatus(rw http.ResponseWriter, req *http.Request) {
|
||||
if taskname != "" {
|
||||
if t, ok := toolbox.AdminTaskList[taskname]; ok {
|
||||
if err := t.Run(); err != nil {
|
||||
data["Message"] = []string{"error", fmt.Sprintf("%s", err)}
|
||||
data["Message"] = []string{"error", template.HTMLEscapeString(fmt.Sprintf("%s", err))}
|
||||
}
|
||||
data["Message"] = []string{"success", fmt.Sprintf("%s run success,Now the Status is <br>%s", taskname, t.GetStatus())}
|
||||
data["Message"] = []string{"success", template.HTMLEscapeString(fmt.Sprintf("%s run success,Now the Status is <br>%s", taskname, t.GetStatus()))}
|
||||
} else {
|
||||
data["Message"] = []string{"warning", fmt.Sprintf("there's no task which named: %s", taskname)}
|
||||
data["Message"] = []string{"warning", template.HTMLEscapeString(fmt.Sprintf("there's no task which named: %s", taskname))}
|
||||
}
|
||||
}
|
||||
|
||||
@ -354,10 +359,10 @@ func taskStatus(rw http.ResponseWriter, req *http.Request) {
|
||||
}
|
||||
for tname, tk := range toolbox.AdminTaskList {
|
||||
result := []string{
|
||||
tname,
|
||||
tk.GetSpec(),
|
||||
tk.GetStatus(),
|
||||
tk.GetPrev().String(),
|
||||
template.HTMLEscapeString(tname),
|
||||
template.HTMLEscapeString(tk.GetSpec()),
|
||||
template.HTMLEscapeString(tk.GetStatus()),
|
||||
template.HTMLEscapeString(tk.GetPrev().String()),
|
||||
}
|
||||
*resultList = append(*resultList, result)
|
||||
}
|
||||
|
@ -52,6 +52,8 @@ func oldMap() M {
|
||||
m["BConfig.WebConfig.DirectoryIndex"] = BConfig.WebConfig.DirectoryIndex
|
||||
m["BConfig.WebConfig.StaticDir"] = BConfig.WebConfig.StaticDir
|
||||
m["BConfig.WebConfig.StaticExtensionsToGzip"] = BConfig.WebConfig.StaticExtensionsToGzip
|
||||
m["BConfig.WebConfig.StaticCacheFileSize"] = BConfig.WebConfig.StaticCacheFileSize
|
||||
m["BConfig.WebConfig.StaticCacheFileNum"] = BConfig.WebConfig.StaticCacheFileNum
|
||||
m["BConfig.WebConfig.TemplateLeft"] = BConfig.WebConfig.TemplateLeft
|
||||
m["BConfig.WebConfig.TemplateRight"] = BConfig.WebConfig.TemplateRight
|
||||
m["BConfig.WebConfig.ViewsPath"] = BConfig.WebConfig.ViewsPath
|
||||
|
9
app.go
9
app.go
@ -123,14 +123,13 @@ func (app *App) Run(mws ...MiddleWare) {
|
||||
httpsAddr = fmt.Sprintf("%s:%d", BConfig.Listen.HTTPSAddr, BConfig.Listen.HTTPSPort)
|
||||
app.Server.Addr = httpsAddr
|
||||
}
|
||||
server := grace.NewServer(httpsAddr, app.Handlers)
|
||||
server := grace.NewServer(httpsAddr, app.Server.Handler)
|
||||
server.Server.ReadTimeout = app.Server.ReadTimeout
|
||||
server.Server.WriteTimeout = app.Server.WriteTimeout
|
||||
if BConfig.Listen.EnableMutualHTTPS {
|
||||
if err := server.ListenAndServeMutualTLS(BConfig.Listen.HTTPSCertFile, BConfig.Listen.HTTPSKeyFile, BConfig.Listen.TrustCaFile); err != nil {
|
||||
logs.Critical("ListenAndServeTLS: ", err, fmt.Sprintf("%d", os.Getpid()))
|
||||
time.Sleep(100 * time.Microsecond)
|
||||
endRunning <- true
|
||||
}
|
||||
} else {
|
||||
if BConfig.Listen.AutoTLS {
|
||||
@ -145,14 +144,14 @@ func (app *App) Run(mws ...MiddleWare) {
|
||||
if err := server.ListenAndServeTLS(BConfig.Listen.HTTPSCertFile, BConfig.Listen.HTTPSKeyFile); err != nil {
|
||||
logs.Critical("ListenAndServeTLS: ", err, fmt.Sprintf("%d", os.Getpid()))
|
||||
time.Sleep(100 * time.Microsecond)
|
||||
endRunning <- true
|
||||
}
|
||||
}
|
||||
endRunning <- true
|
||||
}()
|
||||
}
|
||||
if BConfig.Listen.EnableHTTP {
|
||||
go func() {
|
||||
server := grace.NewServer(addr, app.Handlers)
|
||||
server := grace.NewServer(addr, app.Server.Handler)
|
||||
server.Server.ReadTimeout = app.Server.ReadTimeout
|
||||
server.Server.WriteTimeout = app.Server.WriteTimeout
|
||||
if BConfig.Listen.ListenTCP4 {
|
||||
@ -161,8 +160,8 @@ func (app *App) Run(mws ...MiddleWare) {
|
||||
if err := server.ListenAndServe(); err != nil {
|
||||
logs.Critical("ListenAndServe: ", err, fmt.Sprintf("%d", os.Getpid()))
|
||||
time.Sleep(100 * time.Microsecond)
|
||||
endRunning <- true
|
||||
}
|
||||
endRunning <- true
|
||||
}()
|
||||
}
|
||||
<-endRunning
|
||||
|
2
beego.go
2
beego.go
@ -23,7 +23,7 @@ import (
|
||||
|
||||
const (
|
||||
// VERSION represent beego web framework version.
|
||||
VERSION = "1.12.1"
|
||||
VERSION = "1.12.2"
|
||||
|
||||
// DEV is for develop
|
||||
DEV = "dev"
|
||||
|
27
build_info.go
Normal file
27
build_info.go
Normal file
@ -0,0 +1,27 @@
|
||||
// Copyright 2020 astaxie
|
||||
//
|
||||
// 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
|
||||
|
||||
var (
|
||||
BuildVersion string
|
||||
BuildGitRevision string
|
||||
BuildStatus string
|
||||
BuildTag string
|
||||
BuildTime string
|
||||
|
||||
GoVersion string
|
||||
|
||||
GitBranch string
|
||||
)
|
3
cache/memory.go
vendored
3
cache/memory.go
vendored
@ -218,9 +218,12 @@ func (bc *MemoryCache) vacuum() {
|
||||
}
|
||||
for {
|
||||
<-time.After(bc.dur)
|
||||
bc.RLock()
|
||||
if bc.items == nil {
|
||||
bc.RUnlock()
|
||||
return
|
||||
}
|
||||
bc.RUnlock()
|
||||
if keys := bc.expiredKeys(); len(keys) != 0 {
|
||||
bc.clearItems(keys)
|
||||
}
|
||||
|
49
cache/redis/redis.go
vendored
49
cache/redis/redis.go
vendored
@ -55,6 +55,9 @@ type Cache struct {
|
||||
key string
|
||||
password string
|
||||
maxIdle int
|
||||
|
||||
//the timeout to a value less than the redis server's timeout.
|
||||
timeout time.Duration
|
||||
}
|
||||
|
||||
// NewRedisCache create new redis cache with default collection name.
|
||||
@ -137,12 +140,12 @@ func (rc *Cache) Decr(key string) error {
|
||||
|
||||
// ClearAll clean all cache in redis. delete this redis collection.
|
||||
func (rc *Cache) ClearAll() error {
|
||||
c := rc.p.Get()
|
||||
defer c.Close()
|
||||
cachedKeys, err := redis.Strings(c.Do("KEYS", rc.key+":*"))
|
||||
cachedKeys, err := rc.Scan(rc.key + ":*")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c := rc.p.Get()
|
||||
defer c.Close()
|
||||
for _, str := range cachedKeys {
|
||||
if _, err = c.Do("DEL", str); err != nil {
|
||||
return err
|
||||
@ -151,6 +154,35 @@ func (rc *Cache) ClearAll() error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Scan scan all keys matching the pattern. a better choice than `keys`
|
||||
func (rc *Cache) Scan(pattern string) (keys []string, err error) {
|
||||
c := rc.p.Get()
|
||||
defer c.Close()
|
||||
var (
|
||||
cursor uint64 = 0 // start
|
||||
result []interface{}
|
||||
list []string
|
||||
)
|
||||
for {
|
||||
result, err = redis.Values(c.Do("SCAN", cursor, "MATCH", pattern, "COUNT", 1024))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
list, err = redis.Strings(result[1], nil)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
keys = append(keys, list...)
|
||||
cursor, err = redis.Uint64(result[0], nil)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if cursor == 0 { // over
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// StartAndGC start redis cache adapter.
|
||||
// config is like {"key":"collection key","conn":"connection info","dbNum":"0"}
|
||||
// the cache item in redis are stored forever,
|
||||
@ -182,12 +214,21 @@ func (rc *Cache) StartAndGC(config string) error {
|
||||
if _, ok := cf["maxIdle"]; !ok {
|
||||
cf["maxIdle"] = "3"
|
||||
}
|
||||
if _, ok := cf["timeout"]; !ok {
|
||||
cf["timeout"] = "180s"
|
||||
}
|
||||
rc.key = cf["key"]
|
||||
rc.conninfo = cf["conn"]
|
||||
rc.dbNum, _ = strconv.Atoi(cf["dbNum"])
|
||||
rc.password = cf["password"]
|
||||
rc.maxIdle, _ = strconv.Atoi(cf["maxIdle"])
|
||||
|
||||
if v, err := time.ParseDuration(cf["timeout"]); err == nil {
|
||||
rc.timeout = v
|
||||
} else {
|
||||
rc.timeout = 180 * time.Second
|
||||
}
|
||||
|
||||
rc.connectInit()
|
||||
|
||||
c := rc.p.Get()
|
||||
@ -221,7 +262,7 @@ func (rc *Cache) connectInit() {
|
||||
// initialize a new pool
|
||||
rc.p = &redis.Pool{
|
||||
MaxIdle: rc.maxIdle,
|
||||
IdleTimeout: 180 * time.Second,
|
||||
IdleTimeout: rc.timeout,
|
||||
Dial: dialFunc,
|
||||
}
|
||||
}
|
||||
|
38
cache/redis/redis_test.go
vendored
38
cache/redis/redis_test.go
vendored
@ -15,6 +15,7 @@
|
||||
package redis
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@ -104,3 +105,40 @@ func TestRedisCache(t *testing.T) {
|
||||
t.Error("clear all err")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCache_Scan(t *testing.T) {
|
||||
timeoutDuration := 10 * time.Second
|
||||
// init
|
||||
bm, err := cache.NewCache("redis", `{"conn": "127.0.0.1:6379"}`)
|
||||
if err != nil {
|
||||
t.Error("init err")
|
||||
}
|
||||
// insert all
|
||||
for i := 0; i < 10000; i++ {
|
||||
if err = bm.Put(fmt.Sprintf("astaxie%d", i), fmt.Sprintf("author%d", i), timeoutDuration); err != nil {
|
||||
t.Error("set Error", err)
|
||||
}
|
||||
}
|
||||
// scan all for the first time
|
||||
keys, err := bm.(*Cache).Scan(DefaultKey + ":*")
|
||||
if err != nil {
|
||||
t.Error("scan Error", err)
|
||||
}
|
||||
if len(keys) != 10000 {
|
||||
t.Error("scan all err")
|
||||
}
|
||||
|
||||
// clear all
|
||||
if err = bm.ClearAll(); err != nil {
|
||||
t.Error("clear all err")
|
||||
}
|
||||
|
||||
// scan all for the second time
|
||||
keys, err = bm.(*Cache).Scan(DefaultKey + ":*")
|
||||
if err != nil {
|
||||
t.Error("scan Error", err)
|
||||
}
|
||||
if len(keys) != 0 {
|
||||
t.Error("scan all err")
|
||||
}
|
||||
}
|
||||
|
22
config.go
22
config.go
@ -81,6 +81,8 @@ type WebConfig struct {
|
||||
DirectoryIndex bool
|
||||
StaticDir map[string]string
|
||||
StaticExtensionsToGzip []string
|
||||
StaticCacheFileSize int
|
||||
StaticCacheFileNum int
|
||||
TemplateLeft string
|
||||
TemplateRight string
|
||||
ViewsPath string
|
||||
@ -129,6 +131,8 @@ var (
|
||||
appConfigPath string
|
||||
// appConfigProvider is the provider for the config, default is ini
|
||||
appConfigProvider = "ini"
|
||||
// WorkPath is the absolute path to project root directory
|
||||
WorkPath string
|
||||
)
|
||||
|
||||
func init() {
|
||||
@ -137,7 +141,7 @@ func init() {
|
||||
if AppPath, err = filepath.Abs(filepath.Dir(os.Args[0])); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
workPath, err := os.Getwd()
|
||||
WorkPath, err = os.Getwd()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -145,7 +149,7 @@ func init() {
|
||||
if os.Getenv("BEEGO_RUNMODE") != "" {
|
||||
filename = os.Getenv("BEEGO_RUNMODE") + ".app.conf"
|
||||
}
|
||||
appConfigPath = filepath.Join(workPath, "conf", filename)
|
||||
appConfigPath = filepath.Join(WorkPath, "conf", filename)
|
||||
if !utils.FileExists(appConfigPath) {
|
||||
appConfigPath = filepath.Join(AppPath, "conf", filename)
|
||||
if !utils.FileExists(appConfigPath) {
|
||||
@ -236,6 +240,8 @@ func newBConfig() *Config {
|
||||
DirectoryIndex: false,
|
||||
StaticDir: map[string]string{"/static": "static"},
|
||||
StaticExtensionsToGzip: []string{".css", ".js"},
|
||||
StaticCacheFileSize: 1024 * 100,
|
||||
StaticCacheFileNum: 1000,
|
||||
TemplateLeft: "{{",
|
||||
TemplateRight: "}}",
|
||||
ViewsPath: "views",
|
||||
@ -317,6 +323,14 @@ func assignConfig(ac config.Configer) error {
|
||||
}
|
||||
}
|
||||
|
||||
if sfs, err := ac.Int("StaticCacheFileSize"); err == nil {
|
||||
BConfig.WebConfig.StaticCacheFileSize = sfs
|
||||
}
|
||||
|
||||
if sfn, err := ac.Int("StaticCacheFileNum"); err == nil {
|
||||
BConfig.WebConfig.StaticCacheFileNum = sfn
|
||||
}
|
||||
|
||||
if lo := ac.String("LogOutputs"); lo != "" {
|
||||
// if lo is not nil or empty
|
||||
// means user has set his own LogOutputs
|
||||
@ -408,9 +422,9 @@ func newAppConfig(appConfigProvider, appConfigPath string) (*beegoAppConfig, err
|
||||
|
||||
func (b *beegoAppConfig) Set(key, val string) error {
|
||||
if err := b.innerConfig.Set(BConfig.RunMode+"::"+key, val); err != nil {
|
||||
return err
|
||||
return b.innerConfig.Set(key, val)
|
||||
}
|
||||
return b.innerConfig.Set(key, val)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *beegoAppConfig) String(key string) string {
|
||||
|
@ -20,6 +20,7 @@ import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
@ -94,8 +95,10 @@ func (c *JSONConfigContainer) Int(key string) (int, error) {
|
||||
if val != nil {
|
||||
if v, ok := val.(float64); ok {
|
||||
return int(v), nil
|
||||
} else if v, ok := val.(string); ok {
|
||||
return strconv.Atoi(v)
|
||||
}
|
||||
return 0, errors.New("not int value")
|
||||
return 0, errors.New("not valid value")
|
||||
}
|
||||
return 0, errors.New("not exist key:" + key)
|
||||
}
|
||||
|
@ -115,6 +115,8 @@ func TestAssignConfig_03(t *testing.T) {
|
||||
ac.Set("RunMode", "online")
|
||||
ac.Set("StaticDir", "download:down download2:down2")
|
||||
ac.Set("StaticExtensionsToGzip", ".css,.js,.html,.jpg,.png")
|
||||
ac.Set("StaticCacheFileSize", "87456")
|
||||
ac.Set("StaticCacheFileNum", "1254")
|
||||
assignConfig(ac)
|
||||
|
||||
t.Logf("%#v", BConfig)
|
||||
@ -132,6 +134,12 @@ func TestAssignConfig_03(t *testing.T) {
|
||||
if BConfig.WebConfig.StaticDir["/download2"] != "down2" {
|
||||
t.FailNow()
|
||||
}
|
||||
if BConfig.WebConfig.StaticCacheFileSize != 87456 {
|
||||
t.FailNow()
|
||||
}
|
||||
if BConfig.WebConfig.StaticCacheFileNum != 1254 {
|
||||
t.FailNow()
|
||||
}
|
||||
if len(BConfig.WebConfig.StaticExtensionsToGzip) != 5 {
|
||||
t.FailNow()
|
||||
}
|
||||
|
@ -71,7 +71,9 @@ func (input *BeegoInput) Reset(ctx *Context) {
|
||||
input.CruSession = nil
|
||||
input.pnames = input.pnames[:0]
|
||||
input.pvalues = input.pvalues[:0]
|
||||
input.dataLock.Lock()
|
||||
input.data = nil
|
||||
input.dataLock.Unlock()
|
||||
input.RequestBody = []byte{}
|
||||
}
|
||||
|
||||
@ -87,7 +89,7 @@ func (input *BeegoInput) URI() string {
|
||||
|
||||
// URL returns request url path (without query string, fragment).
|
||||
func (input *BeegoInput) URL() string {
|
||||
return input.Context.Request.URL.Path
|
||||
return input.Context.Request.URL.EscapedPath()
|
||||
}
|
||||
|
||||
// Site returns base site url as scheme://domain type.
|
||||
@ -282,6 +284,11 @@ func (input *BeegoInput) ParamsLen() int {
|
||||
func (input *BeegoInput) Param(key string) string {
|
||||
for i, v := range input.pnames {
|
||||
if v == key && i <= len(input.pvalues) {
|
||||
// we cannot use url.PathEscape(input.pvalues[i])
|
||||
// for example, if the value is /a/b
|
||||
// after url.PathEscape(input.pvalues[i]), the value is %2Fa%2Fb
|
||||
// However, the value is used in ControllerRegister.ServeHTTP
|
||||
// and split by "/", so function crash...
|
||||
return input.pvalues[i]
|
||||
}
|
||||
}
|
||||
|
23
go.mod
23
go.mod
@ -2,36 +2,35 @@ 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/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737
|
||||
github.com/casbin/casbin v1.7.0
|
||||
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58
|
||||
github.com/couchbase/go-couchbase v0.0.0-20181122212707-3e9b6e1258bb
|
||||
github.com/couchbase/gomemcached v0.0.0-20181122193126-5125a94a666c // indirect
|
||||
github.com/couchbase/go-couchbase v0.0.0-20200519150804-63f3cdb75e0d
|
||||
github.com/couchbase/gomemcached v0.0.0-20200526233749-ec430f949808 // indirect
|
||||
github.com/couchbase/goutils v0.0.0-20180530154633-e865a1461c8a // indirect
|
||||
github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76 // indirect
|
||||
github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712 // indirect
|
||||
github.com/elastic/go-elasticsearch/v6 v6.8.5
|
||||
github.com/elazarl/go-bindata-assetfs v1.0.0
|
||||
github.com/go-redis/redis v6.14.2+incompatible
|
||||
github.com/go-sql-driver/mysql v1.4.1
|
||||
github.com/go-sql-driver/mysql v1.5.0
|
||||
github.com/gogo/protobuf v1.1.1
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db // indirect
|
||||
github.com/gomodule/redigo v2.0.0+incompatible
|
||||
github.com/hashicorp/golang-lru v0.5.4
|
||||
github.com/ledisdb/ledisdb v0.0.0-20200510135210-d35789ec47e6
|
||||
github.com/lib/pq v1.0.0
|
||||
github.com/mattn/go-sqlite3 v1.10.0
|
||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible
|
||||
github.com/pelletier/go-toml v1.2.0 // indirect
|
||||
github.com/pkg/errors v0.8.0 // indirect
|
||||
github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726 // indirect
|
||||
github.com/siddontang/ledisdb v0.0.0-20181029004158-becf5f38d373
|
||||
github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d // indirect
|
||||
github.com/prometheus/client_golang v1.7.0
|
||||
github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644
|
||||
github.com/ssdb/gossdb v0.0.0-20180723034631-88f6b59b84ec
|
||||
github.com/stretchr/testify v1.4.0
|
||||
github.com/syndtr/goleveldb v0.0.0-20181127023241-353a9fca669c // indirect
|
||||
github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b // indirect
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550
|
||||
golang.org/x/tools v0.0.0-20200117065230-39095c1d176c
|
||||
gopkg.in/yaml.v2 v2.2.1
|
||||
gopkg.in/yaml.v2 v2.2.8
|
||||
)
|
||||
|
||||
replace golang.org/x/crypto v0.0.0-20181127143415-eb0de9b17e85 => github.com/golang/crypto v0.0.0-20181127143415-eb0de9b17e85
|
||||
|
181
go.sum
181
go.sum
@ -1,80 +1,217 @@
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
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/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc=
|
||||
github.com/alicebob/miniredis v2.5.0+incompatible/go.mod h1:8HZjEj4yU0dwhYHky+DxYx+6BMjkBbe5ONFIF1MXffk=
|
||||
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=
|
||||
github.com/beego/x2j v0.0.0-20131220205130-a0352aadc542/go.mod h1:kSeGC/p1AbBiEp5kat81+DSQrZenVBZXklMLaELspWU=
|
||||
github.com/belogik/goes v0.0.0-20151229125003-e54d722c3aff h1:/kO0p2RTGLB8R5gub7ps0GmYpB2O8LXEoPq8tzFDCUI=
|
||||
github.com/belogik/goes v0.0.0-20151229125003-e54d722c3aff/go.mod h1:PhH1ZhyCzHKt4uAasyx+ljRCgoezetRNf59CUtwUkqY=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737 h1:rRISKWyXfVxvoa702s91Zl5oREZTrR3yv+tXrrX7G/g=
|
||||
github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60=
|
||||
github.com/casbin/casbin v1.7.0 h1:PuzlE8w0JBg/DhIqnkF1Dewf3z+qmUZMVN07PonvVUQ=
|
||||
github.com/casbin/casbin v1.7.0/go.mod h1:c67qKN6Oum3UF5Q1+BByfFxkwKvhwW57ITjqwtzR1KE=
|
||||
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58 h1:F1EaeKL/ta07PY/k9Os/UFtwERei2/XzGemhpGnBKNg=
|
||||
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80=
|
||||
github.com/couchbase/go-couchbase v0.0.0-20181122212707-3e9b6e1258bb h1:w3RapLhkA5+km9Z8vUkC6VCaskduJXvXwJg5neKnfDU=
|
||||
github.com/couchbase/go-couchbase v0.0.0-20181122212707-3e9b6e1258bb/go.mod h1:TWI8EKQMs5u5jLKW/tsb9VwauIrMIxQG1r5fMsswK5U=
|
||||
github.com/couchbase/gomemcached v0.0.0-20181122193126-5125a94a666c h1:K4FIibkr4//ziZKOKmt4RL0YImuTjLLBtwElf+F2lSQ=
|
||||
github.com/couchbase/gomemcached v0.0.0-20181122193126-5125a94a666c/go.mod h1:srVSlQLB8iXBVXHgnqemxUXqN6FCvClgCMPCsjBDR7c=
|
||||
github.com/couchbase/go-couchbase v0.0.0-20200519150804-63f3cdb75e0d h1:OMrhQqj1QCyDT2sxHCDjE+k8aMdn2ngTCGG7g4wrdLo=
|
||||
github.com/couchbase/go-couchbase v0.0.0-20200519150804-63f3cdb75e0d/go.mod h1:TWI8EKQMs5u5jLKW/tsb9VwauIrMIxQG1r5fMsswK5U=
|
||||
github.com/couchbase/gomemcached v0.0.0-20200526233749-ec430f949808 h1:8s2l8TVUwMXl6tZMe3+hPCRJ25nQXiA3d1x622JtOqc=
|
||||
github.com/couchbase/gomemcached v0.0.0-20200526233749-ec430f949808/go.mod h1:srVSlQLB8iXBVXHgnqemxUXqN6FCvClgCMPCsjBDR7c=
|
||||
github.com/couchbase/goutils v0.0.0-20180530154633-e865a1461c8a h1:Y5XsLCEhtEI8qbD9RP3Qlv5FXdTDHxZM9UPUnMRgBp8=
|
||||
github.com/couchbase/goutils v0.0.0-20180530154633-e865a1461c8a/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs=
|
||||
github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76 h1:Lgdd/Qp96Qj8jqLpq2cI1I1X7BJnu06efS+XkhRoLUQ=
|
||||
github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76/go.mod h1:vYwsqCOLxGiisLwp9rITslkFNpZD5rz43tf41QFkTWY=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712 h1:aaQcKT9WumO6JEJcRyTqFVq4XUZiUcKR2/GI31TOcz8=
|
||||
github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||
github.com/elastic/go-elasticsearch/v6 v6.8.5 h1:U2HtkBseC1FNBmDr0TR2tKltL6FxoY+niDAlj5M8TK8=
|
||||
github.com/elastic/go-elasticsearch/v6 v6.8.5/go.mod h1:UwaDJsD3rWLM5rKNFzv9hgox93HoX8utj1kxD9aFUcI=
|
||||
github.com/elazarl/go-bindata-assetfs v1.0.0 h1:G/bYguwHIzWq9ZoyUQqrjTmJbbYn3j3CKKpKinvZLFk=
|
||||
github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
|
||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/glendc/gopher-json v0.0.0-20170414221815-dc4743023d0c/go.mod h1:Gja1A+xZ9BoviGJNA2E9vFkPjjsl+CoJxSXiQM1UXtw=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-redis/redis v6.14.2+incompatible h1:UE9pLhzmWf+xHNmZsoccjXosPicuiNaInPgym8nzfg0=
|
||||
github.com/go-redis/redis v6.14.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||
github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
|
||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-yaml/yaml v0.0.0-20180328195020-5420a8b6744d h1:xy93KVe+KrIIwWDEAfQBdIfsiHJkepbYsDr+VY3g9/o=
|
||||
github.com/go-yaml/yaml v0.0.0-20180328195020-5420a8b6744d/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
github.com/gogo/protobuf v1.1.1 h1:72R+M5VuhED/KujmZVcIquuo8mBgX4oVda//DQb3PXo=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/golang/crypto v0.0.0-20181127143415-eb0de9b17e85 h1:B7ZbAFz7NOmvpUE5RGtu3u0WIizy5GdvbNpEf4RPnWs=
|
||||
github.com/golang/crypto v0.0.0-20181127143415-eb0de9b17e85/go.mod h1:uZvAcrsnNaCxlh1HorK5dUQHGmEKPh2H/Rl1kehswPo=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/gomodule/redigo v2.0.0+incompatible h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNuhuh457pBFPtt0=
|
||||
github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
|
||||
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/ledisdb/ledisdb v0.0.0-20200510135210-d35789ec47e6 h1:wxyqOzKxsRJ6vVRL9sXQ64Z45wmBuQ+OTH9sLsC5rKc=
|
||||
github.com/ledisdb/ledisdb v0.0.0-20200510135210-d35789ec47e6/go.mod h1:n931TsDuKuq+uX4v1fulaMbA/7ZLLhjc85h7chZGBCQ=
|
||||
github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o=
|
||||
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
|
||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.0 h1:Iw5WCbBcaAAd0fpRb1c9r5YCylv4XDoCSigm1zLevwU=
|
||||
github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
|
||||
github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/pelletier/go-toml v1.0.1/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/peterh/liner v1.0.1-0.20171122030339-3681c2a91233/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
|
||||
github.com/pingcap/tidb v2.0.11+incompatible/go.mod h1:I8C6jrPINP2rrVunTRd7C9fRRhQrtR43S1/CL5ix/yQ=
|
||||
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726 h1:xT+JlYxNGqyT+XcU8iUrN18JYed2TvG9yN5ULG2jATM=
|
||||
github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw=
|
||||
github.com/siddontang/ledisdb v0.0.0-20181029004158-becf5f38d373 h1:p6IxqQMjab30l4lb9mmkIkkcE1yv6o0SKbPhW5pxqHI=
|
||||
github.com/siddontang/ledisdb v0.0.0-20181029004158-becf5f38d373/go.mod h1:mF1DpOSOUiJRMR+FDqaqu3EBqrybQtrDDszLUZ6oxPg=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.7.0 h1:wCi7urQOGBsYcQROHqpUUX4ct84xp40t9R9JX0FuA/U=
|
||||
github.com/prometheus/client_golang v1.7.0/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.10.0 h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFBS8=
|
||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644 h1:X+yvsM2yrEktyI+b2qND5gpH8YhURn0k8OCaeRnkINo=
|
||||
github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644/go.mod h1:nkxAfR/5quYxwPZhyDxgasBMnRtBZd0FCEpawpjMUFg=
|
||||
github.com/siddontang/go v0.0.0-20170517070808-cb568a3e5cc0 h1:QIF48X1cihydXibm+4wfAc0r/qyPyuFiPFRNphdMpEE=
|
||||
github.com/siddontang/go v0.0.0-20170517070808-cb568a3e5cc0/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw=
|
||||
github.com/siddontang/goredis v0.0.0-20150324035039-760763f78400/go.mod h1:DDcKzU3qCuvj/tPnimWSsZZzvk9qvkvrIL5naVBPh5s=
|
||||
github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d h1:NVwnfyR3rENtlz62bcrkXME3INVUa4lcdGt+opvxExs=
|
||||
github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d/go.mod h1:AMEsy7v5z92TR1JKMkLLoaOQk++LVnOKL3ScbJ8GNGA=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/ssdb/gossdb v0.0.0-20180723034631-88f6b59b84ec h1:q6XVwXmKvCRHRqesF3cSv6lNqqHi0QWOvgDlSohg8UA=
|
||||
github.com/ssdb/gossdb v0.0.0-20180723034631-88f6b59b84ec/go.mod h1:QBvMkMya+gXctz3kmljlUCu/yB3GZ6oee+dUozsezQE=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/syndtr/goleveldb v0.0.0-20160425020131-cfa635847112/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
|
||||
github.com/syndtr/goleveldb v0.0.0-20181127023241-353a9fca669c h1:3eGShk3EQf5gJCYW+WzA0TEJQd37HLOmlYF7N0YJwv0=
|
||||
github.com/syndtr/goleveldb v0.0.0-20181127023241-353a9fca669c/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
|
||||
github.com/ugorji/go v0.0.0-20171122102828-84cb69a8af83/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
|
||||
github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b h1:0Ve0/CCjiAiyKddUMUn3RwIGlq2iTW4GuVzyoKBYO/8=
|
||||
github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b/go.mod h1:Q12BUT7DqIlHRmgv3RskH+UCM/4eqVMgI0EMmlSpAXc=
|
||||
golang.org/x/crypto v0.0.0-20181127143415-eb0de9b17e85 h1:et7+NAX3lLIk5qUCTA9QelBjGE/NkhzYw/mhnr0s7nI=
|
||||
golang.org/x/crypto v0.0.0-20181127143415-eb0de9b17e85/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
github.com/yuin/gopher-lua v0.0.0-20171031051903-609c9cd26973/go.mod h1:aEV29XrmTYFr3CiRxZeGHpkvbwq+prZduBqMaascyCU=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a h1:gOpx8G595UYyvj8UK4+OFyY4rx037g3fmfhe5SasG3U=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 h1:ogLJMz+qpzav7lGMh10LMvAkM/fAoGlaiiHYiFYdm80=
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/tools v0.0.0-20200117065230-39095c1d176c h1:FodBYPZKH5tAN2O60HlglMwXGAeV/4k+NKbli79M/2c=
|
||||
golang.org/x/tools v0.0.0-20200117065230-39095c1d176c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
@ -46,7 +46,10 @@ func (srv *Server) Serve() (err error) {
|
||||
|
||||
log.Println(syscall.Getpid(), srv.ln.Addr(), "Listener closed.")
|
||||
// wait for Shutdown to return
|
||||
return <-srv.terminalChan
|
||||
if shutdownErr := <-srv.terminalChan; shutdownErr != nil {
|
||||
return shutdownErr
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ListenAndServe listens on the TCP network address srv.Addr and then calls Serve
|
||||
@ -180,7 +183,7 @@ func (srv *Server) ListenAndServeMutualTLS(certFile, keyFile, trustFile string)
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
err = process.Kill()
|
||||
err = process.Signal(syscall.SIGTERM)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -407,6 +407,7 @@ func (b *BeegoHTTPRequest) buildURL(paramBody string) {
|
||||
}()
|
||||
b.Header("Content-Type", bodyWriter.FormDataContentType())
|
||||
b.req.Body = ioutil.NopCloser(pr)
|
||||
b.Header("Transfer-Encoding", "chunked")
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@ package logs
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Try each log level in decreasing order of priority.
|
||||
@ -49,3 +50,15 @@ func TestConsoleNoColor(t *testing.T) {
|
||||
log.SetLogger("console", `{"color":false}`)
|
||||
testConsoleCalls(log)
|
||||
}
|
||||
|
||||
// Test console async
|
||||
func TestConsoleAsync(t *testing.T) {
|
||||
log := NewLogger(100)
|
||||
log.SetLogger("console")
|
||||
log.Async()
|
||||
//log.Close()
|
||||
testConsoleCalls(log)
|
||||
for len(log.msgChan) != 0 {
|
||||
time.Sleep(1 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,17 @@
|
||||
package es
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/OwnLocal/goes"
|
||||
"github.com/elastic/go-elasticsearch/v6"
|
||||
"github.com/elastic/go-elasticsearch/v6/esapi"
|
||||
|
||||
"github.com/astaxie/beego/logs"
|
||||
)
|
||||
|
||||
@ -20,8 +23,14 @@ func NewES() logs.Logger {
|
||||
return cw
|
||||
}
|
||||
|
||||
// esLogger will log msg into ES
|
||||
// before you using this implementation,
|
||||
// please import this package
|
||||
// usually means that you can import this package in your main package
|
||||
// for example, anonymous:
|
||||
// import _ "github.com/astaxie/beego/logs/es"
|
||||
type esLogger struct {
|
||||
*goes.Client
|
||||
*elasticsearch.Client
|
||||
DSN string `json:"dsn"`
|
||||
Level int `json:"level"`
|
||||
}
|
||||
@ -38,10 +47,13 @@ func (el *esLogger) Init(jsonconfig string) error {
|
||||
return err
|
||||
} else if u.Path == "" {
|
||||
return errors.New("missing prefix")
|
||||
} else if host, port, err := net.SplitHostPort(u.Host); err != nil {
|
||||
return err
|
||||
} else {
|
||||
conn := goes.NewClient(host, port)
|
||||
conn, err := elasticsearch.NewClient(elasticsearch.Config{
|
||||
Addresses: []string{el.DSN},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
el.Client = conn
|
||||
}
|
||||
return nil
|
||||
@ -53,21 +65,26 @@ func (el *esLogger) WriteMsg(when time.Time, msg string, level int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
vals := make(map[string]interface{})
|
||||
vals["@timestamp"] = when.Format(time.RFC3339)
|
||||
vals["@msg"] = msg
|
||||
d := goes.Document{
|
||||
Index: fmt.Sprintf("%04d.%02d.%02d", when.Year(), when.Month(), when.Day()),
|
||||
Type: "logs",
|
||||
Fields: vals,
|
||||
idx := LogDocument{
|
||||
Timestamp: when.Format(time.RFC3339),
|
||||
Msg: msg,
|
||||
}
|
||||
_, err := el.Index(d, nil)
|
||||
|
||||
body, err := json.Marshal(idx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req := esapi.IndexRequest{
|
||||
Index: fmt.Sprintf("%04d.%02d.%02d", when.Year(), when.Month(), when.Day()),
|
||||
DocumentType: "logs",
|
||||
Body: strings.NewReader(string(body)),
|
||||
}
|
||||
_, err = req.Do(context.Background(), el.Client)
|
||||
return err
|
||||
}
|
||||
|
||||
// Destroy is a empty method
|
||||
func (el *esLogger) Destroy() {
|
||||
|
||||
}
|
||||
|
||||
// Flush is a empty method
|
||||
@ -75,7 +92,11 @@ func (el *esLogger) Flush() {
|
||||
|
||||
}
|
||||
|
||||
type LogDocument struct {
|
||||
Timestamp string `json:"timestamp"`
|
||||
Msg string `json:"msg"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
logs.Register(logs.AdapterEs, NewES)
|
||||
}
|
||||
|
||||
|
@ -359,6 +359,10 @@ RESTART_LOGGER:
|
||||
|
||||
func (w *fileLogWriter) deleteOldLog() {
|
||||
dir := filepath.Dir(w.Filename)
|
||||
absolutePath, err := filepath.EvalSymlinks(w.Filename)
|
||||
if err == nil {
|
||||
dir = filepath.Dir(absolutePath)
|
||||
}
|
||||
filepath.Walk(dir, func(path string, info os.FileInfo, err error) (returnErr error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
|
@ -295,7 +295,11 @@ func (bl *BeeLogger) writeMsg(logLevel int, msg string, v ...interface{}) error
|
||||
lm.level = logLevel
|
||||
lm.msg = msg
|
||||
lm.when = when
|
||||
bl.msgChan <- lm
|
||||
if bl.outputs != nil {
|
||||
bl.msgChan <- lm
|
||||
} else {
|
||||
logMsgPool.Put(lm)
|
||||
}
|
||||
} else {
|
||||
bl.writeToLoggers(when, msg, logLevel)
|
||||
}
|
||||
|
99
metric/prometheus.go
Normal file
99
metric/prometheus.go
Normal file
@ -0,0 +1,99 @@
|
||||
// Copyright 2020 astaxie
|
||||
//
|
||||
// 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 metric
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/astaxie/beego/logs"
|
||||
)
|
||||
|
||||
func PrometheusMiddleWare(next http.Handler) http.Handler {
|
||||
summaryVec := prometheus.NewSummaryVec(prometheus.SummaryOpts{
|
||||
Name: "beego",
|
||||
Subsystem: "http_request",
|
||||
ConstLabels: map[string]string{
|
||||
"server": beego.BConfig.ServerName,
|
||||
"env": beego.BConfig.RunMode,
|
||||
"appname": beego.BConfig.AppName,
|
||||
},
|
||||
Help: "The statics info for http request",
|
||||
}, []string{"pattern", "method", "status", "duration"})
|
||||
|
||||
prometheus.MustRegister(summaryVec)
|
||||
|
||||
registerBuildInfo()
|
||||
|
||||
return http.HandlerFunc(func(writer http.ResponseWriter, q *http.Request) {
|
||||
start := time.Now()
|
||||
next.ServeHTTP(writer, q)
|
||||
end := time.Now()
|
||||
go report(end.Sub(start), writer, q, summaryVec)
|
||||
})
|
||||
}
|
||||
|
||||
func registerBuildInfo() {
|
||||
buildInfo := prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
||||
Name: "beego",
|
||||
Subsystem: "build_info",
|
||||
Help: "The building information",
|
||||
ConstLabels: map[string]string{
|
||||
"appname": beego.BConfig.AppName,
|
||||
"build_version": beego.BuildVersion,
|
||||
"build_revision": beego.BuildGitRevision,
|
||||
"build_status": beego.BuildStatus,
|
||||
"build_tag": beego.BuildTag,
|
||||
"build_time": strings.Replace(beego.BuildTime, "--", " ", 1),
|
||||
"go_version": beego.GoVersion,
|
||||
"git_branch": beego.GitBranch,
|
||||
"start_time": time.Now().Format("2006-01-02 15:04:05"),
|
||||
},
|
||||
}, []string{})
|
||||
|
||||
prometheus.MustRegister(buildInfo)
|
||||
buildInfo.WithLabelValues().Set(1)
|
||||
}
|
||||
|
||||
func report(dur time.Duration, writer http.ResponseWriter, q *http.Request, vec *prometheus.SummaryVec) {
|
||||
ctrl := beego.BeeApp.Handlers
|
||||
ctx := ctrl.GetContext()
|
||||
ctx.Reset(writer, q)
|
||||
defer ctrl.GiveBackContext(ctx)
|
||||
|
||||
// We cannot read the status code from q.Response.StatusCode
|
||||
// since the http server does not set q.Response. So q.Response is nil
|
||||
// Thus, we use reflection to read the status from writer whose concrete type is http.response
|
||||
responseVal := reflect.ValueOf(writer).Elem()
|
||||
field := responseVal.FieldByName("status")
|
||||
status := -1
|
||||
if field.IsValid() && field.Kind() == reflect.Int {
|
||||
status = int(field.Int())
|
||||
}
|
||||
ptn := "UNKNOWN"
|
||||
if rt, found := ctrl.FindRouter(ctx); found {
|
||||
ptn = rt.GetPattern()
|
||||
} else {
|
||||
logs.Warn("we can not find the router info for this request, so request will be recorded as UNKNOWN: " + q.URL.String())
|
||||
}
|
||||
ms := dur / time.Millisecond
|
||||
vec.WithLabelValues(ptn, q.Method, strconv.Itoa(status), strconv.Itoa(int(ms))).Observe(float64(ms))
|
||||
}
|
42
metric/prometheus_test.go
Normal file
42
metric/prometheus_test.go
Normal file
@ -0,0 +1,42 @@
|
||||
// Copyright 2020 astaxie
|
||||
//
|
||||
// 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 metric
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
|
||||
"github.com/astaxie/beego/context"
|
||||
)
|
||||
|
||||
func TestPrometheusMiddleWare(t *testing.T) {
|
||||
middleware := PrometheusMiddleWare(http.HandlerFunc(func(http.ResponseWriter, *http.Request) {}))
|
||||
writer := &context.Response{}
|
||||
request := &http.Request{
|
||||
URL: &url.URL{
|
||||
Host: "localhost",
|
||||
RawPath: "/a/b/c",
|
||||
},
|
||||
Method: "POST",
|
||||
}
|
||||
vec := prometheus.NewSummaryVec(prometheus.SummaryOpts{}, []string{"pattern", "method", "status", "duration"})
|
||||
|
||||
report(time.Second, writer, request, vec)
|
||||
middleware.ServeHTTP(writer, request)
|
||||
}
|
12
orm/db.go
12
orm/db.go
@ -470,7 +470,7 @@ func (d *dbBase) InsertValue(q dbQuerier, mi *modelInfo, isMulti bool, names []s
|
||||
|
||||
multi := len(values) / len(names)
|
||||
|
||||
if isMulti {
|
||||
if isMulti && multi > 1 {
|
||||
qmarks = strings.Repeat(qmarks+"), (", multi-1) + qmarks
|
||||
}
|
||||
|
||||
@ -770,6 +770,16 @@ func (d *dbBase) UpdateBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Con
|
||||
cols = append(cols, col+" = "+col+" * ?")
|
||||
case ColExcept:
|
||||
cols = append(cols, col+" = "+col+" / ?")
|
||||
case ColBitAnd:
|
||||
cols = append(cols, col+" = "+col+" & ?")
|
||||
case ColBitRShift:
|
||||
cols = append(cols, col+" = "+col+" >> ?")
|
||||
case ColBitLShift:
|
||||
cols = append(cols, col+" = "+col+" << ?")
|
||||
case ColBitXOR:
|
||||
cols = append(cols, col+" = "+col+" ^ ?")
|
||||
case ColBitOr:
|
||||
cols = append(cols, col+" = "+col+" | ?")
|
||||
}
|
||||
values[i] = c.value
|
||||
} else {
|
||||
|
104
orm/db_alias.go
104
orm/db_alias.go
@ -18,6 +18,7 @@ import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
lru "github.com/hashicorp/golang-lru"
|
||||
"reflect"
|
||||
"sync"
|
||||
"time"
|
||||
@ -106,8 +107,8 @@ func (ac *_dbCache) getDefault() (al *alias) {
|
||||
|
||||