mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-24 01:27:49 +01:00
Merge pull request #423 from reasonerjt/job-service
upgrade beego to 1.6.1
This commit is contained in:
commit
7154c092a1
@ -167,10 +167,7 @@ func init() {
|
|||||||
configPath := os.Getenv("CONFIG_PATH")
|
configPath := os.Getenv("CONFIG_PATH")
|
||||||
if len(configPath) != 0 {
|
if len(configPath) != 0 {
|
||||||
log.Infof("Config path: %s", configPath)
|
log.Infof("Config path: %s", configPath)
|
||||||
beego.AppConfigPath = configPath
|
beego.LoadAppConfig("ini", configPath)
|
||||||
if err := beego.ParseConfig(); err != nil {
|
|
||||||
log.Warningf("Failed to parse config file: %s, error: %v", configPath, err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
langs := strings.Split(beego.AppConfig.String("lang::types"), "|")
|
langs := strings.Split(beego.AppConfig.String("lang::types"), "|")
|
||||||
|
5
vendor/github.com/astaxie/beego/.gitignore
generated
vendored
5
vendor/github.com/astaxie/beego/.gitignore
generated
vendored
@ -1,5 +0,0 @@
|
|||||||
.idea
|
|
||||||
.DS_Store
|
|
||||||
*.swp
|
|
||||||
*.swo
|
|
||||||
beego.iml
|
|
30
vendor/github.com/astaxie/beego/.travis.yml
generated
vendored
30
vendor/github.com/astaxie/beego/.travis.yml
generated
vendored
@ -1,30 +0,0 @@
|
|||||||
language: go
|
|
||||||
|
|
||||||
go:
|
|
||||||
- 1.5.1
|
|
||||||
|
|
||||||
services:
|
|
||||||
- redis-server
|
|
||||||
- mysql
|
|
||||||
- postgresql
|
|
||||||
- memcached
|
|
||||||
env:
|
|
||||||
- ORM_DRIVER=sqlite3 ORM_SOURCE=$TRAVIS_BUILD_DIR/orm_test.db
|
|
||||||
- ORM_DRIVER=mysql ORM_SOURCE="root:@/orm_test?charset=utf8"
|
|
||||||
- ORM_DRIVER=postgres ORM_SOURCE="user=postgres dbname=orm_test sslmode=disable"
|
|
||||||
install:
|
|
||||||
- go get github.com/lib/pq
|
|
||||||
- go get github.com/go-sql-driver/mysql
|
|
||||||
- go get github.com/mattn/go-sqlite3
|
|
||||||
- go get github.com/bradfitz/gomemcache/memcache
|
|
||||||
- go get github.com/garyburd/redigo/redis
|
|
||||||
- go get github.com/beego/x2j
|
|
||||||
- go get github.com/beego/goyaml2
|
|
||||||
- go get github.com/belogik/goes
|
|
||||||
- go get github.com/couchbase/go-couchbase
|
|
||||||
- go get github.com/siddontang/ledisdb/config
|
|
||||||
- go get github.com/siddontang/ledisdb/ledis
|
|
||||||
before_script:
|
|
||||||
- sh -c "if [ '$ORM_DRIVER' = 'postgres' ]; then psql -c 'create database orm_test;' -U postgres; fi"
|
|
||||||
- sh -c "if [ '$ORM_DRIVER' = 'mysql' ]; then mysql -u root -e 'create database orm_test;'; fi"
|
|
||||||
- sh -c "if [ '$ORM_DRIVER' = 'sqlite' ]; then touch $TRAVIS_BUILD_DIR/orm_test.db; fi"
|
|
1
vendor/github.com/astaxie/beego/README.md
generated
vendored
1
vendor/github.com/astaxie/beego/README.md
generated
vendored
@ -53,6 +53,7 @@ Please see [Documentation](http://beego.me/docs) for more.
|
|||||||
## Community
|
## Community
|
||||||
|
|
||||||
* [http://beego.me/community](http://beego.me/community)
|
* [http://beego.me/community](http://beego.me/community)
|
||||||
|
* Welcome to join us in Slack: [https://beego.slack.com](https://beego.slack.com), you can get invited from [here](https://github.com/beego/beedoc/issues/232)
|
||||||
|
|
||||||
## LICENSE
|
## LICENSE
|
||||||
|
|
||||||
|
4
vendor/github.com/astaxie/beego/admin.go
generated
vendored
4
vendor/github.com/astaxie/beego/admin.go
generated
vendored
@ -90,8 +90,8 @@ func listConf(rw http.ResponseWriter, r *http.Request) {
|
|||||||
switch command {
|
switch command {
|
||||||
case "conf":
|
case "conf":
|
||||||
m := make(map[string]interface{})
|
m := make(map[string]interface{})
|
||||||
m["AppConfigPath"] = AppConfigPath
|
m["AppConfigPath"] = appConfigPath
|
||||||
m["AppConfigProvider"] = AppConfigProvider
|
m["AppConfigProvider"] = appConfigProvider
|
||||||
m["BConfig.AppName"] = BConfig.AppName
|
m["BConfig.AppName"] = BConfig.AppName
|
||||||
m["BConfig.RunMode"] = BConfig.RunMode
|
m["BConfig.RunMode"] = BConfig.RunMode
|
||||||
m["BConfig.RouterCaseSensitive"] = BConfig.RouterCaseSensitive
|
m["BConfig.RouterCaseSensitive"] = BConfig.RouterCaseSensitive
|
||||||
|
20
vendor/github.com/astaxie/beego/beego.go
generated
vendored
20
vendor/github.com/astaxie/beego/beego.go
generated
vendored
@ -15,7 +15,6 @@
|
|||||||
package beego
|
package beego
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -24,7 +23,7 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
// VERSION represent beego web framework version.
|
// VERSION represent beego web framework version.
|
||||||
VERSION = "1.6.0"
|
VERSION = "1.6.1"
|
||||||
|
|
||||||
// DEV is for develop
|
// DEV is for develop
|
||||||
DEV = "dev"
|
DEV = "dev"
|
||||||
@ -68,21 +67,6 @@ func Run(params ...string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func initBeforeHTTPRun() {
|
func initBeforeHTTPRun() {
|
||||||
// if AppConfigPath is setted or conf/app.conf exist
|
|
||||||
err := ParseConfig()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
//init log
|
|
||||||
for adaptor, config := range BConfig.Log.Outputs {
|
|
||||||
err = BeeLogger.SetLogger(adaptor, config)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("%s with the config `%s` got err:%s\n", adaptor, config, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SetLogFuncCall(BConfig.Log.FileLineNum)
|
|
||||||
|
|
||||||
//init hooks
|
//init hooks
|
||||||
AddAPPStartHook(registerMime)
|
AddAPPStartHook(registerMime)
|
||||||
AddAPPStartHook(registerDefaultErrorHandler)
|
AddAPPStartHook(registerDefaultErrorHandler)
|
||||||
@ -101,7 +85,7 @@ func initBeforeHTTPRun() {
|
|||||||
// TestBeegoInit is for test package init
|
// TestBeegoInit is for test package init
|
||||||
func TestBeegoInit(ap string) {
|
func TestBeegoInit(ap string) {
|
||||||
os.Setenv("BEEGO_RUNMODE", "test")
|
os.Setenv("BEEGO_RUNMODE", "test")
|
||||||
AppConfigPath = filepath.Join(ap, "conf", "app.conf")
|
appConfigPath = filepath.Join(ap, "conf", "app.conf")
|
||||||
os.Chdir(ap)
|
os.Chdir(ap)
|
||||||
initBeforeHTTPRun()
|
initBeforeHTTPRun()
|
||||||
}
|
}
|
||||||
|
190
vendor/github.com/astaxie/beego/cache/memcache/memcache.go
generated
vendored
190
vendor/github.com/astaxie/beego/cache/memcache/memcache.go
generated
vendored
@ -1,190 +0,0 @@
|
|||||||
// Copyright 2014 beego Author. All Rights Reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
// Package memcache for cache provider
|
|
||||||
//
|
|
||||||
// depend on github.com/bradfitz/gomemcache/memcache
|
|
||||||
//
|
|
||||||
// go install github.com/bradfitz/gomemcache/memcache
|
|
||||||
//
|
|
||||||
// Usage:
|
|
||||||
// import(
|
|
||||||
// _ "github.com/astaxie/beego/cache/memcache"
|
|
||||||
// "github.com/astaxie/beego/cache"
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// bm, err := cache.NewCache("memcache", `{"conn":"127.0.0.1:11211"}`)
|
|
||||||
//
|
|
||||||
// more docs http://beego.me/docs/module/cache.md
|
|
||||||
package memcache
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/bradfitz/gomemcache/memcache"
|
|
||||||
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/astaxie/beego/cache"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Cache Memcache adapter.
|
|
||||||
type Cache struct {
|
|
||||||
conn *memcache.Client
|
|
||||||
conninfo []string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewMemCache create new memcache adapter.
|
|
||||||
func NewMemCache() cache.Cache {
|
|
||||||
return &Cache{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get get value from memcache.
|
|
||||||
func (rc *Cache) Get(key string) interface{} {
|
|
||||||
if rc.conn == nil {
|
|
||||||
if err := rc.connectInit(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if item, err := rc.conn.Get(key); err == nil {
|
|
||||||
return string(item.Value)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetMulti get value from memcache.
|
|
||||||
func (rc *Cache) GetMulti(keys []string) []interface{} {
|
|
||||||
size := len(keys)
|
|
||||||
var rv []interface{}
|
|
||||||
if rc.conn == nil {
|
|
||||||
if err := rc.connectInit(); err != nil {
|
|
||||||
for i := 0; i < size; i++ {
|
|
||||||
rv = append(rv, err)
|
|
||||||
}
|
|
||||||
return rv
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mv, err := rc.conn.GetMulti(keys)
|
|
||||||
if err == nil {
|
|
||||||
for _, v := range mv {
|
|
||||||
rv = append(rv, string(v.Value))
|
|
||||||
}
|
|
||||||
return rv
|
|
||||||
}
|
|
||||||
for i := 0; i < size; i++ {
|
|
||||||
rv = append(rv, err)
|
|
||||||
}
|
|
||||||
return rv
|
|
||||||
}
|
|
||||||
|
|
||||||
// Put put value to memcache. only support string.
|
|
||||||
func (rc *Cache) Put(key string, val interface{}, timeout time.Duration) error {
|
|
||||||
if rc.conn == nil {
|
|
||||||
if err := rc.connectInit(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
v, ok := val.(string)
|
|
||||||
if !ok {
|
|
||||||
return errors.New("val must string")
|
|
||||||
}
|
|
||||||
item := memcache.Item{Key: key, Value: []byte(v), Expiration: int32(timeout / time.Second)}
|
|
||||||
return rc.conn.Set(&item)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete delete value in memcache.
|
|
||||||
func (rc *Cache) Delete(key string) error {
|
|
||||||
if rc.conn == nil {
|
|
||||||
if err := rc.connectInit(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return rc.conn.Delete(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Incr increase counter.
|
|
||||||
func (rc *Cache) Incr(key string) error {
|
|
||||||
if rc.conn == nil {
|
|
||||||
if err := rc.connectInit(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_, err := rc.conn.Increment(key, 1)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decr decrease counter.
|
|
||||||
func (rc *Cache) Decr(key string) error {
|
|
||||||
if rc.conn == nil {
|
|
||||||
if err := rc.connectInit(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_, err := rc.conn.Decrement(key, 1)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsExist check value exists in memcache.
|
|
||||||
func (rc *Cache) IsExist(key string) bool {
|
|
||||||
if rc.conn == nil {
|
|
||||||
if err := rc.connectInit(); err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_, err := rc.conn.Get(key)
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClearAll clear all cached in memcache.
|
|
||||||
func (rc *Cache) ClearAll() error {
|
|
||||||
if rc.conn == nil {
|
|
||||||
if err := rc.connectInit(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return rc.conn.FlushAll()
|
|
||||||
}
|
|
||||||
|
|
||||||
// StartAndGC start memcache adapter.
|
|
||||||
// config string is like {"conn":"connection info"}.
|
|
||||||
// if connecting error, return.
|
|
||||||
func (rc *Cache) StartAndGC(config string) error {
|
|
||||||
var cf map[string]string
|
|
||||||
json.Unmarshal([]byte(config), &cf)
|
|
||||||
if _, ok := cf["conn"]; !ok {
|
|
||||||
return errors.New("config has no conn key")
|
|
||||||
}
|
|
||||||
rc.conninfo = strings.Split(cf["conn"], ";")
|
|
||||||
if rc.conn == nil {
|
|
||||||
if err := rc.connectInit(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// connect to memcache and keep the connection.
|
|
||||||
func (rc *Cache) connectInit() error {
|
|
||||||
rc.conn = memcache.New(rc.conninfo...)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
cache.Register("memcache", NewMemCache)
|
|
||||||
}
|
|
240
vendor/github.com/astaxie/beego/cache/redis/redis.go
generated
vendored
240
vendor/github.com/astaxie/beego/cache/redis/redis.go
generated
vendored
@ -1,240 +0,0 @@
|
|||||||
// Copyright 2014 beego Author. All Rights Reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
// Package redis for cache provider
|
|
||||||
//
|
|
||||||
// depend on github.com/garyburd/redigo/redis
|
|
||||||
//
|
|
||||||
// go install github.com/garyburd/redigo/redis
|
|
||||||
//
|
|
||||||
// Usage:
|
|
||||||
// import(
|
|
||||||
// _ "github.com/astaxie/beego/cache/redis"
|
|
||||||
// "github.com/astaxie/beego/cache"
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// bm, err := cache.NewCache("redis", `{"conn":"127.0.0.1:11211"}`)
|
|
||||||
//
|
|
||||||
// more docs http://beego.me/docs/module/cache.md
|
|
||||||
package redis
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/garyburd/redigo/redis"
|
|
||||||
|
|
||||||
"github.com/astaxie/beego/cache"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// DefaultKey the collection name of redis for cache adapter.
|
|
||||||
DefaultKey = "beecacheRedis"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Cache is Redis cache adapter.
|
|
||||||
type Cache struct {
|
|
||||||
p *redis.Pool // redis connection pool
|
|
||||||
conninfo string
|
|
||||||
dbNum int
|
|
||||||
key string
|
|
||||||
password string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewRedisCache create new redis cache with default collection name.
|
|
||||||
func NewRedisCache() cache.Cache {
|
|
||||||
return &Cache{key: DefaultKey}
|
|
||||||
}
|
|
||||||
|
|
||||||
// actually do the redis cmds
|
|
||||||
func (rc *Cache) do(commandName string, args ...interface{}) (reply interface{}, err error) {
|
|
||||||
c := rc.p.Get()
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
return c.Do(commandName, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get cache from redis.
|
|
||||||
func (rc *Cache) Get(key string) interface{} {
|
|
||||||
if v, err := rc.do("GET", key); err == nil {
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetMulti get cache from redis.
|
|
||||||
func (rc *Cache) GetMulti(keys []string) []interface{} {
|
|
||||||
size := len(keys)
|
|
||||||
var rv []interface{}
|
|
||||||
c := rc.p.Get()
|
|
||||||
defer c.Close()
|
|
||||||
var err error
|
|
||||||
for _, key := range keys {
|
|
||||||
err = c.Send("GET", key)
|
|
||||||
if err != nil {
|
|
||||||
goto ERROR
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err = c.Flush(); err != nil {
|
|
||||||
goto ERROR
|
|
||||||
}
|
|
||||||
for i := 0; i < size; i++ {
|
|
||||||
if v, err := c.Receive(); err == nil {
|
|
||||||
rv = append(rv, v.([]byte))
|
|
||||||
} else {
|
|
||||||
rv = append(rv, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return rv
|
|
||||||
ERROR:
|
|
||||||
rv = rv[0:0]
|
|
||||||
for i := 0; i < size; i++ {
|
|
||||||
rv = append(rv, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv
|
|
||||||
}
|
|
||||||
|
|
||||||
// Put put cache to redis.
|
|
||||||
func (rc *Cache) Put(key string, val interface{}, timeout time.Duration) error {
|
|
||||||
var err error
|
|
||||||
if _, err = rc.do("SETEX", key, int64(timeout/time.Second), val); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err = rc.do("HSET", rc.key, key, true); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete delete cache in redis.
|
|
||||||
func (rc *Cache) Delete(key string) error {
|
|
||||||
var err error
|
|
||||||
if _, err = rc.do("DEL", key); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, err = rc.do("HDEL", rc.key, key)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsExist check cache's existence in redis.
|
|
||||||
func (rc *Cache) IsExist(key string) bool {
|
|
||||||
v, err := redis.Bool(rc.do("EXISTS", key))
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if v == false {
|
|
||||||
if _, err = rc.do("HDEL", rc.key, key); err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// Incr increase counter in redis.
|
|
||||||
func (rc *Cache) Incr(key string) error {
|
|
||||||
_, err := redis.Bool(rc.do("INCRBY", key, 1))
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decr decrease counter in redis.
|
|
||||||
func (rc *Cache) Decr(key string) error {
|
|
||||||
_, err := redis.Bool(rc.do("INCRBY", key, -1))
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClearAll clean all cache in redis. delete this redis collection.
|
|
||||||
func (rc *Cache) ClearAll() error {
|
|
||||||
cachedKeys, err := redis.Strings(rc.do("HKEYS", rc.key))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for _, str := range cachedKeys {
|
|
||||||
if _, err = rc.do("DEL", str); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_, err = rc.do("DEL", rc.key)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// StartAndGC start redis cache adapter.
|
|
||||||
// config is like {"key":"collection key","conn":"connection info","dbNum":"0"}
|
|
||||||
// the cache item in redis are stored forever,
|
|
||||||
// so no gc operation.
|
|
||||||
func (rc *Cache) StartAndGC(config string) error {
|
|
||||||
var cf map[string]string
|
|
||||||
json.Unmarshal([]byte(config), &cf)
|
|
||||||
|
|
||||||
if _, ok := cf["key"]; !ok {
|
|
||||||
cf["key"] = DefaultKey
|
|
||||||
}
|
|
||||||
if _, ok := cf["conn"]; !ok {
|
|
||||||
return errors.New("config has no conn key")
|
|
||||||
}
|
|
||||||
if _, ok := cf["dbNum"]; !ok {
|
|
||||||
cf["dbNum"] = "0"
|
|
||||||
}
|
|
||||||
if _, ok := cf["password"]; !ok {
|
|
||||||
cf["password"] = ""
|
|
||||||
}
|
|
||||||
rc.key = cf["key"]
|
|
||||||
rc.conninfo = cf["conn"]
|
|
||||||
rc.dbNum, _ = strconv.Atoi(cf["dbNum"])
|
|
||||||
rc.password = cf["password"]
|
|
||||||
|
|
||||||
rc.connectInit()
|
|
||||||
|
|
||||||
c := rc.p.Get()
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
return c.Err()
|
|
||||||
}
|
|
||||||
|
|
||||||
// connect to redis.
|
|
||||||
func (rc *Cache) connectInit() {
|
|
||||||
dialFunc := func() (c redis.Conn, err error) {
|
|
||||||
c, err = redis.Dial("tcp", rc.conninfo)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if rc.password != "" {
|
|
||||||
if _, err := c.Do("AUTH", rc.password); err != nil {
|
|
||||||
c.Close()
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_, selecterr := c.Do("SELECT", rc.dbNum)
|
|
||||||
if selecterr != nil {
|
|
||||||
c.Close()
|
|
||||||
return nil, selecterr
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// initialize a new pool
|
|
||||||
rc.p = &redis.Pool{
|
|
||||||
MaxIdle: 3,
|
|
||||||
IdleTimeout: 180 * time.Second,
|
|
||||||
Dial: dialFunc,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
cache.Register("redis", NewRedisCache)
|
|
||||||
}
|
|
124
vendor/github.com/astaxie/beego/config.go
generated
vendored
124
vendor/github.com/astaxie/beego/config.go
generated
vendored
@ -15,7 +15,7 @@
|
|||||||
package beego
|
package beego
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"html/template"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
@ -103,17 +103,22 @@ var (
|
|||||||
BConfig *Config
|
BConfig *Config
|
||||||
// AppConfig is the instance of Config, store the config information from file
|
// AppConfig is the instance of Config, store the config information from file
|
||||||
AppConfig *beegoAppConfig
|
AppConfig *beegoAppConfig
|
||||||
// AppConfigPath is the path to the config files
|
// AppPath is the absolute path to the app
|
||||||
AppConfigPath string
|
AppPath string
|
||||||
// AppConfigProvider is the provider for the config, default is ini
|
|
||||||
AppConfigProvider = "ini"
|
|
||||||
// TemplateCache stores template caching
|
|
||||||
TemplateCache map[string]*template.Template
|
|
||||||
// GlobalSessions is the instance for the session manager
|
// GlobalSessions is the instance for the session manager
|
||||||
GlobalSessions *session.Manager
|
GlobalSessions *session.Manager
|
||||||
|
|
||||||
|
// appConfigPath is the path to the config files
|
||||||
|
appConfigPath string
|
||||||
|
// appConfigProvider is the provider for the config, default is ini
|
||||||
|
appConfigProvider = "ini"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
AppPath, _ = filepath.Abs(filepath.Dir(os.Args[0]))
|
||||||
|
|
||||||
|
os.Chdir(AppPath)
|
||||||
|
|
||||||
BConfig = &Config{
|
BConfig = &Config{
|
||||||
AppName: "beego",
|
AppName: "beego",
|
||||||
RunMode: DEV,
|
RunMode: DEV,
|
||||||
@ -162,7 +167,7 @@ func init() {
|
|||||||
SessionName: "beegosessionID",
|
SessionName: "beegosessionID",
|
||||||
SessionGCMaxLifetime: 3600,
|
SessionGCMaxLifetime: 3600,
|
||||||
SessionProviderConfig: "",
|
SessionProviderConfig: "",
|
||||||
SessionCookieLifeTime: 0, //set cookie default is the brower life
|
SessionCookieLifeTime: 0, //set cookie default is the browser life
|
||||||
SessionAutoSetCookie: true,
|
SessionAutoSetCookie: true,
|
||||||
SessionDomain: "",
|
SessionDomain: "",
|
||||||
},
|
},
|
||||||
@ -173,29 +178,29 @@ func init() {
|
|||||||
Outputs: map[string]string{"console": ""},
|
Outputs: map[string]string{"console": ""},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
ParseConfig()
|
|
||||||
|
appConfigPath = filepath.Join(AppPath, "conf", "app.conf")
|
||||||
|
if !utils.FileExists(appConfigPath) {
|
||||||
|
AppConfig = &beegoAppConfig{innerConfig: config.NewFakeConfig()}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := parseConfig(appConfigPath); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseConfig parsed default config file.
|
|
||||||
// now only support ini, next will support json.
|
// now only support ini, next will support json.
|
||||||
func ParseConfig() (err error) {
|
func parseConfig(appConfigPath string) (err error) {
|
||||||
if AppConfigPath == "" {
|
AppConfig, err = newAppConfig(appConfigProvider, appConfigPath)
|
||||||
if utils.FileExists(filepath.Join("conf", "app.conf")) {
|
|
||||||
AppConfigPath = filepath.Join("conf", "app.conf")
|
|
||||||
} else {
|
|
||||||
AppConfig = &beegoAppConfig{config.NewFakeConfig()}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
AppConfig, err = newAppConfig(AppConfigProvider, AppConfigPath)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// set the runmode first
|
// set the run mode first
|
||||||
if envRunMode := os.Getenv("BEEGO_RUNMODE"); envRunMode != "" {
|
if envRunMode := os.Getenv("BEEGO_RUNMODE"); envRunMode != "" {
|
||||||
BConfig.RunMode = envRunMode
|
BConfig.RunMode = envRunMode
|
||||||
} else if runmode := AppConfig.String("RunMode"); runmode != "" {
|
} else if runMode := AppConfig.String("RunMode"); runMode != "" {
|
||||||
BConfig.RunMode = runmode
|
BConfig.RunMode = runMode
|
||||||
}
|
}
|
||||||
|
|
||||||
BConfig.AppName = AppConfig.DefaultString("AppName", BConfig.AppName)
|
BConfig.AppName = AppConfig.DefaultString("AppName", BConfig.AppName)
|
||||||
@ -241,6 +246,8 @@ func ParseConfig() (err error) {
|
|||||||
BConfig.WebConfig.Session.SessionCookieLifeTime = AppConfig.DefaultInt("SessionCookieLifeTime", BConfig.WebConfig.Session.SessionCookieLifeTime)
|
BConfig.WebConfig.Session.SessionCookieLifeTime = AppConfig.DefaultInt("SessionCookieLifeTime", BConfig.WebConfig.Session.SessionCookieLifeTime)
|
||||||
BConfig.WebConfig.Session.SessionAutoSetCookie = AppConfig.DefaultBool("SessionAutoSetCookie", BConfig.WebConfig.Session.SessionAutoSetCookie)
|
BConfig.WebConfig.Session.SessionAutoSetCookie = AppConfig.DefaultBool("SessionAutoSetCookie", BConfig.WebConfig.Session.SessionAutoSetCookie)
|
||||||
BConfig.WebConfig.Session.SessionDomain = AppConfig.DefaultString("SessionDomain", BConfig.WebConfig.Session.SessionDomain)
|
BConfig.WebConfig.Session.SessionDomain = AppConfig.DefaultString("SessionDomain", BConfig.WebConfig.Session.SessionDomain)
|
||||||
|
BConfig.Log.AccessLogs = AppConfig.DefaultBool("LogAccessLogs", BConfig.Log.AccessLogs)
|
||||||
|
BConfig.Log.FileLineNum = AppConfig.DefaultBool("LogFileLineNum", BConfig.Log.FileLineNum)
|
||||||
|
|
||||||
if sd := AppConfig.String("StaticDir"); sd != "" {
|
if sd := AppConfig.String("StaticDir"); sd != "" {
|
||||||
for k := range BConfig.WebConfig.StaticDir {
|
for k := range BConfig.WebConfig.StaticDir {
|
||||||
@ -273,15 +280,58 @@ func ParseConfig() (err error) {
|
|||||||
BConfig.WebConfig.StaticExtensionsToGzip = fileExts
|
BConfig.WebConfig.StaticExtensionsToGzip = fileExts
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if lo := AppConfig.String("LogOutputs"); lo != "" {
|
||||||
|
los := strings.Split(lo, ";")
|
||||||
|
for _, v := range los {
|
||||||
|
if logType2Config := strings.SplitN(v, ",", 2); len(logType2Config) == 2 {
|
||||||
|
BConfig.Log.Outputs[logType2Config[0]] = logType2Config[1]
|
||||||
|
} else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//init log
|
||||||
|
BeeLogger.Reset()
|
||||||
|
for adaptor, config := range BConfig.Log.Outputs {
|
||||||
|
err = BeeLogger.SetLogger(adaptor, config)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("%s with the config `%s` got err:%s\n", adaptor, config, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SetLogFuncCall(BConfig.Log.FileLineNum)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LoadAppConfig allow developer to apply a config file
|
||||||
|
func LoadAppConfig(adapterName, configPath string) error {
|
||||||
|
absConfigPath, err := filepath.Abs(configPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !utils.FileExists(absConfigPath) {
|
||||||
|
return fmt.Errorf("the target config file: %s don't exist", configPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
if absConfigPath == appConfigPath {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
appConfigPath = absConfigPath
|
||||||
|
appConfigProvider = adapterName
|
||||||
|
|
||||||
|
return parseConfig(appConfigPath)
|
||||||
|
}
|
||||||
|
|
||||||
type beegoAppConfig struct {
|
type beegoAppConfig struct {
|
||||||
innerConfig config.Configer
|
innerConfig config.Configer
|
||||||
}
|
}
|
||||||
|
|
||||||
func newAppConfig(AppConfigProvider, AppConfigPath string) (*beegoAppConfig, error) {
|
func newAppConfig(appConfigProvider, appConfigPath string) (*beegoAppConfig, error) {
|
||||||
ac, err := config.NewConfig(AppConfigProvider, AppConfigPath)
|
ac, err := config.NewConfig(appConfigProvider, appConfigPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -337,46 +387,46 @@ func (b *beegoAppConfig) Float(key string) (float64, error) {
|
|||||||
return b.innerConfig.Float(key)
|
return b.innerConfig.Float(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *beegoAppConfig) DefaultString(key string, defaultval string) string {
|
func (b *beegoAppConfig) DefaultString(key string, defaultVal string) string {
|
||||||
if v := b.String(key); v != "" {
|
if v := b.String(key); v != "" {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
return defaultval
|
return defaultVal
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *beegoAppConfig) DefaultStrings(key string, defaultval []string) []string {
|
func (b *beegoAppConfig) DefaultStrings(key string, defaultVal []string) []string {
|
||||||
if v := b.Strings(key); len(v) != 0 {
|
if v := b.Strings(key); len(v) != 0 {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
return defaultval
|
return defaultVal
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *beegoAppConfig) DefaultInt(key string, defaultval int) int {
|
func (b *beegoAppConfig) DefaultInt(key string, defaultVal int) int {
|
||||||
if v, err := b.Int(key); err == nil {
|
if v, err := b.Int(key); err == nil {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
return defaultval
|
return defaultVal
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *beegoAppConfig) DefaultInt64(key string, defaultval int64) int64 {
|
func (b *beegoAppConfig) DefaultInt64(key string, defaultVal int64) int64 {
|
||||||
if v, err := b.Int64(key); err == nil {
|
if v, err := b.Int64(key); err == nil {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
return defaultval
|
return defaultVal
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *beegoAppConfig) DefaultBool(key string, defaultval bool) bool {
|
func (b *beegoAppConfig) DefaultBool(key string, defaultVal bool) bool {
|
||||||
if v, err := b.Bool(key); err == nil {
|
if v, err := b.Bool(key); err == nil {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
return defaultval
|
return defaultVal
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *beegoAppConfig) DefaultFloat(key string, defaultval float64) float64 {
|
func (b *beegoAppConfig) DefaultFloat(key string, defaultVal float64) float64 {
|
||||||
if v, err := b.Float(key); err == nil {
|
if v, err := b.Float(key); err == nil {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
return defaultval
|
return defaultVal
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *beegoAppConfig) DIY(key string) (interface{}, error) {
|
func (b *beegoAppConfig) DIY(key string) (interface{}, error) {
|
||||||
|
36
vendor/github.com/astaxie/beego/config/config.go
generated
vendored
36
vendor/github.com/astaxie/beego/config/config.go
generated
vendored
@ -106,3 +106,39 @@ func NewConfigData(adapterName string, data []byte) (Configer, error) {
|
|||||||
}
|
}
|
||||||
return adapter.ParseData(data)
|
return adapter.ParseData(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ParseBool returns the boolean value represented by the string.
|
||||||
|
//
|
||||||
|
// It accepts 1, 1.0, t, T, TRUE, true, True, YES, yes, Yes,Y, y, ON, on, On,
|
||||||
|
// 0, 0.0, f, F, FALSE, false, False, NO, no, No, N,n, OFF, off, Off.
|
||||||
|
// Any other value returns an error.
|
||||||
|
func ParseBool(val interface{}) (value bool, err error) {
|
||||||
|
if val != nil {
|
||||||
|
switch v := val.(type) {
|
||||||
|
case bool:
|
||||||
|
return v, nil
|
||||||
|
case string:
|
||||||
|
switch v {
|
||||||
|
case "1", "t", "T", "true", "TRUE", "True", "YES", "yes", "Yes", "Y", "y", "ON", "on", "On":
|
||||||
|
return true, nil
|
||||||
|
case "0", "f", "F", "false", "FALSE", "False", "NO", "no", "No", "N", "n", "OFF", "off", "Off":
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
case int8, int32, int64:
|
||||||
|
strV := fmt.Sprintf("%s", v)
|
||||||
|
if strV == "1" {
|
||||||
|
return true, nil
|
||||||
|
} else if strV == "0" {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
case float64:
|
||||||
|
if v == 1 {
|
||||||
|
return true, nil
|
||||||
|
} else if v == 0 {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false, fmt.Errorf("parsing %q: invalid syntax", val)
|
||||||
|
}
|
||||||
|
return false, fmt.Errorf("parsing <nil>: invalid syntax")
|
||||||
|
}
|
||||||
|
10
vendor/github.com/astaxie/beego/config/fake.go
generated
vendored
10
vendor/github.com/astaxie/beego/config/fake.go
generated
vendored
@ -46,12 +46,16 @@ func (c *fakeConfigContainer) DefaultString(key string, defaultval string) strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *fakeConfigContainer) Strings(key string) []string {
|
func (c *fakeConfigContainer) Strings(key string) []string {
|
||||||
return strings.Split(c.getData(key), ";")
|
v := c.getData(key)
|
||||||
|
if v == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return strings.Split(v, ";")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *fakeConfigContainer) DefaultStrings(key string, defaultval []string) []string {
|
func (c *fakeConfigContainer) DefaultStrings(key string, defaultval []string) []string {
|
||||||
v := c.Strings(key)
|
v := c.Strings(key)
|
||||||
if len(v) == 0 {
|
if v == nil {
|
||||||
return defaultval
|
return defaultval
|
||||||
}
|
}
|
||||||
return v
|
return v
|
||||||
@ -82,7 +86,7 @@ func (c *fakeConfigContainer) DefaultInt64(key string, defaultval int64) int64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *fakeConfigContainer) Bool(key string) (bool, error) {
|
func (c *fakeConfigContainer) Bool(key string) (bool, error) {
|
||||||
return strconv.ParseBool(c.getData(key))
|
return ParseBool(c.getData(key))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *fakeConfigContainer) DefaultBool(key string, defaultval bool) bool {
|
func (c *fakeConfigContainer) DefaultBool(key string, defaultval bool) bool {
|
||||||
|
51
vendor/github.com/astaxie/beego/config/ini.go
generated
vendored
51
vendor/github.com/astaxie/beego/config/ini.go
generated
vendored
@ -27,7 +27,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
"unicode"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -97,9 +96,11 @@ func (ini *IniConfig) parseFile(name string) (*IniConfigContainer, error) {
|
|||||||
}
|
}
|
||||||
if bComment != nil {
|
if bComment != nil {
|
||||||
line = bytes.TrimLeft(line, string(bComment))
|
line = bytes.TrimLeft(line, string(bComment))
|
||||||
line = bytes.TrimLeftFunc(line, unicode.IsSpace)
|
// Need append to a new line if multi-line comments.
|
||||||
|
if comment.Len() > 0 {
|
||||||
|
comment.WriteByte('\n')
|
||||||
|
}
|
||||||
comment.Write(line)
|
comment.Write(line)
|
||||||
comment.WriteByte('\n')
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,7 +195,7 @@ type IniConfigContainer struct {
|
|||||||
|
|
||||||
// Bool returns the boolean value for a given key.
|
// Bool returns the boolean value for a given key.
|
||||||
func (c *IniConfigContainer) Bool(key string) (bool, error) {
|
func (c *IniConfigContainer) Bool(key string) (bool, error) {
|
||||||
return strconv.ParseBool(c.getdata(key))
|
return ParseBool(c.getdata(key))
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultBool returns the boolean value for a given key.
|
// DefaultBool returns the boolean value for a given key.
|
||||||
@ -268,15 +269,20 @@ func (c *IniConfigContainer) DefaultString(key string, defaultval string) string
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Strings returns the []string value for a given key.
|
// Strings returns the []string value for a given key.
|
||||||
|
// Return nil if config value does not exist or is empty.
|
||||||
func (c *IniConfigContainer) Strings(key string) []string {
|
func (c *IniConfigContainer) Strings(key string) []string {
|
||||||
return strings.Split(c.String(key), ";")
|
v := c.String(key)
|
||||||
|
if v == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return strings.Split(v, ";")
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultStrings returns the []string value for a given key.
|
// DefaultStrings returns the []string value for a given key.
|
||||||
// if err != nil return defaltval
|
// if err != nil return defaltval
|
||||||
func (c *IniConfigContainer) DefaultStrings(key string, defaultval []string) []string {
|
func (c *IniConfigContainer) DefaultStrings(key string, defaultval []string) []string {
|
||||||
v := c.Strings(key)
|
v := c.Strings(key)
|
||||||
if len(v) == 0 {
|
if v == nil {
|
||||||
return defaultval
|
return defaultval
|
||||||
}
|
}
|
||||||
return v
|
return v
|
||||||
@ -299,14 +305,35 @@ func (c *IniConfigContainer) SaveConfigFile(filename string) (err error) {
|
|||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
|
// Get section or key comments. Fixed #1607
|
||||||
|
getCommentStr := func(section, key string) string {
|
||||||
|
comment, ok := "", false
|
||||||
|
if len(key) == 0 {
|
||||||
|
comment, ok = c.sectionComment[section]
|
||||||
|
} else {
|
||||||
|
comment, ok = c.keyComment[section+"."+key]
|
||||||
|
}
|
||||||
|
|
||||||
|
if ok {
|
||||||
|
// Empty comment
|
||||||
|
if len(comment) == 0 || len(strings.TrimSpace(comment)) == 0 {
|
||||||
|
return string(bNumComment)
|
||||||
|
}
|
||||||
|
prefix := string(bNumComment)
|
||||||
|
// Add the line head character "#"
|
||||||
|
return prefix + strings.Replace(comment, lineBreak, lineBreak+prefix, -1)
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
buf := bytes.NewBuffer(nil)
|
buf := bytes.NewBuffer(nil)
|
||||||
// Save default section at first place
|
// Save default section at first place
|
||||||
if dt, ok := c.data[defaultSection]; ok {
|
if dt, ok := c.data[defaultSection]; ok {
|
||||||
for key, val := range dt {
|
for key, val := range dt {
|
||||||
if key != " " {
|
if key != " " {
|
||||||
// Write key comments.
|
// Write key comments.
|
||||||
if v, ok := c.keyComment[key]; ok {
|
if v := getCommentStr(defaultSection, key); len(v) > 0 {
|
||||||
if _, err = buf.WriteString(string(bNumComment) + v + lineBreak); err != nil {
|
if _, err = buf.WriteString(v + lineBreak); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -327,8 +354,8 @@ func (c *IniConfigContainer) SaveConfigFile(filename string) (err error) {
|
|||||||
for section, dt := range c.data {
|
for section, dt := range c.data {
|
||||||
if section != defaultSection {
|
if section != defaultSection {
|
||||||
// Write section comments.
|
// Write section comments.
|
||||||
if v, ok := c.sectionComment[section]; ok {
|
if v := getCommentStr(section, ""); len(v) > 0 {
|
||||||
if _, err = buf.WriteString(string(bNumComment) + v + lineBreak); err != nil {
|
if _, err = buf.WriteString(v + lineBreak); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -341,8 +368,8 @@ func (c *IniConfigContainer) SaveConfigFile(filename string) (err error) {
|
|||||||
for key, val := range dt {
|
for key, val := range dt {
|
||||||
if key != " " {
|
if key != " " {
|
||||||
// Write key comments.
|
// Write key comments.
|
||||||
if v, ok := c.keyComment[key]; ok {
|
if v := getCommentStr(section, key); len(v) > 0 {
|
||||||
if _, err = buf.WriteString(string(bNumComment) + v + lineBreak); err != nil {
|
if _, err = buf.WriteString(v + lineBreak); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
12
vendor/github.com/astaxie/beego/config/json.go
generated
vendored
12
vendor/github.com/astaxie/beego/config/json.go
generated
vendored
@ -17,6 +17,7 @@ package config
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
@ -70,12 +71,9 @@ type JSONConfigContainer struct {
|
|||||||
func (c *JSONConfigContainer) Bool(key string) (bool, error) {
|
func (c *JSONConfigContainer) Bool(key string) (bool, error) {
|
||||||
val := c.getData(key)
|
val := c.getData(key)
|
||||||
if val != nil {
|
if val != nil {
|
||||||
if v, ok := val.(bool); ok {
|
return ParseBool(val)
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
return false, errors.New("not bool value")
|
|
||||||
}
|
}
|
||||||
return false, errors.New("not exist key:" + key)
|
return false, fmt.Errorf("not exist key: %q", key)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultBool return the bool value if has no error
|
// DefaultBool return the bool value if has no error
|
||||||
@ -175,7 +173,7 @@ func (c *JSONConfigContainer) DefaultString(key string, defaultval string) strin
|
|||||||
func (c *JSONConfigContainer) Strings(key string) []string {
|
func (c *JSONConfigContainer) Strings(key string) []string {
|
||||||
stringVal := c.String(key)
|
stringVal := c.String(key)
|
||||||
if stringVal == "" {
|
if stringVal == "" {
|
||||||
return []string{}
|
return nil
|
||||||
}
|
}
|
||||||
return strings.Split(c.String(key), ";")
|
return strings.Split(c.String(key), ";")
|
||||||
}
|
}
|
||||||
@ -183,7 +181,7 @@ func (c *JSONConfigContainer) Strings(key string) []string {
|
|||||||
// DefaultStrings returns the []string value for a given key.
|
// DefaultStrings returns the []string value for a given key.
|
||||||
// if err != nil return defaltval
|
// if err != nil return defaltval
|
||||||
func (c *JSONConfigContainer) DefaultStrings(key string, defaultval []string) []string {
|
func (c *JSONConfigContainer) DefaultStrings(key string, defaultval []string) []string {
|
||||||
if v := c.Strings(key); len(v) > 0 {
|
if v := c.Strings(key); v != nil {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
return defaultval
|
return defaultval
|
||||||
|
229
vendor/github.com/astaxie/beego/config/xml/xml.go
generated
vendored
229
vendor/github.com/astaxie/beego/config/xml/xml.go
generated
vendored
@ -1,229 +0,0 @@
|
|||||||
// Copyright 2014 beego Author. All Rights Reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
// Package xml for config provider
|
|
||||||
//
|
|
||||||
// depend on github.com/beego/x2j
|
|
||||||
//
|
|
||||||
// go install github.com/beego/x2j
|
|
||||||
//
|
|
||||||
// Usage:
|
|
||||||
// import(
|
|
||||||
// _ "github.com/astaxie/beego/config/xml"
|
|
||||||
// "github.com/astaxie/beego/config"
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// cnf, err := config.NewConfig("xml", "config.xml")
|
|
||||||
//
|
|
||||||
// more docs http://beego.me/docs/module/config.md
|
|
||||||
package xml
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/xml"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/astaxie/beego/config"
|
|
||||||
"github.com/beego/x2j"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Config is a xml config parser and implements Config interface.
|
|
||||||
// xml configurations should be included in <config></config> tag.
|
|
||||||
// only support key/value pair as <key>value</key> as each item.
|
|
||||||
type Config struct{}
|
|
||||||
|
|
||||||
// Parse returns a ConfigContainer with parsed xml config map.
|
|
||||||
func (xc *Config) Parse(filename string) (config.Configer, error) {
|
|
||||||
file, err := os.Open(filename)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
x := &ConfigContainer{data: make(map[string]interface{})}
|
|
||||||
content, err := ioutil.ReadAll(file)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
d, err := x2j.DocToMap(string(content))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
x.data = d["config"].(map[string]interface{})
|
|
||||||
return x, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseData xml data
|
|
||||||
func (xc *Config) ParseData(data []byte) (config.Configer, error) {
|
|
||||||
// Save memory data to temporary file
|
|
||||||
tmpName := path.Join(os.TempDir(), "beego", fmt.Sprintf("%d", time.Now().Nanosecond()))
|
|
||||||
os.MkdirAll(path.Dir(tmpName), os.ModePerm)
|
|
||||||
if err := ioutil.WriteFile(tmpName, data, 0655); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return xc.Parse(tmpName)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ConfigContainer A Config represents the xml configuration.
|
|
||||||
type ConfigContainer struct {
|
|
||||||
data map[string]interface{}
|
|
||||||
sync.Mutex
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bool returns the boolean value for a given key.
|
|
||||||
func (c *ConfigContainer) Bool(key string) (bool, error) {
|
|
||||||
return strconv.ParseBool(c.data[key].(string))
|
|
||||||
}
|
|
||||||
|
|
||||||
// DefaultBool return the bool value if has no error
|
|
||||||
// otherwise return the defaultval
|
|
||||||
func (c *ConfigContainer) DefaultBool(key string, defaultval bool) bool {
|
|
||||||
v, err := c.Bool(key)
|
|
||||||
if err != nil {
|
|
||||||
return defaultval
|
|
||||||
}
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int returns the integer value for a given key.
|
|
||||||
func (c *ConfigContainer) Int(key string) (int, error) {
|
|
||||||
return strconv.Atoi(c.data[key].(string))
|
|
||||||
}
|
|
||||||
|
|
||||||
// DefaultInt returns the integer value for a given key.
|
|
||||||
// if err != nil return defaltval
|
|
||||||
func (c *ConfigContainer) DefaultInt(key string, defaultval int) int {
|
|
||||||
v, err := c.Int(key)
|
|
||||||
if err != nil {
|
|
||||||
return defaultval
|
|
||||||
}
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int64 returns the int64 value for a given key.
|
|
||||||
func (c *ConfigContainer) Int64(key string) (int64, error) {
|
|
||||||
return strconv.ParseInt(c.data[key].(string), 10, 64)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DefaultInt64 returns the int64 value for a given key.
|
|
||||||
// if err != nil return defaltval
|
|
||||||
func (c *ConfigContainer) DefaultInt64(key string, defaultval int64) int64 {
|
|
||||||
v, err := c.Int64(key)
|
|
||||||
if err != nil {
|
|
||||||
return defaultval
|
|
||||||
}
|
|
||||||
return v
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float returns the float value for a given key.
|
|
||||||
func (c *ConfigContainer) Float(key string) (float64, error) {
|
|
||||||
return strconv.ParseFloat(c.data[key].(string), 64)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DefaultFloat returns the float64 value for a given key.
|
|
||||||
// if err != nil return defaltval
|
|
||||||
func (c *ConfigContainer) DefaultFloat(key string, defaultval float64) float64 {
|
|
||||||
v, err := c.Float(key)
|
|
||||||
if err != nil {
|
|
||||||
return defaultval
|
|
||||||
}
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the string value for a given key.
|
|
||||||
func (c *ConfigContainer) String(key string) string {
|
|
||||||
if v, ok := c.data[key].(string); ok {
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// DefaultString returns the string value for a given key.
|
|
||||||
// if err != nil return defaltval
|
|
||||||
func (c *ConfigContainer) DefaultString(key string, defaultval string) string {
|
|
||||||
v := c.String(key)
|
|
||||||
if v == "" {
|
|
||||||
return defaultval
|
|
||||||
}
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// Strings returns the []string value for a given key.
|
|
||||||
func (c *ConfigContainer) Strings(key string) []string {
|
|
||||||
return strings.Split(c.String(key), ";")
|
|
||||||
}
|
|
||||||
|
|
||||||
// DefaultStrings returns the []string value for a given key.
|
|
||||||
// if err != nil return defaltval
|
|
||||||
func (c *ConfigContainer) DefaultStrings(key string, defaultval []string) []string {
|
|
||||||
v := c.Strings(key)
|
|
||||||
if len(v) == 0 {
|
|
||||||
return defaultval
|
|
||||||
}
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetSection returns map for the given section
|
|
||||||
func (c *ConfigContainer) GetSection(section string) (map[string]string, error) {
|
|
||||||
if v, ok := c.data[section]; ok {
|
|
||||||
return v.(map[string]string), nil
|
|
||||||
}
|
|
||||||
return nil, errors.New("not exist setction")
|
|
||||||
}
|
|
||||||
|
|
||||||
// SaveConfigFile save the config into file
|
|
||||||
func (c *ConfigContainer) SaveConfigFile(filename string) (err error) {
|
|
||||||
// Write configuration file by filename.
|
|
||||||
f, err := os.Create(filename)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
b, err := xml.MarshalIndent(c.data, " ", " ")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, err = f.Write(b)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set writes a new value for key.
|
|
||||||
func (c *ConfigContainer) Set(key, val string) error {
|
|
||||||
c.Lock()
|
|
||||||
defer c.Unlock()
|
|
||||||
c.data[key] = val
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DIY returns the raw value by a given key.
|
|
||||||
func (c *ConfigContainer) DIY(key string) (v interface{}, err error) {
|
|
||||||
if v, ok := c.data[key]; ok {
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
return nil, errors.New("not exist key")
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
config.Register("xml", &Config{})
|
|
||||||
}
|
|
266
vendor/github.com/astaxie/beego/config/yaml/yaml.go
generated
vendored
266
vendor/github.com/astaxie/beego/config/yaml/yaml.go
generated
vendored
@ -1,266 +0,0 @@
|
|||||||
// Copyright 2014 beego Author. All Rights Reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
// Package yaml for config provider
|
|
||||||
//
|
|
||||||
// depend on github.com/beego/goyaml2
|
|
||||||
//
|
|
||||||
// go install github.com/beego/goyaml2
|
|
||||||
//
|
|
||||||
// Usage:
|
|
||||||
// import(
|
|
||||||
// _ "github.com/astaxie/beego/config/yaml"
|
|
||||||
// "github.com/astaxie/beego/config"
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// cnf, err := config.NewConfig("yaml", "config.yaml")
|
|
||||||
//
|
|
||||||
// more docs http://beego.me/docs/module/config.md
|
|
||||||
package yaml
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/astaxie/beego/config"
|
|
||||||
"github.com/beego/goyaml2"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Config is a yaml config parser and implements Config interface.
|
|
||||||
type Config struct{}
|
|
||||||
|
|
||||||
// Parse returns a ConfigContainer with parsed yaml config map.
|
|
||||||
func (yaml *Config) Parse(filename string) (y config.Configer, err error) {
|
|
||||||
cnf, err := ReadYmlReader(filename)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
y = &ConfigContainer{
|
|
||||||
data: cnf,
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseData parse yaml data
|
|
||||||
func (yaml *Config) ParseData(data []byte) (config.Configer, error) {
|
|
||||||
// Save memory data to temporary file
|
|
||||||
tmpName := path.Join(os.TempDir(), "beego", fmt.Sprintf("%d", time.Now().Nanosecond()))
|
|
||||||
os.MkdirAll(path.Dir(tmpName), os.ModePerm)
|
|
||||||
if err := ioutil.WriteFile(tmpName, data, 0655); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return yaml.Parse(tmpName)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadYmlReader Read yaml file to map.
|
|
||||||
// if json like, use json package, unless goyaml2 package.
|
|
||||||
func ReadYmlReader(path string) (cnf map[string]interface{}, err error) {
|
|
||||||
f, err := os.Open(path)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
|
|
||||||
buf, err := ioutil.ReadAll(f)
|
|
||||||
if err != nil || len(buf) < 3 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if string(buf[0:1]) == "{" {
|
|
||||||
log.Println("Look like a Json, try json umarshal")
|
|
||||||
err = json.Unmarshal(buf, &cnf)
|
|
||||||
if err == nil {
|
|
||||||
log.Println("It is Json Map")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data, err := goyaml2.Read(bytes.NewBuffer(buf))
|
|
||||||
if err != nil {
|
|
||||||
log.Println("Goyaml2 ERR>", string(buf), err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if data == nil {
|
|
||||||
log.Println("Goyaml2 output nil? Pls report bug\n" + string(buf))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
cnf, ok := data.(map[string]interface{})
|
|
||||||
if !ok {
|
|
||||||
log.Println("Not a Map? >> ", string(buf), data)
|
|
||||||
cnf = nil
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// ConfigContainer A Config represents the yaml configuration.
|
|
||||||
type ConfigContainer struct {
|
|
||||||
data map[string]interface{}
|
|
||||||
sync.Mutex
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bool returns the boolean value for a given key.
|
|
||||||
func (c *ConfigContainer) Bool(key string) (bool, error) {
|
|
||||||
if v, ok := c.data[key].(bool); ok {
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
return false, errors.New("not bool value")
|
|
||||||
}
|
|
||||||
|
|
||||||
// DefaultBool return the bool value if has no error
|
|
||||||
// otherwise return the defaultval
|
|
||||||
func (c *ConfigContainer) DefaultBool(key string, defaultval bool) bool {
|
|
||||||
v, err := c.Bool(key)
|
|
||||||
if err != nil {
|
|
||||||
return defaultval
|
|
||||||
}
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int returns the integer value for a given key.
|
|
||||||
func (c *ConfigContainer) Int(key string) (int, error) {
|
|
||||||
if v, ok := c.data[key].(int64); ok {
|
|
||||||
return int(v), nil
|
|
||||||
}
|
|
||||||
return 0, errors.New("not int value")
|
|
||||||
}
|
|
||||||
|
|
||||||
// DefaultInt returns the integer value for a given key.
|
|
||||||
// if err != nil return defaltval
|
|
||||||
func (c *ConfigContainer) DefaultInt(key string, defaultval int) int {
|
|
||||||
v, err := c.Int(key)
|
|
||||||
if err != nil {
|
|
||||||
return defaultval
|
|
||||||
}
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int64 returns the int64 value for a given key.
|
|
||||||
func (c *ConfigContainer) Int64(key string) (int64, error) {
|
|
||||||
if v, ok := c.data[key].(int64); ok {
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
return 0, errors.New("not bool value")
|
|
||||||
}
|
|
||||||
|
|
||||||
// DefaultInt64 returns the int64 value for a given key.
|
|
||||||
// if err != nil return defaltval
|
|
||||||
func (c *ConfigContainer) DefaultInt64(key string, defaultval int64) int64 {
|
|
||||||
v, err := c.Int64(key)
|
|
||||||
if err != nil {
|
|
||||||
return defaultval
|
|
||||||
}
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float returns the float value for a given key.
|
|
||||||
func (c *ConfigContainer) Float(key string) (float64, error) {
|
|
||||||
if v, ok := c.data[key].(float64); ok {
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
return 0.0, errors.New("not float64 value")
|
|
||||||
}
|
|
||||||
|
|
||||||
// DefaultFloat returns the float64 value for a given key.
|
|
||||||
// if err != nil return defaltval
|
|
||||||
func (c *ConfigContainer) DefaultFloat(key string, defaultval float64) float64 {
|
|
||||||
v, err := c.Float(key)
|
|
||||||
if err != nil {
|
|
||||||
return defaultval
|
|
||||||
}
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the string value for a given key.
|
|
||||||
func (c *ConfigContainer) String(key string) string {
|
|
||||||
if v, ok := c.data[key].(string); ok {
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// DefaultString returns the string value for a given key.
|
|
||||||
// if err != nil return defaltval
|
|
||||||
func (c *ConfigContainer) DefaultString(key string, defaultval string) string {
|
|
||||||
v := c.String(key)
|
|
||||||
if v == "" {
|
|
||||||
return defaultval
|
|
||||||
}
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// Strings returns the []string value for a given key.
|
|
||||||
func (c *ConfigContainer) Strings(key string) []string {
|
|
||||||
return strings.Split(c.String(key), ";")
|
|
||||||
}
|
|
||||||
|
|
||||||
// DefaultStrings returns the []string value for a given key.
|
|
||||||
// if err != nil return defaltval
|
|
||||||
func (c *ConfigContainer) DefaultStrings(key string, defaultval []string) []string {
|
|
||||||
v := c.Strings(key)
|
|
||||||
if len(v) == 0 {
|
|
||||||
return defaultval
|
|
||||||
}
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetSection returns map for the given section
|
|
||||||
func (c *ConfigContainer) GetSection(section string) (map[string]string, error) {
|
|
||||||
v, ok := c.data[section]
|
|
||||||
if ok {
|
|
||||||
return v.(map[string]string), nil
|
|
||||||
}
|
|
||||||
return nil, errors.New("not exist setction")
|
|
||||||
}
|
|
||||||
|
|
||||||
// SaveConfigFile save the config into file
|
|
||||||
func (c *ConfigContainer) SaveConfigFile(filename string) (err error) {
|
|
||||||
// Write configuration file by filename.
|
|
||||||
f, err := os.Create(filename)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
err = goyaml2.Write(f, c.data)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set writes a new value for key.
|
|
||||||
func (c *ConfigContainer) Set(key, val string) error {
|
|
||||||
c.Lock()
|
|
||||||
defer c.Unlock()
|
|
||||||
c.data[key] = val
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DIY returns the raw value by a given key.
|
|
||||||
func (c *ConfigContainer) DIY(key string) (v interface{}, err error) {
|
|
||||||
if v, ok := c.data[key]; ok {
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
return nil, errors.New("not exist key")
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
config.Register("yaml", &Config{})
|
|
||||||
}
|
|
51
vendor/github.com/astaxie/beego/context/context.go
generated
vendored
51
vendor/github.com/astaxie/beego/context/context.go
generated
vendored
@ -24,11 +24,13 @@ package context
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"bytes"
|
||||||
"crypto/hmac"
|
"crypto/hmac"
|
||||||
"crypto/sha1"
|
"crypto/sha1"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -59,7 +61,10 @@ type Context struct {
|
|||||||
// Reset init Context, BeegoInput and BeegoOutput
|
// Reset init Context, BeegoInput and BeegoOutput
|
||||||
func (ctx *Context) Reset(rw http.ResponseWriter, r *http.Request) {
|
func (ctx *Context) Reset(rw http.ResponseWriter, r *http.Request) {
|
||||||
ctx.Request = r
|
ctx.Request = r
|
||||||
ctx.ResponseWriter = &Response{rw, false, 0}
|
if ctx.ResponseWriter == nil {
|
||||||
|
ctx.ResponseWriter = &Response{}
|
||||||
|
}
|
||||||
|
ctx.ResponseWriter.reset(rw)
|
||||||
ctx.Input.Reset(ctx)
|
ctx.Input.Reset(ctx)
|
||||||
ctx.Output.Reset(ctx)
|
ctx.Output.Reset(ctx)
|
||||||
}
|
}
|
||||||
@ -176,25 +181,43 @@ type Response struct {
|
|||||||
Status int
|
Status int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Response) reset(rw http.ResponseWriter) {
|
||||||
|
r.ResponseWriter = rw
|
||||||
|
r.Status = 0
|
||||||
|
r.Started = false
|
||||||
|
}
|
||||||
|
|
||||||
// Write writes the data to the connection as part of an HTTP reply,
|
// Write writes the data to the connection as part of an HTTP reply,
|
||||||
// and sets `started` to true.
|
// and sets `started` to true.
|
||||||
// started means the response has sent out.
|
// started means the response has sent out.
|
||||||
func (w *Response) Write(p []byte) (int, error) {
|
func (r *Response) Write(p []byte) (int, error) {
|
||||||
w.Started = true
|
r.Started = true
|
||||||
return w.ResponseWriter.Write(p)
|
return r.ResponseWriter.Write(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy writes the data to the connection as part of an HTTP reply,
|
||||||
|
// and sets `started` to true.
|
||||||
|
// started means the response has sent out.
|
||||||
|
func (r *Response) Copy(buf *bytes.Buffer) (int64, error) {
|
||||||
|
r.Started = true
|
||||||
|
return io.Copy(r.ResponseWriter, buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteHeader sends an HTTP response header with status code,
|
// WriteHeader sends an HTTP response header with status code,
|
||||||
// and sets `started` to true.
|
// and sets `started` to true.
|
||||||
func (w *Response) WriteHeader(code int) {
|
func (r *Response) WriteHeader(code int) {
|
||||||
w.Status = code
|
if r.Status > 0 {
|
||||||
w.Started = true
|
//prevent multiple response.WriteHeader calls
|
||||||
w.ResponseWriter.WriteHeader(code)
|
return
|
||||||
|
}
|
||||||
|
r.Status = code
|
||||||
|
r.Started = true
|
||||||
|
r.ResponseWriter.WriteHeader(code)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hijack hijacker for http
|
// Hijack hijacker for http
|
||||||
func (w *Response) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
func (r *Response) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
||||||
hj, ok := w.ResponseWriter.(http.Hijacker)
|
hj, ok := r.ResponseWriter.(http.Hijacker)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, nil, errors.New("webserver doesn't support hijacking")
|
return nil, nil, errors.New("webserver doesn't support hijacking")
|
||||||
}
|
}
|
||||||
@ -202,15 +225,15 @@ func (w *Response) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Flush http.Flusher
|
// Flush http.Flusher
|
||||||
func (w *Response) Flush() {
|
func (r *Response) Flush() {
|
||||||
if f, ok := w.ResponseWriter.(http.Flusher); ok {
|
if f, ok := r.ResponseWriter.(http.Flusher); ok {
|
||||||
f.Flush()
|
f.Flush()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CloseNotify http.CloseNotifier
|
// CloseNotify http.CloseNotifier
|
||||||
func (w *Response) CloseNotify() <-chan bool {
|
func (r *Response) CloseNotify() <-chan bool {
|
||||||
if cn, ok := w.ResponseWriter.(http.CloseNotifier); ok {
|
if cn, ok := r.ResponseWriter.(http.CloseNotifier); ok {
|
||||||
return cn.CloseNotify()
|
return cn.CloseNotify()
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
7
vendor/github.com/astaxie/beego/context/input.go
generated
vendored
7
vendor/github.com/astaxie/beego/context/input.go
generated
vendored
@ -287,6 +287,13 @@ func (input *BeegoInput) Params() map[string]string {
|
|||||||
|
|
||||||
// SetParam will set the param with key and value
|
// SetParam will set the param with key and value
|
||||||
func (input *BeegoInput) SetParam(key, val string) {
|
func (input *BeegoInput) SetParam(key, val string) {
|
||||||
|
// check if already exists
|
||||||
|
for i, v := range input.pnames {
|
||||||
|
if v == key && i <= len(input.pvalues) {
|
||||||
|
input.pvalues[i] = val
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
input.pvalues = append(input.pvalues, val)
|
input.pvalues = append(input.pvalues, val)
|
||||||
input.pnames = append(input.pnames, key)
|
input.pnames = append(input.pnames, key)
|
||||||
}
|
}
|
||||||
|
20
vendor/github.com/astaxie/beego/context/output.go
generated
vendored
20
vendor/github.com/astaxie/beego/context/output.go
generated
vendored
@ -21,7 +21,6 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"html/template"
|
"html/template"
|
||||||
"io"
|
|
||||||
"mime"
|
"mime"
|
||||||
"net/http"
|
"net/http"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@ -57,7 +56,7 @@ func (output *BeegoOutput) Header(key, val string) {
|
|||||||
// Body sets response body content.
|
// Body sets response body content.
|
||||||
// if EnableGzip, compress content string.
|
// if EnableGzip, compress content string.
|
||||||
// it sends out response body directly.
|
// it sends out response body directly.
|
||||||
func (output *BeegoOutput) Body(content []byte) {
|
func (output *BeegoOutput) Body(content []byte) error {
|
||||||
var encoding string
|
var encoding string
|
||||||
var buf = &bytes.Buffer{}
|
var buf = &bytes.Buffer{}
|
||||||
if output.EnableGzip {
|
if output.EnableGzip {
|
||||||
@ -75,7 +74,8 @@ func (output *BeegoOutput) Body(content []byte) {
|
|||||||
output.Status = 0
|
output.Status = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
io.Copy(output.Context.ResponseWriter, buf)
|
_, err := output.Context.ResponseWriter.Copy(buf)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cookie sets cookie value via given key.
|
// Cookie sets cookie value via given key.
|
||||||
@ -97,9 +97,10 @@ func (output *BeegoOutput) Cookie(name string, value string, others ...interface
|
|||||||
maxAge = v
|
maxAge = v
|
||||||
}
|
}
|
||||||
|
|
||||||
if maxAge > 0 {
|
switch {
|
||||||
|
case maxAge > 0:
|
||||||
fmt.Fprintf(&b, "; Expires=%s; Max-Age=%d", time.Now().Add(time.Duration(maxAge)*time.Second).UTC().Format(time.RFC1123), maxAge)
|
fmt.Fprintf(&b, "; Expires=%s; Max-Age=%d", time.Now().Add(time.Duration(maxAge)*time.Second).UTC().Format(time.RFC1123), maxAge)
|
||||||
} else {
|
case maxAge < 0:
|
||||||
fmt.Fprintf(&b, "; Max-Age=0")
|
fmt.Fprintf(&b, "; Max-Age=0")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -186,8 +187,7 @@ func (output *BeegoOutput) JSON(data interface{}, hasIndent bool, coding bool) e
|
|||||||
if coding {
|
if coding {
|
||||||
content = []byte(stringsToJSON(string(content)))
|
content = []byte(stringsToJSON(string(content)))
|
||||||
}
|
}
|
||||||
output.Body(content)
|
return output.Body(content)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// JSONP writes jsonp to response body.
|
// JSONP writes jsonp to response body.
|
||||||
@ -212,8 +212,7 @@ func (output *BeegoOutput) JSONP(data interface{}, hasIndent bool) error {
|
|||||||
callbackContent.WriteString("(")
|
callbackContent.WriteString("(")
|
||||||
callbackContent.Write(content)
|
callbackContent.Write(content)
|
||||||
callbackContent.WriteString(");\r\n")
|
callbackContent.WriteString(");\r\n")
|
||||||
output.Body(callbackContent.Bytes())
|
return output.Body(callbackContent.Bytes())
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// XML writes xml string to response body.
|
// XML writes xml string to response body.
|
||||||
@ -230,8 +229,7 @@ func (output *BeegoOutput) XML(data interface{}, hasIndent bool) error {
|
|||||||
http.Error(output.Context.ResponseWriter, err.Error(), http.StatusInternalServerError)
|
http.Error(output.Context.ResponseWriter, err.Error(), http.StatusInternalServerError)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
output.Body(content)
|
return output.Body(content)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Download forces response for download file.
|
// Download forces response for download file.
|
||||||
|
74
vendor/github.com/astaxie/beego/controller.go
generated
vendored
74
vendor/github.com/astaxie/beego/controller.go
generated
vendored
@ -185,8 +185,7 @@ func (c *Controller) Render() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
c.Ctx.Output.Header("Content-Type", "text/html; charset=utf-8")
|
c.Ctx.Output.Header("Content-Type", "text/html; charset=utf-8")
|
||||||
c.Ctx.Output.Body(rb)
|
return c.Ctx.Output.Body(rb)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// RenderString returns the rendered template string. Do not send out response.
|
// RenderString returns the rendered template string. Do not send out response.
|
||||||
@ -197,33 +196,9 @@ func (c *Controller) RenderString() (string, error) {
|
|||||||
|
|
||||||
// RenderBytes returns the bytes of rendered template string. Do not send out response.
|
// RenderBytes returns the bytes of rendered template string. Do not send out response.
|
||||||
func (c *Controller) RenderBytes() ([]byte, error) {
|
func (c *Controller) RenderBytes() ([]byte, error) {
|
||||||
//if the controller has set layout, then first get the tplname's content set the content to the layout
|
buf, err := c.renderTemplate()
|
||||||
var buf bytes.Buffer
|
//if the controller has set layout, then first get the tplName's content set the content to the layout
|
||||||
if c.Layout != "" {
|
if err == nil && c.Layout != "" {
|
||||||
if c.TplName == "" {
|
|
||||||
c.TplName = strings.ToLower(c.controllerName) + "/" + strings.ToLower(c.actionName) + "." + c.TplExt
|
|
||||||
}
|
|
||||||
|
|
||||||
if BConfig.RunMode == DEV {
|
|
||||||
buildFiles := []string{c.TplName}
|
|
||||||
if c.LayoutSections != nil {
|
|
||||||
for _, sectionTpl := range c.LayoutSections {
|
|
||||||
if sectionTpl == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
buildFiles = append(buildFiles, sectionTpl)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BuildTemplate(BConfig.WebConfig.ViewsPath, buildFiles...)
|
|
||||||
}
|
|
||||||
if _, ok := BeeTemplates[c.TplName]; !ok {
|
|
||||||
panic("can't find templatefile in the path:" + c.TplName)
|
|
||||||
}
|
|
||||||
err := BeeTemplates[c.TplName].ExecuteTemplate(&buf, c.TplName, c.Data)
|
|
||||||
if err != nil {
|
|
||||||
Trace("template Execute err:", err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
c.Data["LayoutContent"] = template.HTML(buf.String())
|
c.Data["LayoutContent"] = template.HTML(buf.String())
|
||||||
|
|
||||||
if c.LayoutSections != nil {
|
if c.LayoutSections != nil {
|
||||||
@ -232,11 +207,9 @@ func (c *Controller) RenderBytes() ([]byte, error) {
|
|||||||
c.Data[sectionName] = ""
|
c.Data[sectionName] = ""
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
buf.Reset()
|
buf.Reset()
|
||||||
err = BeeTemplates[sectionTpl].ExecuteTemplate(&buf, sectionTpl, c.Data)
|
err = executeTemplate(&buf, sectionTpl, c.Data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Trace("template Execute err:", err)
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
c.Data[sectionName] = template.HTML(buf.String())
|
c.Data[sectionName] = template.HTML(buf.String())
|
||||||
@ -244,30 +217,32 @@ func (c *Controller) RenderBytes() ([]byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
buf.Reset()
|
buf.Reset()
|
||||||
err = BeeTemplates[c.Layout].ExecuteTemplate(&buf, c.Layout, c.Data)
|
executeTemplate(&buf, c.Layout, c.Data)
|
||||||
if err != nil {
|
|
||||||
Trace("template Execute err:", err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return buf.Bytes(), nil
|
|
||||||
}
|
}
|
||||||
|
return buf.Bytes(), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Controller) renderTemplate() (bytes.Buffer, error) {
|
||||||
|
var buf bytes.Buffer
|
||||||
if c.TplName == "" {
|
if c.TplName == "" {
|
||||||
c.TplName = strings.ToLower(c.controllerName) + "/" + strings.ToLower(c.actionName) + "." + c.TplExt
|
c.TplName = strings.ToLower(c.controllerName) + "/" + strings.ToLower(c.actionName) + "." + c.TplExt
|
||||||
}
|
}
|
||||||
if BConfig.RunMode == DEV {
|
if BConfig.RunMode == DEV {
|
||||||
BuildTemplate(BConfig.WebConfig.ViewsPath, c.TplName)
|
buildFiles := []string{c.TplName}
|
||||||
|
if c.Layout != "" {
|
||||||
|
buildFiles = append(buildFiles, c.Layout)
|
||||||
|
if c.LayoutSections != nil {
|
||||||
|
for _, sectionTpl := range c.LayoutSections {
|
||||||
|
if sectionTpl == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
buildFiles = append(buildFiles, sectionTpl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BuildTemplate(BConfig.WebConfig.ViewsPath, buildFiles...)
|
||||||
}
|
}
|
||||||
if _, ok := BeeTemplates[c.TplName]; !ok {
|
return buf, executeTemplate(&buf, c.TplName, c.Data)
|
||||||
panic("can't find templatefile in the path:" + c.TplName)
|
|
||||||
}
|
|
||||||
buf.Reset()
|
|
||||||
err := BeeTemplates[c.TplName].ExecuteTemplate(&buf, c.TplName, c.Data)
|
|
||||||
if err != nil {
|
|
||||||
Trace("template Execute err:", err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return buf.Bytes(), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Redirect sends the redirection response to url with status code.
|
// Redirect sends the redirection response to url with status code.
|
||||||
@ -287,6 +262,7 @@ func (c *Controller) Abort(code string) {
|
|||||||
// CustomAbort stops controller handler and show the error data, it's similar Aborts, but support status code and body.
|
// CustomAbort stops controller handler and show the error data, it's similar Aborts, but support status code and body.
|
||||||
func (c *Controller) CustomAbort(status int, body string) {
|
func (c *Controller) CustomAbort(status int, body string) {
|
||||||
c.Ctx.ResponseWriter.WriteHeader(status)
|
c.Ctx.ResponseWriter.WriteHeader(status)
|
||||||
|
//c.Ctx.Output.Status = status
|
||||||
// first panic from ErrorMaps, is is user defined error functions.
|
// first panic from ErrorMaps, is is user defined error functions.
|
||||||
if _, ok := ErrorMaps[body]; ok {
|
if _, ok := ErrorMaps[body]; ok {
|
||||||
panic(body)
|
panic(body)
|
||||||
|
1
vendor/github.com/astaxie/beego/error.go
generated
vendored
1
vendor/github.com/astaxie/beego/error.go
generated
vendored
@ -424,6 +424,7 @@ func exception(errCode string, ctx *context.Context) {
|
|||||||
|
|
||||||
func executeError(err *errorInfo, ctx *context.Context, code int) {
|
func executeError(err *errorInfo, ctx *context.Context, code int) {
|
||||||
if err.errorType == errorTypeHandler {
|
if err.errorType == errorTypeHandler {
|
||||||
|
ctx.ResponseWriter.WriteHeader(code)
|
||||||
err.handler(ctx.ResponseWriter, ctx.Request)
|
err.handler(ctx.ResponseWriter, ctx.Request)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
15
vendor/github.com/astaxie/beego/grace/server.go
generated
vendored
15
vendor/github.com/astaxie/beego/grace/server.go
generated
vendored
@ -90,16 +90,15 @@ func (srv *Server) ListenAndServeTLS(certFile, keyFile string) (err error) {
|
|||||||
addr = ":https"
|
addr = ":https"
|
||||||
}
|
}
|
||||||
|
|
||||||
config := &tls.Config{}
|
if srv.TLSConfig == nil {
|
||||||
if srv.TLSConfig != nil {
|
srv.TLSConfig = &tls.Config{}
|
||||||
*config = *srv.TLSConfig
|
|
||||||
}
|
}
|
||||||
if config.NextProtos == nil {
|
if srv.TLSConfig.NextProtos == nil {
|
||||||
config.NextProtos = []string{"http/1.1"}
|
srv.TLSConfig.NextProtos = []string{"http/1.1"}
|
||||||
}
|
}
|
||||||
|
|
||||||
config.Certificates = make([]tls.Certificate, 1)
|
srv.TLSConfig.Certificates = make([]tls.Certificate, 1)
|
||||||
config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
|
srv.TLSConfig.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -113,7 +112,7 @@ func (srv *Server) ListenAndServeTLS(certFile, keyFile string) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
srv.tlsInnerListener = newGraceListener(l, srv)
|
srv.tlsInnerListener = newGraceListener(l, srv)
|
||||||
srv.GraceListener = tls.NewListener(srv.tlsInnerListener, config)
|
srv.GraceListener = tls.NewListener(srv.tlsInnerListener, srv.TLSConfig)
|
||||||
|
|
||||||
if srv.isChild {
|
if srv.isChild {
|
||||||
process, err := os.FindProcess(os.Getppid())
|
process, err := os.FindProcess(os.Getppid())
|
||||||
|
10
vendor/github.com/astaxie/beego/hooks.go
generated
vendored
10
vendor/github.com/astaxie/beego/hooks.go
generated
vendored
@ -68,13 +68,11 @@ func registerSession() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func registerTemplate() error {
|
func registerTemplate() error {
|
||||||
if BConfig.WebConfig.AutoRender {
|
if err := BuildTemplate(BConfig.WebConfig.ViewsPath); err != nil {
|
||||||
if err := BuildTemplate(BConfig.WebConfig.ViewsPath); err != nil {
|
if BConfig.RunMode == DEV {
|
||||||
if BConfig.RunMode == DEV {
|
Warn(err)
|
||||||
Warn(err)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
97
vendor/github.com/astaxie/beego/httplib/README.md
generated
vendored
97
vendor/github.com/astaxie/beego/httplib/README.md
generated
vendored
@ -1,97 +0,0 @@
|
|||||||
# httplib
|
|
||||||
httplib is an libs help you to curl remote url.
|
|
||||||
|
|
||||||
# How to use?
|
|
||||||
|
|
||||||
## GET
|
|
||||||
you can use Get to crawl data.
|
|
||||||
|
|
||||||
import "github.com/astaxie/beego/httplib"
|
|
||||||
|
|
||||||
str, err := httplib.Get("http://beego.me/").String()
|
|
||||||
if err != nil {
|
|
||||||
// error
|
|
||||||
}
|
|
||||||
fmt.Println(str)
|
|
||||||
|
|
||||||
## POST
|
|
||||||
POST data to remote url
|
|
||||||
|
|
||||||
req := httplib.Post("http://beego.me/")
|
|
||||||
req.Param("username","astaxie")
|
|
||||||
req.Param("password","123456")
|
|
||||||
str, err := req.String()
|
|
||||||
if err != nil {
|
|
||||||
// error
|
|
||||||
}
|
|
||||||
fmt.Println(str)
|
|
||||||
|
|
||||||
## Set timeout
|
|
||||||
|
|
||||||
The default timeout is `60` seconds, function prototype:
|
|
||||||
|
|
||||||
SetTimeout(connectTimeout, readWriteTimeout time.Duration)
|
|
||||||
|
|
||||||
Exmaple:
|
|
||||||
|
|
||||||
// GET
|
|
||||||
httplib.Get("http://beego.me/").SetTimeout(100 * time.Second, 30 * time.Second)
|
|
||||||
|
|
||||||
// POST
|
|
||||||
httplib.Post("http://beego.me/").SetTimeout(100 * time.Second, 30 * time.Second)
|
|
||||||
|
|
||||||
|
|
||||||
## Debug
|
|
||||||
|
|
||||||
If you want to debug the request info, set the debug on
|
|
||||||
|
|
||||||
httplib.Get("http://beego.me/").Debug(true)
|
|
||||||
|
|
||||||
## Set HTTP Basic Auth
|
|
||||||
|
|
||||||
str, err := Get("http://beego.me/").SetBasicAuth("user", "passwd").String()
|
|
||||||
if err != nil {
|
|
||||||
// error
|
|
||||||
}
|
|
||||||
fmt.Println(str)
|
|
||||||
|
|
||||||
## Set HTTPS
|
|
||||||
|
|
||||||
If request url is https, You can set the client support TSL:
|
|
||||||
|
|
||||||
httplib.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true})
|
|
||||||
|
|
||||||
More info about the `tls.Config` please visit http://golang.org/pkg/crypto/tls/#Config
|
|
||||||
|
|
||||||
## Set HTTP Version
|
|
||||||
|
|
||||||
some servers need to specify the protocol version of HTTP
|
|
||||||
|
|
||||||
httplib.Get("http://beego.me/").SetProtocolVersion("HTTP/1.1")
|
|
||||||
|
|
||||||
## Set Cookie
|
|
||||||
|
|
||||||
some http request need setcookie. So set it like this:
|
|
||||||
|
|
||||||
cookie := &http.Cookie{}
|
|
||||||
cookie.Name = "username"
|
|
||||||
cookie.Value = "astaxie"
|
|
||||||
httplib.Get("http://beego.me/").SetCookie(cookie)
|
|
||||||
|
|
||||||
## Upload file
|
|
||||||
|
|
||||||
httplib support mutil file upload, use `req.PostFile()`
|
|
||||||
|
|
||||||
req := httplib.Post("http://beego.me/")
|
|
||||||
req.Param("username","astaxie")
|
|
||||||
req.PostFile("uploadfile1", "httplib.pdf")
|
|
||||||
str, err := req.String()
|
|
||||||
if err != nil {
|
|
||||||
// error
|
|
||||||
}
|
|
||||||
fmt.Println(str)
|
|
||||||
|
|
||||||
|
|
||||||
See godoc for further documentation and examples.
|
|
||||||
|
|
||||||
* [godoc.org/github.com/astaxie/beego/httplib](https://godoc.org/github.com/astaxie/beego/httplib)
|
|
552
vendor/github.com/astaxie/beego/httplib/httplib.go
generated
vendored
552
vendor/github.com/astaxie/beego/httplib/httplib.go
generated
vendored
@ -1,552 +0,0 @@
|
|||||||
// Copyright 2014 beego Author. All Rights Reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
// Package httplib is used as http.Client
|
|
||||||
// Usage:
|
|
||||||
//
|
|
||||||
// import "github.com/astaxie/beego/httplib"
|
|
||||||
//
|
|
||||||
// b := httplib.Post("http://beego.me/")
|
|
||||||
// b.Param("username","astaxie")
|
|
||||||
// b.Param("password","123456")
|
|
||||||
// b.PostFile("uploadfile1", "httplib.pdf")
|
|
||||||
// b.PostFile("uploadfile2", "httplib.txt")
|
|
||||||
// str, err := b.String()
|
|
||||||
// if err != nil {
|
|
||||||
// t.Fatal(err)
|
|
||||||
// }
|
|
||||||
// fmt.Println(str)
|
|
||||||
//
|
|
||||||
// more docs http://beego.me/docs/module/httplib.md
|
|
||||||
package httplib
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"compress/gzip"
|
|
||||||
"crypto/tls"
|
|
||||||
"encoding/json"
|
|
||||||
"encoding/xml"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
|
||||||
"mime/multipart"
|
|
||||||
"net"
|
|
||||||
"net/http"
|
|
||||||
"net/http/cookiejar"
|
|
||||||
"net/http/httputil"
|
|
||||||
"net/url"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
var defaultSetting = BeegoHTTPSettings{
|
|
||||||
UserAgent: "beegoServer",
|
|
||||||
ConnectTimeout: 60 * time.Second,
|
|
||||||
ReadWriteTimeout: 60 * time.Second,
|
|
||||||
Gzip: true,
|
|
||||||
DumpBody: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
var defaultCookieJar http.CookieJar
|
|
||||||
var settingMutex sync.Mutex
|
|
||||||
|
|
||||||
// createDefaultCookie creates a global cookiejar to store cookies.
|
|
||||||
func createDefaultCookie() {
|
|
||||||
settingMutex.Lock()
|
|
||||||
defer settingMutex.Unlock()
|
|
||||||
defaultCookieJar, _ = cookiejar.New(nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetDefaultSetting Overwrite default settings
|
|
||||||
func SetDefaultSetting(setting BeegoHTTPSettings) {
|
|
||||||
settingMutex.Lock()
|
|
||||||
defer settingMutex.Unlock()
|
|
||||||
defaultSetting = setting
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewBeegoRequest return *BeegoHttpRequest with specific method
|
|
||||||
func NewBeegoRequest(rawurl, method string) *BeegoHTTPRequest {
|
|
||||||
var resp http.Response
|
|
||||||
u, err := url.Parse(rawurl)
|
|
||||||
if err != nil {
|
|
||||||
log.Println("Httplib:", err)
|
|
||||||
}
|
|
||||||
req := http.Request{
|
|
||||||
URL: u,
|
|
||||||
Method: method,
|
|
||||||
Header: make(http.Header),
|
|
||||||
Proto: "HTTP/1.1",
|
|
||||||
ProtoMajor: 1,
|
|
||||||
ProtoMinor: 1,
|
|
||||||
}
|
|
||||||
return &BeegoHTTPRequest{
|
|
||||||
url: rawurl,
|
|
||||||
req: &req,
|
|
||||||
params: map[string][]string{},
|
|
||||||
files: map[string]string{},
|
|
||||||
setting: defaultSetting,
|
|
||||||
resp: &resp,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get returns *BeegoHttpRequest with GET method.
|
|
||||||
func Get(url string) *BeegoHTTPRequest {
|
|
||||||
return NewBeegoRequest(url, "GET")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Post returns *BeegoHttpRequest with POST method.
|
|
||||||
func Post(url string) *BeegoHTTPRequest {
|
|
||||||
return NewBeegoRequest(url, "POST")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Put returns *BeegoHttpRequest with PUT method.
|
|
||||||
func Put(url string) *BeegoHTTPRequest {
|
|
||||||
return NewBeegoRequest(url, "PUT")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete returns *BeegoHttpRequest DELETE method.
|
|
||||||
func Delete(url string) *BeegoHTTPRequest {
|
|
||||||
return NewBeegoRequest(url, "DELETE")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Head returns *BeegoHttpRequest with HEAD method.
|
|
||||||
func Head(url string) *BeegoHTTPRequest {
|
|
||||||
return NewBeegoRequest(url, "HEAD")
|
|
||||||
}
|
|
||||||
|
|
||||||
// BeegoHTTPSettings is the http.Client setting
|
|
||||||
type BeegoHTTPSettings struct {
|
|
||||||
ShowDebug bool
|
|
||||||
UserAgent string
|
|
||||||
ConnectTimeout time.Duration
|
|
||||||
ReadWriteTimeout time.Duration
|
|
||||||
TLSClientConfig *tls.Config
|
|
||||||
Proxy func(*http.Request) (*url.URL, error)
|
|
||||||
Transport http.RoundTripper
|
|
||||||
EnableCookie bool
|
|
||||||
Gzip bool
|
|
||||||
DumpBody bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// BeegoHTTPRequest provides more useful methods for requesting one url than http.Request.
|
|
||||||
type BeegoHTTPRequest struct {
|
|
||||||
url string
|
|
||||||
req *http.Request
|
|
||||||
params map[string][]string
|
|
||||||
files map[string]string
|
|
||||||
setting BeegoHTTPSettings
|
|
||||||
resp *http.Response
|
|
||||||
body []byte
|
|
||||||
dump []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetRequest return the request object
|
|
||||||
func (b *BeegoHTTPRequest) GetRequest() *http.Request {
|
|
||||||
return b.req
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setting Change request settings
|
|
||||||
func (b *BeegoHTTPRequest) Setting(setting BeegoHTTPSettings) *BeegoHTTPRequest {
|
|
||||||
b.setting = setting
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetBasicAuth sets the request's Authorization header to use HTTP Basic Authentication with the provided username and password.
|
|
||||||
func (b *BeegoHTTPRequest) SetBasicAuth(username, password string) *BeegoHTTPRequest {
|
|
||||||
b.req.SetBasicAuth(username, password)
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetEnableCookie sets enable/disable cookiejar
|
|
||||||
func (b *BeegoHTTPRequest) SetEnableCookie(enable bool) *BeegoHTTPRequest {
|
|
||||||
b.setting.EnableCookie = enable
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetUserAgent sets User-Agent header field
|
|
||||||
func (b *BeegoHTTPRequest) SetUserAgent(useragent string) *BeegoHTTPRequest {
|
|
||||||
b.setting.UserAgent = useragent
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
// Debug sets show debug or not when executing request.
|
|
||||||
func (b *BeegoHTTPRequest) Debug(isdebug bool) *BeegoHTTPRequest {
|
|
||||||
b.setting.ShowDebug = isdebug
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
// DumpBody setting whether need to Dump the Body.
|
|
||||||
func (b *BeegoHTTPRequest) DumpBody(isdump bool) *BeegoHTTPRequest {
|
|
||||||
b.setting.DumpBody = isdump
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
// DumpRequest return the DumpRequest
|
|
||||||
func (b *BeegoHTTPRequest) DumpRequest() []byte {
|
|
||||||
return b.dump
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetTimeout sets connect time out and read-write time out for BeegoRequest.
|
|
||||||
func (b *BeegoHTTPRequest) SetTimeout(connectTimeout, readWriteTimeout time.Duration) *BeegoHTTPRequest {
|
|
||||||
b.setting.ConnectTimeout = connectTimeout
|
|
||||||
b.setting.ReadWriteTimeout = readWriteTimeout
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetTLSClientConfig sets tls connection configurations if visiting https url.
|
|
||||||
func (b *BeegoHTTPRequest) SetTLSClientConfig(config *tls.Config) *BeegoHTTPRequest {
|
|
||||||
b.setting.TLSClientConfig = config
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
// Header add header item string in request.
|
|
||||||
func (b *BeegoHTTPRequest) Header(key, value string) *BeegoHTTPRequest {
|
|
||||||
b.req.Header.Set(key, value)
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetHost set the request host
|
|
||||||
func (b *BeegoHTTPRequest) SetHost(host string) *BeegoHTTPRequest {
|
|
||||||
b.req.Host = host
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetProtocolVersion Set the protocol version for incoming requests.
|
|
||||||
// Client requests always use HTTP/1.1.
|
|
||||||
func (b *BeegoHTTPRequest) SetProtocolVersion(vers string) *BeegoHTTPRequest {
|
|
||||||
if len(vers) == 0 {
|
|
||||||
vers = "HTTP/1.1"
|
|
||||||
}
|
|
||||||
|
|
||||||
major, minor, ok := http.ParseHTTPVersion(vers)
|
|
||||||
if ok {
|
|
||||||
b.req.Proto = vers
|
|
||||||
b.req.ProtoMajor = major
|
|
||||||
b.req.ProtoMinor = minor
|
|
||||||
}
|
|
||||||
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetCookie add cookie into request.
|
|
||||||
func (b *BeegoHTTPRequest) SetCookie(cookie *http.Cookie) *BeegoHTTPRequest {
|
|
||||||
b.req.Header.Add("Cookie", cookie.String())
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetTransport set the setting transport
|
|
||||||
func (b *BeegoHTTPRequest) SetTransport(transport http.RoundTripper) *BeegoHTTPRequest {
|
|
||||||
b.setting.Transport = transport
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetProxy set the http proxy
|
|
||||||
// example:
|
|
||||||
//
|
|
||||||
// func(req *http.Request) (*url.URL, error) {
|
|
||||||
// u, _ := url.ParseRequestURI("http://127.0.0.1:8118")
|
|
||||||
// return u, nil
|
|
||||||
// }
|
|
||||||
func (b *BeegoHTTPRequest) SetProxy(proxy func(*http.Request) (*url.URL, error)) *BeegoHTTPRequest {
|
|
||||||
b.setting.Proxy = proxy
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
// Param adds query param in to request.
|
|
||||||
// params build query string as ?key1=value1&key2=value2...
|
|
||||||
func (b *BeegoHTTPRequest) Param(key, value string) *BeegoHTTPRequest {
|
|
||||||
if param, ok := b.params[key]; ok {
|
|
||||||
b.params[key] = append(param, value)
|
|
||||||
} else {
|
|
||||||
b.params[key] = []string{value}
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
// PostFile add a post file to the request
|
|
||||||
func (b *BeegoHTTPRequest) PostFile(formname, filename string) *BeegoHTTPRequest {
|
|
||||||
b.files[formname] = filename
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
// Body adds request raw body.
|
|
||||||
// it supports string and []byte.
|
|
||||||
func (b *BeegoHTTPRequest) Body(data interface{}) *BeegoHTTPRequest {
|
|
||||||
switch t := data.(type) {
|
|
||||||
case string:
|
|
||||||
bf := bytes.NewBufferString(t)
|
|
||||||
b.req.Body = ioutil.NopCloser(bf)
|
|
||||||
b.req.ContentLength = int64(len(t))
|
|
||||||
case []byte:
|
|
||||||
bf := bytes.NewBuffer(t)
|
|
||||||
b.req.Body = ioutil.NopCloser(bf)
|
|
||||||
b.req.ContentLength = int64(len(t))
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
// JSONBody adds request raw body encoding by JSON.
|
|
||||||
func (b *BeegoHTTPRequest) JSONBody(obj interface{}) (*BeegoHTTPRequest, error) {
|
|
||||||
if b.req.Body == nil && obj != nil {
|
|
||||||
buf := bytes.NewBuffer(nil)
|
|
||||||
enc := json.NewEncoder(buf)
|
|
||||||
if err := enc.Encode(obj); err != nil {
|
|
||||||
return b, err
|
|
||||||
}
|
|
||||||
b.req.Body = ioutil.NopCloser(buf)
|
|
||||||
b.req.ContentLength = int64(buf.Len())
|
|
||||||
b.req.Header.Set("Content-Type", "application/json")
|
|
||||||
}
|
|
||||||
return b, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *BeegoHTTPRequest) buildURL(paramBody string) {
|
|
||||||
// build GET url with query string
|
|
||||||
if b.req.Method == "GET" && len(paramBody) > 0 {
|
|
||||||
if strings.Index(b.url, "?") != -1 {
|
|
||||||
b.url += "&" + paramBody
|
|
||||||
} else {
|
|
||||||
b.url = b.url + "?" + paramBody
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// build POST/PUT/PATCH url and body
|
|
||||||
if (b.req.Method == "POST" || b.req.Method == "PUT" || b.req.Method == "PATCH") && b.req.Body == nil {
|
|
||||||
// with files
|
|
||||||
if len(b.files) > 0 {
|
|
||||||
pr, pw := io.Pipe()
|
|
||||||
bodyWriter := multipart.NewWriter(pw)
|
|
||||||
go func() {
|
|
||||||
for formname, filename := range b.files {
|
|
||||||
fileWriter, err := bodyWriter.CreateFormFile(formname, filename)
|
|
||||||
if err != nil {
|
|
||||||
log.Println("Httplib:", err)
|
|
||||||
}
|
|
||||||
fh, err := os.Open(filename)
|
|
||||||
if err != nil {
|
|
||||||
log.Println("Httplib:", err)
|
|
||||||
}
|
|
||||||
//iocopy
|
|
||||||
_, err = io.Copy(fileWriter, fh)
|
|
||||||
fh.Close()
|
|
||||||
if err != nil {
|
|
||||||
log.Println("Httplib:", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for k, v := range b.params {
|
|
||||||
for _, vv := range v {
|
|
||||||
bodyWriter.WriteField(k, vv)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bodyWriter.Close()
|
|
||||||
pw.Close()
|
|
||||||
}()
|
|
||||||
b.Header("Content-Type", bodyWriter.FormDataContentType())
|
|
||||||
b.req.Body = ioutil.NopCloser(pr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// with params
|
|
||||||
if len(paramBody) > 0 {
|
|
||||||
b.Header("Content-Type", "application/x-www-form-urlencoded")
|
|
||||||
b.Body(paramBody)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *BeegoHTTPRequest) getResponse() (*http.Response, error) {
|
|
||||||
if b.resp.StatusCode != 0 {
|
|
||||||
return b.resp, nil
|
|
||||||
}
|
|
||||||
resp, err := b.DoRequest()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
b.resp = resp
|
|
||||||
return resp, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DoRequest will do the client.Do
|
|
||||||
func (b *BeegoHTTPRequest) DoRequest() (*http.Response, error) {
|
|
||||||
var paramBody string
|
|
||||||
if len(b.params) > 0 {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
for k, v := range b.params {
|
|
||||||
for _, vv := range v {
|
|
||||||
buf.WriteString(url.QueryEscape(k))
|
|
||||||
buf.WriteByte('=')
|
|
||||||
buf.WriteString(url.QueryEscape(vv))
|
|
||||||
buf.WriteByte('&')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
paramBody = buf.String()
|
|
||||||
paramBody = paramBody[0 : len(paramBody)-1]
|
|
||||||
}
|
|
||||||
|
|
||||||
b.buildURL(paramBody)
|
|
||||||
url, err := url.Parse(b.url)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
b.req.URL = url
|
|
||||||
|
|
||||||
trans := b.setting.Transport
|
|
||||||
|
|
||||||
if trans == nil {
|
|
||||||
// create default transport
|
|
||||||
trans = &http.Transport{
|
|
||||||
TLSClientConfig: b.setting.TLSClientConfig,
|
|
||||||
Proxy: b.setting.Proxy,
|
|
||||||
Dial: TimeoutDialer(b.setting.ConnectTimeout, b.setting.ReadWriteTimeout),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// if b.transport is *http.Transport then set the settings.
|
|
||||||
if t, ok := trans.(*http.Transport); ok {
|
|
||||||
if t.TLSClientConfig == nil {
|
|
||||||
t.TLSClientConfig = b.setting.TLSClientConfig
|
|
||||||
}
|
|
||||||
if t.Proxy == nil {
|
|
||||||
t.Proxy = b.setting.Proxy
|
|
||||||
}
|
|
||||||
if t.Dial == nil {
|
|
||||||
t.Dial = TimeoutDialer(b.setting.ConnectTimeout, b.setting.ReadWriteTimeout)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var jar http.CookieJar
|
|
||||||
if b.setting.EnableCookie {
|
|
||||||
if defaultCookieJar == nil {
|
|
||||||
createDefaultCookie()
|
|
||||||
}
|
|
||||||
jar = defaultCookieJar
|
|
||||||
}
|
|
||||||
|
|
||||||
client := &http.Client{
|
|
||||||
Transport: trans,
|
|
||||||
Jar: jar,
|
|
||||||
}
|
|
||||||
|
|
||||||
if b.setting.UserAgent != "" && b.req.Header.Get("User-Agent") == "" {
|
|
||||||
b.req.Header.Set("User-Agent", b.setting.UserAgent)
|
|
||||||
}
|
|
||||||
|
|
||||||
if b.setting.ShowDebug {
|
|
||||||
dump, err := httputil.DumpRequest(b.req, b.setting.DumpBody)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err.Error())
|
|
||||||
}
|
|
||||||
b.dump = dump
|
|
||||||
}
|
|
||||||
return client.Do(b.req)
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the body string in response.
|
|
||||||
// it calls Response inner.
|
|
||||||
func (b *BeegoHTTPRequest) String() (string, error) {
|
|
||||||
data, err := b.Bytes()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
return string(data), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bytes returns the body []byte in response.
|
|
||||||
// it calls Response inner.
|
|
||||||
func (b *BeegoHTTPRequest) Bytes() ([]byte, error) {
|
|
||||||
if b.body != nil {
|
|
||||||
return b.body, nil
|
|
||||||
}
|
|
||||||
resp, err := b.getResponse()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if resp.Body == nil {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
if b.setting.Gzip && resp.Header.Get("Content-Encoding") == "gzip" {
|
|
||||||
reader, err := gzip.NewReader(resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
b.body, err = ioutil.ReadAll(reader)
|
|
||||||
} else {
|
|
||||||
b.body, err = ioutil.ReadAll(resp.Body)
|
|
||||||
}
|
|
||||||
return b.body, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToFile saves the body data in response to one file.
|
|
||||||
// it calls Response inner.
|
|
||||||
func (b *BeegoHTTPRequest) ToFile(filename string) error {
|
|
||||||
f, err := os.Create(filename)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
|
|
||||||
resp, err := b.getResponse()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if resp.Body == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
_, err = io.Copy(f, resp.Body)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToJSON returns the map that marshals from the body bytes as json in response .
|
|
||||||
// it calls Response inner.
|
|
||||||
func (b *BeegoHTTPRequest) ToJSON(v interface{}) error {
|
|
||||||
data, err := b.Bytes()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return json.Unmarshal(data, v)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToXML returns the map that marshals from the body bytes as xml in response .
|
|
||||||
// it calls Response inner.
|
|
||||||
func (b *BeegoHTTPRequest) ToXML(v interface{}) error {
|
|
||||||
data, err := b.Bytes()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return xml.Unmarshal(data, v)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Response executes request client gets response mannually.
|
|
||||||
func (b *BeegoHTTPRequest) Response() (*http.Response, error) {
|
|
||||||
return b.getResponse()
|
|
||||||
}
|
|
||||||
|
|
||||||
// TimeoutDialer returns functions of connection dialer with timeout settings for http.Transport Dial field.
|
|
||||||
func TimeoutDialer(cTimeout time.Duration, rwTimeout time.Duration) func(net, addr string) (c net.Conn, err error) {
|
|
||||||
return func(netw, addr string) (net.Conn, error) {
|
|
||||||
conn, err := net.DialTimeout(netw, addr, cTimeout)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
err = conn.SetDeadline(time.Now().Add(rwTimeout))
|
|
||||||
return conn, err
|
|
||||||
}
|
|
||||||
}
|
|
19
vendor/github.com/astaxie/beego/logs/conn.go
generated
vendored
19
vendor/github.com/astaxie/beego/logs/conn.go
generated
vendored
@ -17,14 +17,14 @@ package logs
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
|
||||||
"net"
|
"net"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// connWriter implements LoggerInterface.
|
// connWriter implements LoggerInterface.
|
||||||
// it writes messages in keep-live tcp connection.
|
// it writes messages in keep-live tcp connection.
|
||||||
type connWriter struct {
|
type connWriter struct {
|
||||||
lg *log.Logger
|
lg *logWriter
|
||||||
innerWriter io.WriteCloser
|
innerWriter io.WriteCloser
|
||||||
ReconnectOnMsg bool `json:"reconnectOnMsg"`
|
ReconnectOnMsg bool `json:"reconnectOnMsg"`
|
||||||
Reconnect bool `json:"reconnect"`
|
Reconnect bool `json:"reconnect"`
|
||||||
@ -42,17 +42,17 @@ func NewConn() Logger {
|
|||||||
|
|
||||||
// Init init connection writer with json config.
|
// Init init connection writer with json config.
|
||||||
// json config only need key "level".
|
// json config only need key "level".
|
||||||
func (c *connWriter) Init(jsonconfig string) error {
|
func (c *connWriter) Init(jsonConfig string) error {
|
||||||
return json.Unmarshal([]byte(jsonconfig), c)
|
return json.Unmarshal([]byte(jsonConfig), c)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteMsg write message in connection.
|
// WriteMsg write message in connection.
|
||||||
// if connection is down, try to re-connect.
|
// if connection is down, try to re-connect.
|
||||||
func (c *connWriter) WriteMsg(msg string, level int) error {
|
func (c *connWriter) WriteMsg(when time.Time, msg string, level int) error {
|
||||||
if level > c.Level {
|
if level > c.Level {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if c.neddedConnectOnMsg() {
|
if c.needToConnectOnMsg() {
|
||||||
err := c.connect()
|
err := c.connect()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -62,7 +62,8 @@ func (c *connWriter) WriteMsg(msg string, level int) error {
|
|||||||
if c.ReconnectOnMsg {
|
if c.ReconnectOnMsg {
|
||||||
defer c.innerWriter.Close()
|
defer c.innerWriter.Close()
|
||||||
}
|
}
|
||||||
c.lg.Println(msg)
|
|
||||||
|
c.lg.println(when, msg)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,11 +95,11 @@ func (c *connWriter) connect() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
c.innerWriter = conn
|
c.innerWriter = conn
|
||||||
c.lg = log.New(conn, "", log.Ldate|log.Ltime)
|
c.lg = newLogWriter(conn)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *connWriter) neddedConnectOnMsg() bool {
|
func (c *connWriter) needToConnectOnMsg() bool {
|
||||||
if c.Reconnect {
|
if c.Reconnect {
|
||||||
c.Reconnect = false
|
c.Reconnect = false
|
||||||
return true
|
return true
|
||||||
|
50
vendor/github.com/astaxie/beego/logs/console.go
generated
vendored
50
vendor/github.com/astaxie/beego/logs/console.go
generated
vendored
@ -16,9 +16,9 @@ package logs
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"log"
|
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// brush is a color join function
|
// brush is a color join function
|
||||||
@ -34,51 +34,55 @@ func newBrush(color string) brush {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var colors = []brush{
|
var colors = []brush{
|
||||||
newBrush("1;37"), // Emergency white
|
newBrush("1;37"), // Emergency white
|
||||||
newBrush("1;36"), // Alert cyan
|
newBrush("1;36"), // Alert cyan
|
||||||
newBrush("1;35"), // Critical magenta
|
newBrush("1;35"), // Critical magenta
|
||||||
newBrush("1;31"), // Error red
|
newBrush("1;31"), // Error red
|
||||||
newBrush("1;33"), // Warning yellow
|
newBrush("1;33"), // Warning yellow
|
||||||
newBrush("1;32"), // Notice green
|
newBrush("1;32"), // Notice green
|
||||||
newBrush("1;34"), // Informational blue
|
newBrush("1;34"), // Informational blue
|
||||||
newBrush("1;34"), // Debug blue
|
newBrush("1;34"), // Debug blue
|
||||||
}
|
}
|
||||||
|
|
||||||
// consoleWriter implements LoggerInterface and writes messages to terminal.
|
// consoleWriter implements LoggerInterface and writes messages to terminal.
|
||||||
type consoleWriter struct {
|
type consoleWriter struct {
|
||||||
lg *log.Logger
|
lg *logWriter
|
||||||
Level int `json:"level"`
|
Level int `json:"level"`
|
||||||
|
Colorful bool `json:"color"` //this filed is useful only when system's terminal supports color
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewConsole create ConsoleWriter returning as LoggerInterface.
|
// NewConsole create ConsoleWriter returning as LoggerInterface.
|
||||||
func NewConsole() Logger {
|
func NewConsole() Logger {
|
||||||
cw := &consoleWriter{
|
cw := &consoleWriter{
|
||||||
lg: log.New(os.Stdout, "", log.Ldate|log.Ltime),
|
lg: newLogWriter(os.Stdout),
|
||||||
Level: LevelDebug,
|
Level: LevelDebug,
|
||||||
|
Colorful: true,
|
||||||
}
|
}
|
||||||
return cw
|
return cw
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init init console logger.
|
// Init init console logger.
|
||||||
// jsonconfig like '{"level":LevelTrace}'.
|
// jsonConfig like '{"level":LevelTrace}'.
|
||||||
func (c *consoleWriter) Init(jsonconfig string) error {
|
func (c *consoleWriter) Init(jsonConfig string) error {
|
||||||
if len(jsonconfig) == 0 {
|
if len(jsonConfig) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return json.Unmarshal([]byte(jsonconfig), c)
|
err := json.Unmarshal([]byte(jsonConfig), c)
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
c.Colorful = false
|
||||||
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteMsg write message in console.
|
// WriteMsg write message in console.
|
||||||
func (c *consoleWriter) WriteMsg(msg string, level int) error {
|
func (c *consoleWriter) WriteMsg(when time.Time, msg string, level int) error {
|
||||||
if level > c.Level {
|
if level > c.Level {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if goos := runtime.GOOS; goos == "windows" {
|
if c.Colorful {
|
||||||
c.lg.Println(msg)
|
msg = colors[level](msg)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
c.lg.Println(colors[level](msg))
|
c.lg.println(when, msg)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
80
vendor/github.com/astaxie/beego/logs/es/es.go
generated
vendored
80
vendor/github.com/astaxie/beego/logs/es/es.go
generated
vendored
@ -1,80 +0,0 @@
|
|||||||
package es
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"net/url"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/astaxie/beego/logs"
|
|
||||||
"github.com/belogik/goes"
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewES return a LoggerInterface
|
|
||||||
func NewES() logs.Logger {
|
|
||||||
cw := &esLogger{
|
|
||||||
Level: logs.LevelDebug,
|
|
||||||
}
|
|
||||||
return cw
|
|
||||||
}
|
|
||||||
|
|
||||||
type esLogger struct {
|
|
||||||
*goes.Connection
|
|
||||||
DSN string `json:"dsn"`
|
|
||||||
Level int `json:"level"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// {"dsn":"http://localhost:9200/","level":1}
|
|
||||||
func (el *esLogger) Init(jsonconfig string) error {
|
|
||||||
err := json.Unmarshal([]byte(jsonconfig), el)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if el.DSN == "" {
|
|
||||||
return errors.New("empty dsn")
|
|
||||||
} else if u, err := url.Parse(el.DSN); err != nil {
|
|
||||||
return err
|
|
||||||
} else if u.Path == "" {
|
|
||||||
return errors.New("missing prefix")
|
|
||||||
} else if host, port, err := net.SplitHostPort(u.Host); err != nil {
|
|
||||||
return err
|
|
||||||
} else {
|
|
||||||
conn := goes.NewConnection(host, port)
|
|
||||||
el.Connection = conn
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteMsg will write the msg and level into es
|
|
||||||
func (el *esLogger) WriteMsg(msg string, level int) error {
|
|
||||||
if level > el.Level {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
t := time.Now()
|
|
||||||
vals := make(map[string]interface{})
|
|
||||||
vals["@timestamp"] = t.Format(time.RFC3339)
|
|
||||||
vals["@msg"] = msg
|
|
||||||
d := goes.Document{
|
|
||||||
Index: fmt.Sprintf("%04d.%02d.%02d", t.Year(), t.Month(), t.Day()),
|
|
||||||
Type: "logs",
|
|
||||||
Fields: vals,
|
|
||||||
}
|
|
||||||
_, err := el.Index(d, nil)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Destroy is a empty method
|
|
||||||
func (el *esLogger) Destroy() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flush is a empty method
|
|
||||||
func (el *esLogger) Flush() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
logs.Register("es", NewES)
|
|
||||||
}
|
|
78
vendor/github.com/astaxie/beego/logs/file.go
generated
vendored
78
vendor/github.com/astaxie/beego/logs/file.go
generated
vendored
@ -53,9 +53,11 @@ type fileLogWriter struct {
|
|||||||
Level int `json:"level"`
|
Level int `json:"level"`
|
||||||
|
|
||||||
Perm os.FileMode `json:"perm"`
|
Perm os.FileMode `json:"perm"`
|
||||||
|
|
||||||
|
fileNameOnly, suffix string // like "project.log", project is fileNameOnly and .log is suffix
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFileWriter create a FileLogWriter returning as LoggerInterface.
|
// newFileWriter create a FileLogWriter returning as LoggerInterface.
|
||||||
func newFileWriter() Logger {
|
func newFileWriter() Logger {
|
||||||
w := &fileLogWriter{
|
w := &fileLogWriter{
|
||||||
Filename: "",
|
Filename: "",
|
||||||
@ -89,6 +91,11 @@ func (w *fileLogWriter) Init(jsonConfig string) error {
|
|||||||
if len(w.Filename) == 0 {
|
if len(w.Filename) == 0 {
|
||||||
return errors.New("jsonconfig must have filename")
|
return errors.New("jsonconfig must have filename")
|
||||||
}
|
}
|
||||||
|
w.suffix = filepath.Ext(w.Filename)
|
||||||
|
w.fileNameOnly = strings.TrimSuffix(w.Filename, w.suffix)
|
||||||
|
if w.suffix == "" {
|
||||||
|
w.suffix = ".log"
|
||||||
|
}
|
||||||
err = w.startLogger()
|
err = w.startLogger()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -114,59 +121,19 @@ func (w *fileLogWriter) needRotate(size int, day int) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// WriteMsg write logger message into file.
|
// WriteMsg write logger message into file.
|
||||||
func (w *fileLogWriter) WriteMsg(msg string, level int) error {
|
func (w *fileLogWriter) WriteMsg(when time.Time, msg string, level int) error {
|
||||||
if level > w.Level {
|
if level > w.Level {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
//2016/01/12 21:34:33
|
h, d := formatTimeHeader(when)
|
||||||
now := time.Now()
|
msg = string(h) + msg + "\n"
|
||||||
y, mo, d := now.Date()
|
|
||||||
h, mi, s := now.Clock()
|
|
||||||
//len(2006/01/02 15:03:04)==19
|
|
||||||
var buf [20]byte
|
|
||||||
t := 3
|
|
||||||
for y >= 10 {
|
|
||||||
p := y / 10
|
|
||||||
buf[t] = byte('0' + y - p*10)
|
|
||||||
y = p
|
|
||||||
t--
|
|
||||||
}
|
|
||||||
buf[0] = byte('0' + y)
|
|
||||||
buf[4] = '/'
|
|
||||||
if mo > 9 {
|
|
||||||
buf[5] = '1'
|
|
||||||
buf[6] = byte('0' + mo - 9)
|
|
||||||
} else {
|
|
||||||
buf[5] = '0'
|
|
||||||
buf[6] = byte('0' + mo)
|
|
||||||
}
|
|
||||||
buf[7] = '/'
|
|
||||||
t = d / 10
|
|
||||||
buf[8] = byte('0' + t)
|
|
||||||
buf[9] = byte('0' + d - t*10)
|
|
||||||
buf[10] = ' '
|
|
||||||
t = h / 10
|
|
||||||
buf[11] = byte('0' + t)
|
|
||||||
buf[12] = byte('0' + h - t*10)
|
|
||||||
buf[13] = ':'
|
|
||||||
t = mi / 10
|
|
||||||
buf[14] = byte('0' + t)
|
|
||||||
buf[15] = byte('0' + mi - t*10)
|
|
||||||
buf[16] = ':'
|
|
||||||
t = s / 10
|
|
||||||
buf[17] = byte('0' + t)
|
|
||||||
buf[18] = byte('0' + s - t*10)
|
|
||||||
buf[19] = ' '
|
|
||||||
msg = string(buf[0:]) + msg + "\n"
|
|
||||||
|
|
||||||
if w.Rotate {
|
if w.Rotate {
|
||||||
if w.needRotate(len(msg), d) {
|
if w.needRotate(len(msg), d) {
|
||||||
w.Lock()
|
w.Lock()
|
||||||
if w.needRotate(len(msg), d) {
|
if w.needRotate(len(msg), d) {
|
||||||
if err := w.doRotate(); err != nil {
|
if err := w.doRotate(when); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.Filename, err)
|
fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.Filename, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
w.Unlock()
|
w.Unlock()
|
||||||
}
|
}
|
||||||
@ -235,8 +202,8 @@ func (w *fileLogWriter) lines() (int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DoRotate means it need to write file in new file.
|
// DoRotate means it need to write file in new file.
|
||||||
// new file name like xx.2013-01-01.2.log
|
// new file name like xx.2013-01-01.log (daily) or xx.001.log (by line or size)
|
||||||
func (w *fileLogWriter) doRotate() error {
|
func (w *fileLogWriter) doRotate(logTime time.Time) error {
|
||||||
_, err := os.Lstat(w.Filename)
|
_, err := os.Lstat(w.Filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -245,13 +212,13 @@ func (w *fileLogWriter) doRotate() error {
|
|||||||
// Find the next available number
|
// Find the next available number
|
||||||
num := 1
|
num := 1
|
||||||
fName := ""
|
fName := ""
|
||||||
suffix := filepath.Ext(w.Filename)
|
if w.MaxLines > 0 || w.MaxSize > 0 {
|
||||||
filenameOnly := strings.TrimSuffix(w.Filename, suffix)
|
for ; err == nil && num <= 999; num++ {
|
||||||
if suffix == "" {
|
fName = w.fileNameOnly + fmt.Sprintf(".%s.%03d%s", logTime.Format("2006-01-02"), num, w.suffix)
|
||||||
suffix = ".log"
|
_, err = os.Lstat(fName)
|
||||||
}
|
}
|
||||||
for ; err == nil && num <= 999; num++ {
|
} else {
|
||||||
fName = filenameOnly + fmt.Sprintf(".%s.%03d%s", time.Now().Format("2006-01-02"), num, suffix)
|
fName = fmt.Sprintf("%s.%s%s", w.fileNameOnly, logTime.Format("2006-01-02"), w.suffix)
|
||||||
_, err = os.Lstat(fName)
|
_, err = os.Lstat(fName)
|
||||||
}
|
}
|
||||||
// return error if the last file checked still existed
|
// return error if the last file checked still existed
|
||||||
@ -289,7 +256,8 @@ func (w *fileLogWriter) deleteOldLog() {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
if !info.IsDir() && info.ModTime().Unix() < (time.Now().Unix()-60*60*24*w.MaxDays) {
|
if !info.IsDir() && info.ModTime().Unix() < (time.Now().Unix()-60*60*24*w.MaxDays) {
|
||||||
if strings.HasPrefix(filepath.Base(path), filepath.Base(w.Filename)) {
|
if strings.HasPrefix(filepath.Base(path), w.fileNameOnly) &&
|
||||||
|
strings.HasSuffix(filepath.Base(path), w.suffix) {
|
||||||
os.Remove(path)
|
os.Remove(path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
92
vendor/github.com/astaxie/beego/logs/log.go
generated
vendored
92
vendor/github.com/astaxie/beego/logs/log.go
generated
vendored
@ -40,6 +40,7 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RFC5424 log message levels.
|
// RFC5424 log message levels.
|
||||||
@ -68,7 +69,7 @@ type loggerType func() Logger
|
|||||||
// Logger defines the behavior of a log provider.
|
// Logger defines the behavior of a log provider.
|
||||||
type Logger interface {
|
type Logger interface {
|
||||||
Init(config string) error
|
Init(config string) error
|
||||||
WriteMsg(msg string, level int) error
|
WriteMsg(when time.Time, msg string, level int) error
|
||||||
Destroy()
|
Destroy()
|
||||||
Flush()
|
Flush()
|
||||||
}
|
}
|
||||||
@ -97,6 +98,8 @@ type BeeLogger struct {
|
|||||||
loggerFuncCallDepth int
|
loggerFuncCallDepth int
|
||||||
asynchronous bool
|
asynchronous bool
|
||||||
msgChan chan *logMsg
|
msgChan chan *logMsg
|
||||||
|
signalChan chan string
|
||||||
|
wg sync.WaitGroup
|
||||||
outputs []*nameLogger
|
outputs []*nameLogger
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,6 +111,7 @@ type nameLogger struct {
|
|||||||
type logMsg struct {
|
type logMsg struct {
|
||||||
level int
|
level int
|
||||||
msg string
|
msg string
|
||||||
|
when time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
var logMsgPool *sync.Pool
|
var logMsgPool *sync.Pool
|
||||||
@ -120,6 +124,7 @@ func NewLogger(channelLen int64) *BeeLogger {
|
|||||||
bl.level = LevelDebug
|
bl.level = LevelDebug
|
||||||
bl.loggerFuncCallDepth = 2
|
bl.loggerFuncCallDepth = 2
|
||||||
bl.msgChan = make(chan *logMsg, channelLen)
|
bl.msgChan = make(chan *logMsg, channelLen)
|
||||||
|
bl.signalChan = make(chan string, 1)
|
||||||
return bl
|
return bl
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,6 +136,7 @@ func (bl *BeeLogger) Async() *BeeLogger {
|
|||||||
return &logMsg{}
|
return &logMsg{}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
bl.wg.Add(1)
|
||||||
go bl.startLogger()
|
go bl.startLogger()
|
||||||
return bl
|
return bl
|
||||||
}
|
}
|
||||||
@ -140,17 +146,25 @@ func (bl *BeeLogger) Async() *BeeLogger {
|
|||||||
func (bl *BeeLogger) SetLogger(adapterName string, config string) error {
|
func (bl *BeeLogger) SetLogger(adapterName string, config string) error {
|
||||||
bl.lock.Lock()
|
bl.lock.Lock()
|
||||||
defer bl.lock.Unlock()
|
defer bl.lock.Unlock()
|
||||||
if log, ok := adapters[adapterName]; ok {
|
|
||||||
lg := log()
|
for _, l := range bl.outputs {
|
||||||
err := lg.Init(config)
|
if l.name == adapterName {
|
||||||
if err != nil {
|
return fmt.Errorf("logs: duplicate adaptername %q (you have set this logger before)", adapterName)
|
||||||
fmt.Fprintln(os.Stderr, "logs.BeeLogger.SetLogger: "+err.Error())
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
bl.outputs = append(bl.outputs, &nameLogger{name: adapterName, Logger: lg})
|
}
|
||||||
} else {
|
|
||||||
|
log, ok := adapters[adapterName]
|
||||||
|
if !ok {
|
||||||
return fmt.Errorf("logs: unknown adaptername %q (forgotten Register?)", adapterName)
|
return fmt.Errorf("logs: unknown adaptername %q (forgotten Register?)", adapterName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lg := log()
|
||||||
|
err := lg.Init(config)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintln(os.Stderr, "logs.BeeLogger.SetLogger: "+err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
bl.outputs = append(bl.outputs, &nameLogger{name: adapterName, Logger: lg})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,9 +187,9 @@ func (bl *BeeLogger) DelLogger(adapterName string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bl *BeeLogger) writeToLoggers(msg string, level int) {
|
func (bl *BeeLogger) writeToLoggers(when time.Time, msg string, level int) {
|
||||||
for _, l := range bl.outputs {
|
for _, l := range bl.outputs {
|
||||||
err := l.WriteMsg(msg, level)
|
err := l.WriteMsg(when, msg, level)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "unable to WriteMsg to adapter:%v,error:%v\n", l.name, err)
|
fmt.Fprintf(os.Stderr, "unable to WriteMsg to adapter:%v,error:%v\n", l.name, err)
|
||||||
}
|
}
|
||||||
@ -183,6 +197,7 @@ func (bl *BeeLogger) writeToLoggers(msg string, level int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (bl *BeeLogger) writeMsg(logLevel int, msg string) error {
|
func (bl *BeeLogger) writeMsg(logLevel int, msg string) error {
|
||||||
|
when := time.Now()
|
||||||
if bl.enableFuncCallDepth {
|
if bl.enableFuncCallDepth {
|
||||||
_, file, line, ok := runtime.Caller(bl.loggerFuncCallDepth)
|
_, file, line, ok := runtime.Caller(bl.loggerFuncCallDepth)
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -196,9 +211,10 @@ func (bl *BeeLogger) writeMsg(logLevel int, msg string) error {
|
|||||||
lm := logMsgPool.Get().(*logMsg)
|
lm := logMsgPool.Get().(*logMsg)
|
||||||
lm.level = logLevel
|
lm.level = logLevel
|
||||||
lm.msg = msg
|
lm.msg = msg
|
||||||
|
lm.when = when
|
||||||
bl.msgChan <- lm
|
bl.msgChan <- lm
|
||||||
} else {
|
} else {
|
||||||
bl.writeToLoggers(msg, logLevel)
|
bl.writeToLoggers(when, msg, logLevel)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -228,11 +244,26 @@ func (bl *BeeLogger) EnableFuncCallDepth(b bool) {
|
|||||||
// start logger chan reading.
|
// start logger chan reading.
|
||||||
// when chan is not empty, write logs.
|
// when chan is not empty, write logs.
|
||||||
func (bl *BeeLogger) startLogger() {
|
func (bl *BeeLogger) startLogger() {
|
||||||
|
gameOver := false
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case bm := <-bl.msgChan:
|
case bm := <-bl.msgChan:
|
||||||
bl.writeToLoggers(bm.msg, bm.level)
|
bl.writeToLoggers(bm.when, bm.msg, bm.level)
|
||||||
logMsgPool.Put(bm)
|
logMsgPool.Put(bm)
|
||||||
|
case sg := <-bl.signalChan:
|
||||||
|
// Now should only send "flush" or "close" to bl.signalChan
|
||||||
|
bl.flush()
|
||||||
|
if sg == "close" {
|
||||||
|
for _, l := range bl.outputs {
|
||||||
|
l.Destroy()
|
||||||
|
}
|
||||||
|
bl.outputs = nil
|
||||||
|
gameOver = true
|
||||||
|
}
|
||||||
|
bl.wg.Done()
|
||||||
|
}
|
||||||
|
if gameOver {
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -341,17 +372,45 @@ func (bl *BeeLogger) Trace(format string, v ...interface{}) {
|
|||||||
|
|
||||||
// Flush flush all chan data.
|
// Flush flush all chan data.
|
||||||
func (bl *BeeLogger) Flush() {
|
func (bl *BeeLogger) Flush() {
|
||||||
for _, l := range bl.outputs {
|
if bl.asynchronous {
|
||||||
l.Flush()
|
bl.signalChan <- "flush"
|
||||||
|
bl.wg.Wait()
|
||||||
|
bl.wg.Add(1)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
bl.flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close close logger, flush all chan data and destroy all adapters in BeeLogger.
|
// Close close logger, flush all chan data and destroy all adapters in BeeLogger.
|
||||||
func (bl *BeeLogger) Close() {
|
func (bl *BeeLogger) Close() {
|
||||||
|
if bl.asynchronous {
|
||||||
|
bl.signalChan <- "close"
|
||||||
|
bl.wg.Wait()
|
||||||
|
} else {
|
||||||
|
bl.flush()
|
||||||
|
for _, l := range bl.outputs {
|
||||||
|
l.Destroy()
|
||||||
|
}
|
||||||
|
bl.outputs = nil
|
||||||
|
}
|
||||||
|
close(bl.msgChan)
|
||||||
|
close(bl.signalChan)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset close all outputs, and set bl.outputs to nil
|
||||||
|
func (bl *BeeLogger) Reset() {
|
||||||
|
bl.Flush()
|
||||||
|
for _, l := range bl.outputs {
|
||||||
|
l.Destroy()
|
||||||
|
}
|
||||||
|
bl.outputs = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bl *BeeLogger) flush() {
|
||||||
for {
|
for {
|
||||||
if len(bl.msgChan) > 0 {
|
if len(bl.msgChan) > 0 {
|
||||||
bm := <-bl.msgChan
|
bm := <-bl.msgChan
|
||||||
bl.writeToLoggers(bm.msg, bm.level)
|
bl.writeToLoggers(bm.when, bm.msg, bm.level)
|
||||||
logMsgPool.Put(bm)
|
logMsgPool.Put(bm)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -359,6 +418,5 @@ func (bl *BeeLogger) Close() {
|
|||||||
}
|
}
|
||||||
for _, l := range bl.outputs {
|
for _, l := range bl.outputs {
|
||||||
l.Flush()
|
l.Flush()
|
||||||
l.Destroy()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
80
vendor/github.com/astaxie/beego/logs/logger.go
generated
vendored
Normal file
80
vendor/github.com/astaxie/beego/logs/logger.go
generated
vendored
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
// Copyright 2014 beego Author. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
|
||||||
|
package logs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type logWriter struct {
|
||||||
|
sync.Mutex
|
||||||
|
writer io.Writer
|
||||||
|
}
|
||||||
|
|
||||||
|
func newLogWriter(wr io.Writer) *logWriter {
|
||||||
|
return &logWriter{writer: wr}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lg *logWriter) println(when time.Time, msg string) {
|
||||||
|
lg.Lock()
|
||||||
|
h, _ := formatTimeHeader(when)
|
||||||
|
lg.writer.Write(append(append(h, msg...), '\n'))
|
||||||
|
lg.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
func formatTimeHeader(when time.Time) ([]byte, int) {
|
||||||
|
y, mo, d := when.Date()
|
||||||
|
h, mi, s := when.Clock()
|
||||||
|
//len(2006/01/02 15:03:04)==19
|
||||||
|
var buf [20]byte
|
||||||
|
t := 3
|
||||||
|
for y >= 10 {
|
||||||
|
p := y / 10
|
||||||
|
buf[t] = byte('0' + y - p*10)
|
||||||
|
y = p
|
||||||
|
t--
|
||||||
|
}
|
||||||
|
buf[0] = byte('0' + y)
|
||||||
|
buf[4] = '/'
|
||||||
|
if mo > 9 {
|
||||||
|
buf[5] = '1'
|
||||||
|
buf[6] = byte('0' + mo - 9)
|
||||||
|
} else {
|
||||||
|
buf[5] = '0'
|
||||||
|
buf[6] = byte('0' + mo)
|
||||||
|
}
|
||||||
|
buf[7] = '/'
|
||||||
|
t = d / 10
|
||||||
|
buf[8] = byte('0' + t)
|
||||||
|
buf[9] = byte('0' + d - t*10)
|
||||||
|
buf[10] = ' '
|
||||||
|
t = h / 10
|
||||||
|
buf[11] = byte('0' + t)
|
||||||
|
buf[12] = byte('0' + h - t*10)
|
||||||
|
buf[13] = ':'
|
||||||
|
t = mi / 10
|
||||||
|
buf[14] = byte('0' + t)
|
||||||
|
buf[15] = byte('0' + mi - t*10)
|
||||||
|
buf[16] = ':'
|
||||||
|
t = s / 10
|
||||||
|
buf[17] = byte('0' + t)
|
||||||
|
buf[18] = byte('0' + s - t*10)
|
||||||
|
buf[19] = ' '
|
||||||
|
|
||||||
|
return buf[0:], d
|
||||||
|
}
|
116
vendor/github.com/astaxie/beego/logs/multifile.go
generated
vendored
Normal file
116
vendor/github.com/astaxie/beego/logs/multifile.go
generated
vendored
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
// Copyright 2014 beego Author. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package logs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A filesLogWriter manages several fileLogWriter
|
||||||
|
// filesLogWriter will write logs to the file in json configuration and write the same level log to correspond file
|
||||||
|
// means if the file name in configuration is project.log filesLogWriter will create project.error.log/project.debug.log
|
||||||
|
// and write the error-level logs to project.error.log and write the debug-level logs to project.debug.log
|
||||||
|
// the rotate attribute also acts like fileLogWriter
|
||||||
|
type multiFileLogWriter struct {
|
||||||
|
writers [LevelDebug + 1 + 1]*fileLogWriter // the last one for fullLogWriter
|
||||||
|
fullLogWriter *fileLogWriter
|
||||||
|
Separate []string `json:"separate"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var levelNames = [...]string{"emergency", "alert", "critical", "error", "warning", "notice", "info", "debug"}
|
||||||
|
|
||||||
|
// Init file logger with json config.
|
||||||
|
// jsonConfig like:
|
||||||
|
// {
|
||||||
|
// "filename":"logs/beego.log",
|
||||||
|
// "maxLines":0,
|
||||||
|
// "maxsize":0,
|
||||||
|
// "daily":true,
|
||||||
|
// "maxDays":15,
|
||||||
|
// "rotate":true,
|
||||||
|
// "perm":0600,
|
||||||
|
// "separate":["emergency", "alert", "critical", "error", "warning", "notice", "info", "debug"],
|
||||||
|
// }
|
||||||
|
|
||||||
|
func (f *multiFileLogWriter) Init(config string) error {
|
||||||
|
writer := newFileWriter().(*fileLogWriter)
|
||||||
|
err := writer.Init(config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
f.fullLogWriter = writer
|
||||||
|
f.writers[LevelDebug+1] = writer
|
||||||
|
|
||||||
|
//unmarshal "separate" field to f.Separate
|
||||||
|
json.Unmarshal([]byte(config), f)
|
||||||
|
|
||||||
|
jsonMap := map[string]interface{}{}
|
||||||
|
json.Unmarshal([]byte(config), &jsonMap)
|
||||||
|
|
||||||
|
for i := LevelEmergency; i < LevelDebug+1; i++ {
|
||||||
|
for _, v := range f.Separate {
|
||||||
|
if v == levelNames[i] {
|
||||||
|
jsonMap["filename"] = f.fullLogWriter.fileNameOnly + "." + levelNames[i] + f.fullLogWriter.suffix
|
||||||
|
jsonMap["level"] = i
|
||||||
|
bs, _ := json.Marshal(jsonMap)
|
||||||
|
writer = newFileWriter().(*fileLogWriter)
|
||||||
|
writer.Init(string(bs))
|
||||||
|
f.writers[i] = writer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *multiFileLogWriter) Destroy() {
|
||||||
|
for i := 0; i < len(f.writers); i++ {
|
||||||
|
if f.writers[i] != nil {
|
||||||
|
f.writers[i].Destroy()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *multiFileLogWriter) WriteMsg(when time.Time, msg string, level int) error {
|
||||||
|
if f.fullLogWriter != nil {
|
||||||
|
f.fullLogWriter.WriteMsg(when, msg, level)
|
||||||
|
}
|
||||||
|
for i := 0; i < len(f.writers)-1; i++ {
|
||||||
|
if f.writers[i] != nil {
|
||||||
|
if level == f.writers[i].Level {
|
||||||
|
f.writers[i].WriteMsg(when, msg, level)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *multiFileLogWriter) Flush() {
|
||||||
|
for i := 0; i < len(f.writers); i++ {
|
||||||
|
if f.writers[i] != nil {
|
||||||
|
f.writers[i].Flush()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// newFilesWriter create a FileLogWriter returning as LoggerInterface.
|
||||||
|
func newFilesWriter() Logger {
|
||||||
|
return &multiFileLogWriter{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
Register("multifile", newFilesWriter)
|
||||||
|
}
|
4
vendor/github.com/astaxie/beego/logs/smtp.go
generated
vendored
4
vendor/github.com/astaxie/beego/logs/smtp.go
generated
vendored
@ -126,7 +126,7 @@ func (s *SMTPWriter) sendMail(hostAddressWithPort string, auth smtp.Auth, fromAd
|
|||||||
|
|
||||||
// WriteMsg write message in smtp writer.
|
// WriteMsg write message in smtp writer.
|
||||||
// it will send an email with subject and only this message.
|
// it will send an email with subject and only this message.
|
||||||
func (s *SMTPWriter) WriteMsg(msg string, level int) error {
|
func (s *SMTPWriter) WriteMsg(when time.Time, msg string, level int) error {
|
||||||
if level > s.Level {
|
if level > s.Level {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -140,7 +140,7 @@ func (s *SMTPWriter) WriteMsg(msg string, level int) error {
|
|||||||
// and send the email all in one step.
|
// and send the email all in one step.
|
||||||
contentType := "Content-Type: text/plain" + "; charset=UTF-8"
|
contentType := "Content-Type: text/plain" + "; charset=UTF-8"
|
||||||
mailmsg := []byte("To: " + strings.Join(s.RecipientAddresses, ";") + "\r\nFrom: " + s.FromAddress + "<" + s.FromAddress +
|
mailmsg := []byte("To: " + strings.Join(s.RecipientAddresses, ";") + "\r\nFrom: " + s.FromAddress + "<" + s.FromAddress +
|
||||||
">\r\nSubject: " + s.Subject + "\r\n" + contentType + "\r\n\r\n" + fmt.Sprintf(".%s", time.Now().Format("2006-01-02 15:04:05")) + msg)
|
">\r\nSubject: " + s.Subject + "\r\n" + contentType + "\r\n\r\n" + fmt.Sprintf(".%s", when.Format("2006-01-02 15:04:05")) + msg)
|
||||||
|
|
||||||
return s.sendMail(s.Host, auth, s.FromAddress, s.RecipientAddresses, mailmsg)
|
return s.sendMail(s.Host, auth, s.FromAddress, s.RecipientAddresses, mailmsg)
|
||||||
}
|
}
|
||||||
|
53
vendor/github.com/astaxie/beego/migration/ddl.go
generated
vendored
53
vendor/github.com/astaxie/beego/migration/ddl.go
generated
vendored
@ -1,53 +0,0 @@
|
|||||||
// Copyright 2014 beego Author. All Rights Reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package migration
|
|
||||||
|
|
||||||
// Table store the tablename and Column
|
|
||||||
type Table struct {
|
|
||||||
TableName string
|
|
||||||
Columns []*Column
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create return the create sql
|
|
||||||
func (t *Table) Create() string {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// Drop return the drop sql
|
|
||||||
func (t *Table) Drop() string {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// Column define the columns name type and Default
|
|
||||||
type Column struct {
|
|
||||||
Name string
|
|
||||||
Type string
|
|
||||||
Default interface{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create return create sql with the provided tbname and columns
|
|
||||||
func Create(tbname string, columns ...Column) string {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// Drop return the drop sql with the provided tbname and columns
|
|
||||||
func Drop(tbname string, columns ...Column) string {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// TableDDL is still in think
|
|
||||||
func TableDDL(tbname string, columns ...Column) string {
|
|
||||||
return ""
|
|
||||||
}
|
|
278
vendor/github.com/astaxie/beego/migration/migration.go
generated
vendored
278
vendor/github.com/astaxie/beego/migration/migration.go
generated
vendored
@ -1,278 +0,0 @@
|
|||||||
// Copyright 2014 beego Author. All Rights Reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
// Package migration is used for migration
|
|
||||||
//
|
|
||||||
// The table structure is as follow:
|
|
||||||
//
|
|
||||||
// CREATE TABLE `migrations` (
|
|
||||||
// `id_migration` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'surrogate key',
|
|
||||||
// `name` varchar(255) DEFAULT NULL COMMENT 'migration name, unique',
|
|
||||||
// `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'date migrated or rolled back',
|
|
||||||
// `statements` longtext COMMENT 'SQL statements for this migration',
|
|
||||||
// `rollback_statements` longtext,
|
|
||||||
// `status` enum('update','rollback') DEFAULT NULL COMMENT 'update indicates it is a normal migration while rollback means this migration is rolled back',
|
|
||||||
// PRIMARY KEY (`id_migration`)
|
|
||||||
// ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
|
||||||
package migration
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"sort"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/astaxie/beego"
|
|
||||||
"github.com/astaxie/beego/orm"
|
|
||||||
)
|
|
||||||
|
|
||||||
// const the data format for the bee generate migration datatype
|
|
||||||
const (
|
|
||||||
DateFormat = "20060102_150405"
|
|
||||||
DBDateFormat = "2006-01-02 15:04:05"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Migrationer is an interface for all Migration struct
|
|
||||||
type Migrationer interface {
|
|
||||||
Up()
|
|
||||||
Down()
|
|
||||||
Reset()
|
|
||||||
Exec(name, status string) error
|
|
||||||
GetCreated() int64
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
migrationMap map[string]Migrationer
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
migrationMap = make(map[string]Migrationer)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Migration the basic type which will implement the basic type
|
|
||||||
type Migration struct {
|
|
||||||
sqls []string
|
|
||||||
Created string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Up implement in the Inheritance struct for upgrade
|
|
||||||
func (m *Migration) Up() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Down implement in the Inheritance struct for down
|
|
||||||
func (m *Migration) Down() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// SQL add sql want to execute
|
|
||||||
func (m *Migration) SQL(sql string) {
|
|
||||||
m.sqls = append(m.sqls, sql)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset the sqls
|
|
||||||
func (m *Migration) Reset() {
|
|
||||||
m.sqls = make([]string, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Exec execute the sql already add in the sql
|
|
||||||
func (m *Migration) Exec(name, status string) error {
|
|
||||||
o := orm.NewOrm()
|
|
||||||
for _, s := range m.sqls {
|
|
||||||
beego.Info("exec sql:", s)
|
|
||||||
r := o.Raw(s)
|
|
||||||
_, err := r.Exec()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return m.addOrUpdateRecord(name, status)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Migration) addOrUpdateRecord(name, status string) error {
|
|
||||||
o := orm.NewOrm()
|
|
||||||
if status == "down" {
|
|
||||||
status = "rollback"
|
|
||||||
p, err := o.Raw("update migrations set status = ?, rollback_statements = ?, created_at = ? where name = ?").Prepare()
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
_, err = p.Exec(status, strings.Join(m.sqls, "; "), time.Now().Format(DBDateFormat), name)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
status = "update"
|
|
||||||
p, err := o.Raw("insert into migrations(name, created_at, statements, status) values(?,?,?,?)").Prepare()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, err = p.Exec(name, time.Now().Format(DBDateFormat), strings.Join(m.sqls, "; "), status)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetCreated get the unixtime from the Created
|
|
||||||
func (m *Migration) GetCreated() int64 {
|
|
||||||
t, err := time.Parse(DateFormat, m.Created)
|
|
||||||
if err != nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return t.Unix()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register register the Migration in the map
|
|
||||||
func Register(name string, m Migrationer) error {
|
|
||||||
if _, ok := migrationMap[name]; ok {
|
|
||||||
return errors.New("already exist name:" + name)
|
|
||||||
}
|
|
||||||
migrationMap[name] = m
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Upgrade upgrate the migration from lasttime
|
|
||||||
func Upgrade(lasttime int64) error {
|
|
||||||
sm := sortMap(migrationMap)
|
|
||||||
i := 0
|
|
||||||
for _, v := range sm {
|
|
||||||
if v.created > lasttime {
|
|
||||||
beego.Info("start upgrade", v.name)
|
|
||||||
v.m.Reset()
|
|
||||||
v.m.Up()
|
|
||||||
err := v.m.Exec(v.name, "up")
|
|
||||||
if err != nil {
|
|
||||||
beego.Error("execute error:", err)
|
|
||||||
time.Sleep(2 * time.Second)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
beego.Info("end upgrade:", v.name)
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
beego.Info("total success upgrade:", i, " migration")
|
|
||||||
time.Sleep(2 * time.Second)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rollback rollback the migration by the name
|
|
||||||
func Rollback(name string) error {
|
|
||||||
if v, ok := migrationMap[name]; ok {
|
|
||||||
beego.Info("start rollback")
|
|
||||||
v.Reset()
|
|
||||||
v.Down()
|
|
||||||
err := v.Exec(name, "down")
|
|
||||||
if err != nil {
|
|
||||||
beego.Error("execute error:", err)
|
|
||||||
time.Sleep(2 * time.Second)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
beego.Info("end rollback")
|
|
||||||
time.Sleep(2 * time.Second)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
beego.Error("not exist the migrationMap name:" + name)
|
|
||||||
time.Sleep(2 * time.Second)
|
|
||||||
return errors.New("not exist the migrationMap name:" + name)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset reset all migration
|
|
||||||
// run all migration's down function
|
|
||||||
func Reset() error {
|
|
||||||
sm := sortMap(migrationMap)
|
|
||||||
i := 0
|
|
||||||
for j := len(sm) - 1; j >= 0; j-- {
|
|
||||||
v := sm[j]
|
|
||||||
if isRollBack(v.name) {
|
|
||||||
beego.Info("skip the", v.name)
|
|
||||||
time.Sleep(1 * time.Second)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
beego.Info("start reset:", v.name)
|
|
||||||
v.m.Reset()
|
|
||||||
v.m.Down()
|
|
||||||
err := v.m.Exec(v.name, "down")
|
|
||||||
if err != nil {
|
|
||||||
beego.Error("execute error:", err)
|
|
||||||
time.Sleep(2 * time.Second)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
i++
|
|
||||||
beego.Info("end reset:", v.name)
|
|
||||||
}
|
|
||||||
beego.Info("total success reset:", i, " migration")
|
|
||||||
time.Sleep(2 * time.Second)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Refresh first Reset, then Upgrade
|
|
||||||
func Refresh() error {
|
|
||||||
err := Reset()
|
|
||||||
if err != nil {
|
|
||||||
beego.Error("execute error:", err)
|
|
||||||
time.Sleep(2 * time.Second)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = Upgrade(0)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
type dataSlice []data
|
|
||||||
|
|
||||||
type data struct {
|
|
||||||
created int64
|
|
||||||
name string
|
|
||||||
m Migrationer
|
|
||||||
}
|
|
||||||
|
|
||||||
// Len is part of sort.Interface.
|
|
||||||
func (d dataSlice) Len() int {
|
|
||||||
return len(d)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Swap is part of sort.Interface.
|
|
||||||
func (d dataSlice) Swap(i, j int) {
|
|
||||||
d[i], d[j] = d[j], d[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Less is part of sort.Interface. We use count as the value to sort by
|
|
||||||
func (d dataSlice) Less(i, j int) bool {
|
|
||||||
return d[i].created < d[j].created
|
|
||||||
}
|
|
||||||
|
|
||||||
func sortMap(m map[string]Migrationer) dataSlice {
|
|
||||||
s := make(dataSlice, 0, len(m))
|
|
||||||
for k, v := range m {
|
|
||||||
d := data{}
|
|
||||||
d.created = v.GetCreated()
|
|
||||||
d.name = k
|
|
||||||
d.m = v
|
|
||||||
s = append(s, d)
|
|
||||||
}
|
|
||||||
sort.Sort(s)
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
func isRollBack(name string) bool {
|
|
||||||
o := orm.NewOrm()
|
|
||||||
var maps []orm.Params
|
|
||||||
num, err := o.Raw("select * from migrations where `name` = ? order by id_migration desc", name).Values(&maps)
|
|
||||||
if err != nil {
|
|
||||||
beego.Info("get name has error", err)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if num <= 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if maps[0]["status"] == "rollback" {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
7
vendor/github.com/astaxie/beego/namespace.go
generated
vendored
7
vendor/github.com/astaxie/beego/namespace.go
generated
vendored
@ -388,3 +388,10 @@ func NSNamespace(prefix string, params ...LinkNamespace) LinkNamespace {
|
|||||||
ns.Namespace(n)
|
ns.Namespace(n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NSHandler add handler
|
||||||
|
func NSHandler(rootpath string, h http.Handler) LinkNamespace {
|
||||||
|
return func(ns *Namespace) {
|
||||||
|
ns.Handler(rootpath, h)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
14
vendor/github.com/astaxie/beego/orm/db.go
generated
vendored
14
vendor/github.com/astaxie/beego/orm/db.go
generated
vendored
@ -113,7 +113,7 @@ func (d *dbBase) collectFieldValue(mi *modelInfo, fi *fieldInfo, ind reflect.Val
|
|||||||
if fi.pk {
|
if fi.pk {
|
||||||
_, value, _ = getExistPk(mi, ind)
|
_, value, _ = getExistPk(mi, ind)
|
||||||
} else {
|
} else {
|
||||||
field := ind.Field(fi.fieldIndex)
|
field := ind.FieldByIndex(fi.fieldIndex)
|
||||||
if fi.isFielder {
|
if fi.isFielder {
|
||||||
f := field.Addr().Interface().(Fielder)
|
f := field.Addr().Interface().(Fielder)
|
||||||
value = f.RawValue()
|
value = f.RawValue()
|
||||||
@ -517,9 +517,9 @@ func (d *dbBase) Delete(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.
|
|||||||
if num > 0 {
|
if num > 0 {
|
||||||
if mi.fields.pk.auto {
|
if mi.fields.pk.auto {
|
||||||
if mi.fields.pk.fieldType&IsPostiveIntegerField > 0 {
|
if mi.fields.pk.fieldType&IsPostiveIntegerField > 0 {
|
||||||
ind.Field(mi.fields.pk.fieldIndex).SetUint(0)
|
ind.FieldByIndex(mi.fields.pk.fieldIndex).SetUint(0)
|
||||||
} else {
|
} else {
|
||||||
ind.Field(mi.fields.pk.fieldIndex).SetInt(0)
|
ind.FieldByIndex(mi.fields.pk.fieldIndex).SetInt(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err := d.deleteRels(q, mi, []interface{}{pkValue}, tz)
|
err := d.deleteRels(q, mi, []interface{}{pkValue}, tz)
|
||||||
@ -859,13 +859,13 @@ func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condi
|
|||||||
mmi = fi.relModelInfo
|
mmi = fi.relModelInfo
|
||||||
field := last
|
field := last
|
||||||
if last.Kind() != reflect.Invalid {
|
if last.Kind() != reflect.Invalid {
|
||||||
field = reflect.Indirect(last.Field(fi.fieldIndex))
|
field = reflect.Indirect(last.FieldByIndex(fi.fieldIndex))
|
||||||
if field.IsValid() {
|
if field.IsValid() {
|
||||||
d.setColsValues(mmi, &field, mmi.fields.dbcols, trefs[:len(mmi.fields.dbcols)], tz)
|
d.setColsValues(mmi, &field, mmi.fields.dbcols, trefs[:len(mmi.fields.dbcols)], tz)
|
||||||
for _, fi := range mmi.fields.fieldsReverse {
|
for _, fi := range mmi.fields.fieldsReverse {
|
||||||
if fi.inModel && fi.reverseFieldInfo.mi == lastm {
|
if fi.inModel && fi.reverseFieldInfo.mi == lastm {
|
||||||
if fi.reverseFieldInfo != nil {
|
if fi.reverseFieldInfo != nil {
|
||||||
f := field.Field(fi.fieldIndex)
|
f := field.FieldByIndex(fi.fieldIndex)
|
||||||
if f.Kind() == reflect.Ptr {
|
if f.Kind() == reflect.Ptr {
|
||||||
f.Set(last.Addr())
|
f.Set(last.Addr())
|
||||||
}
|
}
|
||||||
@ -1014,7 +1014,7 @@ func (d *dbBase) setColsValues(mi *modelInfo, ind *reflect.Value, cols []string,
|
|||||||
|
|
||||||
fi := mi.fields.GetByColumn(column)
|
fi := mi.fields.GetByColumn(column)
|
||||||
|
|
||||||
field := ind.Field(fi.fieldIndex)
|
field := ind.FieldByIndex(fi.fieldIndex)
|
||||||
|
|
||||||
value, err := d.convertValueFromDB(fi, val, tz)
|
value, err := d.convertValueFromDB(fi, val, tz)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1350,7 +1350,7 @@ setValue:
|
|||||||
fieldType = fi.relModelInfo.fields.pk.fieldType
|
fieldType = fi.relModelInfo.fields.pk.fieldType
|
||||||
mf := reflect.New(fi.relModelInfo.addrField.Elem().Type())
|
mf := reflect.New(fi.relModelInfo.addrField.Elem().Type())
|
||||||
field.Set(mf)
|
field.Set(mf)
|
||||||
f := mf.Elem().Field(fi.relModelInfo.fields.pk.fieldIndex)
|
f := mf.Elem().FieldByIndex(fi.relModelInfo.fields.pk.fieldIndex)
|
||||||
field = f
|
field = f
|
||||||
goto setValue
|
goto setValue
|
||||||
}
|
}
|
||||||
|
3
vendor/github.com/astaxie/beego/orm/db_alias.go
generated
vendored
3
vendor/github.com/astaxie/beego/orm/db_alias.go
generated
vendored
@ -59,6 +59,7 @@ var (
|
|||||||
"postgres": DRPostgres,
|
"postgres": DRPostgres,
|
||||||
"sqlite3": DRSqlite,
|
"sqlite3": DRSqlite,
|
||||||
"tidb": DRTiDB,
|
"tidb": DRTiDB,
|
||||||
|
"oracle": DROracle,
|
||||||
}
|
}
|
||||||
dbBasers = map[DriverType]dbBaser{
|
dbBasers = map[DriverType]dbBaser{
|
||||||
DRMySQL: newdbBaseMysql(),
|
DRMySQL: newdbBaseMysql(),
|
||||||
@ -151,7 +152,7 @@ func detectTZ(al *alias) {
|
|||||||
al.Engine = "INNODB"
|
al.Engine = "INNODB"
|
||||||
}
|
}
|
||||||
|
|
||||||
case DRSqlite:
|
case DRSqlite, DROracle:
|
||||||
al.TZ = time.UTC
|
al.TZ = time.UTC
|
||||||
|
|
||||||
case DRPostgres:
|
case DRPostgres:
|
||||||
|
67
vendor/github.com/astaxie/beego/orm/db_oracle.go
generated
vendored
67
vendor/github.com/astaxie/beego/orm/db_oracle.go
generated
vendored
@ -14,6 +14,41 @@
|
|||||||
|
|
||||||
package orm
|
package orm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// oracle operators.
|
||||||
|
var oracleOperators = map[string]string{
|
||||||
|
"exact": "= ?",
|
||||||
|
"gt": "> ?",
|
||||||
|
"gte": ">= ?",
|
||||||
|
"lt": "< ?",
|
||||||
|
"lte": "<= ?",
|
||||||
|
"//iendswith": "LIKE ?",
|
||||||
|
}
|
||||||
|
|
||||||
|
// oracle column field types.
|
||||||
|
var oracleTypes = map[string]string{
|
||||||
|
"pk": "NOT NULL PRIMARY KEY",
|
||||||
|
"bool": "bool",
|
||||||
|
"string": "VARCHAR2(%d)",
|
||||||
|
"string-text": "VARCHAR2(%d)",
|
||||||
|
"time.Time-date": "DATE",
|
||||||
|
"time.Time": "TIMESTAMP",
|
||||||
|
"int8": "INTEGER",
|
||||||
|
"int16": "INTEGER",
|
||||||
|
"int32": "INTEGER",
|
||||||
|
"int64": "INTEGER",
|
||||||
|
"uint8": "INTEGER",
|
||||||
|
"uint16": "INTEGER",
|
||||||
|
"uint32": "INTEGER",
|
||||||
|
"uint64": "INTEGER",
|
||||||
|
"float64": "NUMBER",
|
||||||
|
"float64-decimal": "NUMBER(%d, %d)",
|
||||||
|
}
|
||||||
|
|
||||||
// oracle dbBaser
|
// oracle dbBaser
|
||||||
type dbBaseOracle struct {
|
type dbBaseOracle struct {
|
||||||
dbBase
|
dbBase
|
||||||
@ -27,3 +62,35 @@ func newdbBaseOracle() dbBaser {
|
|||||||
b.ins = b
|
b.ins = b
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OperatorSQL get oracle operator.
|
||||||
|
func (d *dbBaseOracle) OperatorSQL(operator string) string {
|
||||||
|
return oracleOperators[operator]
|
||||||
|
}
|
||||||
|
|
||||||
|
// DbTypes get oracle table field types.
|
||||||
|
func (d *dbBaseOracle) DbTypes() map[string]string {
|
||||||
|
return oracleTypes
|
||||||
|
}
|
||||||
|
|
||||||
|
//ShowTablesQuery show all the tables in database
|
||||||
|
func (d *dbBaseOracle) ShowTablesQuery() string {
|
||||||
|
return "SELECT TABLE_NAME FROM USER_TABLES"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Oracle
|
||||||
|
func (d *dbBaseOracle) ShowColumnsQuery(table string) string {
|
||||||
|
return fmt.Sprintf("SELECT COLUMN_NAME FROM ALL_TAB_COLUMNS "+
|
||||||
|
"WHERE TABLE_NAME ='%s'", strings.ToUpper(table))
|
||||||
|
}
|
||||||
|
|
||||||
|
// check index is exist
|
||||||
|
func (d *dbBaseOracle) IndexExists(db dbQuerier, table string, name string) bool {
|
||||||
|
row := db.QueryRow("SELECT COUNT(*) FROM USER_IND_COLUMNS, USER_INDEXES "+
|
||||||
|
"WHERE USER_IND_COLUMNS.INDEX_NAME = USER_INDEXES.INDEX_NAME "+
|
||||||
|
"AND USER_IND_COLUMNS.TABLE_NAME = ? AND USER_IND_COLUMNS.INDEX_NAME = ?", strings.ToUpper(table), strings.ToUpper(name))
|
||||||
|
|
||||||
|
var cnt int
|
||||||
|
row.Scan(&cnt)
|
||||||
|
return cnt > 0
|
||||||
|
}
|
||||||
|
2
vendor/github.com/astaxie/beego/orm/db_utils.go
generated
vendored
2
vendor/github.com/astaxie/beego/orm/db_utils.go
generated
vendored
@ -32,7 +32,7 @@ func getDbAlias(name string) *alias {
|
|||||||
func getExistPk(mi *modelInfo, ind reflect.Value) (column string, value interface{}, exist bool) {
|
func getExistPk(mi *modelInfo, ind reflect.Value) (column string, value interface{}, exist bool) {
|
||||||
fi := mi.fields.pk
|
fi := mi.fields.pk
|
||||||
|
|
||||||
v := ind.Field(fi.fieldIndex)
|
v := ind.FieldByIndex(fi.fieldIndex)
|
||||||
if fi.fieldType&IsPostiveIntegerField > 0 {
|
if fi.fieldType&IsPostiveIntegerField > 0 {
|
||||||
vu := v.Uint()
|
vu := v.Uint()
|
||||||
exist = vu > 0
|
exist = vu > 0
|
||||||
|
6
vendor/github.com/astaxie/beego/orm/models_info_f.go
generated
vendored
6
vendor/github.com/astaxie/beego/orm/models_info_f.go
generated
vendored
@ -102,7 +102,7 @@ func newFields() *fields {
|
|||||||
// single field info
|
// single field info
|
||||||
type fieldInfo struct {
|
type fieldInfo struct {
|
||||||
mi *modelInfo
|
mi *modelInfo
|
||||||
fieldIndex int
|
fieldIndex []int
|
||||||
fieldType int
|
fieldType int
|
||||||
dbcol bool
|
dbcol bool
|
||||||
inModel bool
|
inModel bool
|
||||||
@ -138,7 +138,7 @@ type fieldInfo struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// new field info
|
// new field info
|
||||||
func newFieldInfo(mi *modelInfo, field reflect.Value, sf reflect.StructField) (fi *fieldInfo, err error) {
|
func newFieldInfo(mi *modelInfo, field reflect.Value, sf reflect.StructField, mName string) (fi *fieldInfo, err error) {
|
||||||
var (
|
var (
|
||||||
tag string
|
tag string
|
||||||
tagValue string
|
tagValue string
|
||||||
@ -278,7 +278,7 @@ checkType:
|
|||||||
fi.column = getColumnName(fieldType, addrField, sf, tags["column"])
|
fi.column = getColumnName(fieldType, addrField, sf, tags["column"])
|
||||||
fi.addrValue = addrField
|
fi.addrValue = addrField
|
||||||
fi.sf = sf
|
fi.sf = sf
|
||||||
fi.fullName = mi.fullName + "." + sf.Name
|
fi.fullName = mi.fullName + mName + "." + sf.Name
|
||||||
|
|
||||||
fi.null = attrs["null"]
|
fi.null = attrs["null"]
|
||||||
fi.index = attrs["index"]
|
fi.index = attrs["index"]
|
||||||
|
29
vendor/github.com/astaxie/beego/orm/models_info_m.go
generated
vendored
29
vendor/github.com/astaxie/beego/orm/models_info_m.go
generated
vendored
@ -36,11 +36,6 @@ type modelInfo struct {
|
|||||||
|
|
||||||
// new model info
|
// new model info
|
||||||
func newModelInfo(val reflect.Value) (info *modelInfo) {
|
func newModelInfo(val reflect.Value) (info *modelInfo) {
|
||||||
var (
|
|
||||||
err error
|
|
||||||
fi *fieldInfo
|
|
||||||
sf reflect.StructField
|
|
||||||
)
|
|
||||||
|
|
||||||
info = &modelInfo{}
|
info = &modelInfo{}
|
||||||
info.fields = newFields()
|
info.fields = newFields()
|
||||||
@ -53,13 +48,31 @@ func newModelInfo(val reflect.Value) (info *modelInfo) {
|
|||||||
info.name = typ.Name()
|
info.name = typ.Name()
|
||||||
info.fullName = getFullName(typ)
|
info.fullName = getFullName(typ)
|
||||||
|
|
||||||
|
addModelFields(info, ind, "", []int{})
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func addModelFields(info *modelInfo, ind reflect.Value, mName string, index []int) {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
fi *fieldInfo
|
||||||
|
sf reflect.StructField
|
||||||
|
)
|
||||||
|
|
||||||
for i := 0; i < ind.NumField(); i++ {
|
for i := 0; i < ind.NumField(); i++ {
|
||||||
field := ind.Field(i)
|
field := ind.Field(i)
|
||||||
sf = ind.Type().Field(i)
|
sf = ind.Type().Field(i)
|
||||||
if sf.PkgPath != "" {
|
if sf.PkgPath != "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
fi, err = newFieldInfo(info, field, sf)
|
// add anonymous struct fields
|
||||||
|
if sf.Anonymous {
|
||||||
|
addModelFields(info, field, mName+"."+sf.Name, append(index, i))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
fi, err = newFieldInfo(info, field, sf, mName)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == errSkipField {
|
if err == errSkipField {
|
||||||
@ -84,7 +97,7 @@ func newModelInfo(val reflect.Value) (info *modelInfo) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fi.fieldIndex = i
|
fi.fieldIndex = append(index, i)
|
||||||
fi.mi = info
|
fi.mi = info
|
||||||
fi.inModel = true
|
fi.inModel = true
|
||||||
}
|
}
|
||||||
@ -93,8 +106,6 @@ func newModelInfo(val reflect.Value) (info *modelInfo) {
|
|||||||
fmt.Println(fmt.Errorf("field: %s.%s, %s", ind.Type(), sf.Name, err))
|
fmt.Println(fmt.Errorf("field: %s.%s, %s", ind.Type(), sf.Name, err))
|
||||||
os.Exit(2)
|
os.Exit(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// combine related model info to new model info.
|
// combine related model info to new model info.
|
||||||
|
8
vendor/github.com/astaxie/beego/orm/orm.go
generated
vendored
8
vendor/github.com/astaxie/beego/orm/orm.go
generated
vendored
@ -140,7 +140,7 @@ func (o *orm) ReadOrCreate(md interface{}, col1 string, cols ...string) (bool, i
|
|||||||
return (err == nil), id, err
|
return (err == nil), id, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return false, ind.Field(mi.fields.pk.fieldIndex).Int(), err
|
return false, ind.FieldByIndex(mi.fields.pk.fieldIndex).Int(), err
|
||||||
}
|
}
|
||||||
|
|
||||||
// insert model data to database
|
// insert model data to database
|
||||||
@ -160,9 +160,9 @@ func (o *orm) Insert(md interface{}) (int64, error) {
|
|||||||
func (o *orm) setPk(mi *modelInfo, ind reflect.Value, id int64) {
|
func (o *orm) setPk(mi *modelInfo, ind reflect.Value, id int64) {
|
||||||
if mi.fields.pk.auto {
|
if mi.fields.pk.auto {
|
||||||
if mi.fields.pk.fieldType&IsPostiveIntegerField > 0 {
|
if mi.fields.pk.fieldType&IsPostiveIntegerField > 0 {
|
||||||
ind.Field(mi.fields.pk.fieldIndex).SetUint(uint64(id))
|
ind.FieldByIndex(mi.fields.pk.fieldIndex).SetUint(uint64(id))
|
||||||
} else {
|
} else {
|
||||||
ind.Field(mi.fields.pk.fieldIndex).SetInt(id)
|
ind.FieldByIndex(mi.fields.pk.fieldIndex).SetInt(id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -290,7 +290,7 @@ func (o *orm) LoadRelated(md interface{}, name string, args ...interface{}) (int
|
|||||||
qs.orders = []string{order}
|
qs.orders = []string{order}
|
||||||
}
|
}
|
||||||
|
|
||||||
find := ind.Field(fi.fieldIndex)
|
find := ind.FieldByIndex(fi.fieldIndex)
|
||||||
|
|
||||||
var nums int64
|
var nums int64
|
||||||
var err error
|
var err error
|
||||||
|
4
vendor/github.com/astaxie/beego/orm/orm_object.go
generated
vendored
4
vendor/github.com/astaxie/beego/orm/orm_object.go
generated
vendored
@ -51,9 +51,9 @@ func (o *insertSet) Insert(md interface{}) (int64, error) {
|
|||||||
if id > 0 {
|
if id > 0 {
|
||||||
if o.mi.fields.pk.auto {
|
if o.mi.fields.pk.auto {
|
||||||
if o.mi.fields.pk.fieldType&IsPostiveIntegerField > 0 {
|
if o.mi.fields.pk.fieldType&IsPostiveIntegerField > 0 {
|
||||||
ind.Field(o.mi.fields.pk.fieldIndex).SetUint(uint64(id))
|
ind.FieldByIndex(o.mi.fields.pk.fieldIndex).SetUint(uint64(id))
|
||||||
} else {
|
} else {
|
||||||
ind.Field(o.mi.fields.pk.fieldIndex).SetInt(id)
|
ind.FieldByIndex(o.mi.fields.pk.fieldIndex).SetInt(id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
4
vendor/github.com/astaxie/beego/orm/orm_raw.go
generated
vendored
4
vendor/github.com/astaxie/beego/orm/orm_raw.go
generated
vendored
@ -342,7 +342,7 @@ func (o *rawSet) QueryRow(containers ...interface{}) error {
|
|||||||
for _, col := range columns {
|
for _, col := range columns {
|
||||||
if fi := sMi.fields.GetByColumn(col); fi != nil {
|
if fi := sMi.fields.GetByColumn(col); fi != nil {
|
||||||
value := reflect.ValueOf(columnsMp[col]).Elem().Interface()
|
value := reflect.ValueOf(columnsMp[col]).Elem().Interface()
|
||||||
o.setFieldValue(ind.FieldByIndex([]int{fi.fieldIndex}), value)
|
o.setFieldValue(ind.FieldByIndex(fi.fieldIndex), value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -480,7 +480,7 @@ func (o *rawSet) QueryRows(containers ...interface{}) (int64, error) {
|
|||||||
for _, col := range columns {
|
for _, col := range columns {
|
||||||
if fi := sMi.fields.GetByColumn(col); fi != nil {
|
if fi := sMi.fields.GetByColumn(col); fi != nil {
|
||||||
value := reflect.ValueOf(columnsMp[col]).Elem().Interface()
|
value := reflect.ValueOf(columnsMp[col]).Elem().Interface()
|
||||||
o.setFieldValue(ind.FieldByIndex([]int{fi.fieldIndex}), value)
|
o.setFieldValue(ind.FieldByIndex(fi.fieldIndex), value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
10
vendor/github.com/astaxie/beego/orm/types.go
generated
vendored
10
vendor/github.com/astaxie/beego/orm/types.go
generated
vendored
@ -148,6 +148,10 @@ type QuerySeter interface {
|
|||||||
// add OFFSET value
|
// add OFFSET value
|
||||||
// same as Limit function's args[0]
|
// same as Limit function's args[0]
|
||||||
Offset(offset interface{}) QuerySeter
|
Offset(offset interface{}) QuerySeter
|
||||||
|
// add GROUP BY expression
|
||||||
|
// for example:
|
||||||
|
// qs.GroupBy("id")
|
||||||
|
GroupBy(exprs ...string) QuerySeter
|
||||||
// add ORDER expression.
|
// add ORDER expression.
|
||||||
// "column" means ASC, "-column" means DESC.
|
// "column" means ASC, "-column" means DESC.
|
||||||
// for example:
|
// for example:
|
||||||
@ -162,6 +166,12 @@ type QuerySeter interface {
|
|||||||
// qs.RelatedSel("profile").One(&user)
|
// qs.RelatedSel("profile").One(&user)
|
||||||
// user.Profile.Age = 32
|
// user.Profile.Age = 32
|
||||||
RelatedSel(params ...interface{}) QuerySeter
|
RelatedSel(params ...interface{}) QuerySeter
|
||||||
|
// Set Distinct
|
||||||
|
// for example:
|
||||||
|
// o.QueryTable("policy").Filter("Groups__Group__Users__User", user).
|
||||||
|
// Distinct().
|
||||||
|
// All(&permissions)
|
||||||
|
Distinct() QuerySeter
|
||||||
// return QuerySeter execution result number
|
// return QuerySeter execution result number
|
||||||
// for example:
|
// for example:
|
||||||
// num, err = qs.Filter("profile__age__gt", 28).Count()
|
// num, err = qs.Filter("profile__age__gt", 28).Count()
|
||||||
|
8
vendor/github.com/astaxie/beego/parser.go
generated
vendored
8
vendor/github.com/astaxie/beego/parser.go
generated
vendored
@ -58,7 +58,7 @@ func parserPkg(pkgRealpath, pkgpath string) error {
|
|||||||
rep := strings.NewReplacer("/", "_", ".", "_")
|
rep := strings.NewReplacer("/", "_", ".", "_")
|
||||||
commentFilename = coomentPrefix + rep.Replace(pkgpath) + ".go"
|
commentFilename = coomentPrefix + rep.Replace(pkgpath) + ".go"
|
||||||
if !compareFile(pkgRealpath) {
|
if !compareFile(pkgRealpath) {
|
||||||
Info(pkgRealpath + " has not changed, not reloading")
|
Info(pkgRealpath + " no changed")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
genInfoList = make(map[string][]ControllerComments)
|
genInfoList = make(map[string][]ControllerComments)
|
||||||
@ -130,7 +130,7 @@ func parserComments(comments *ast.CommentGroup, funcName, controllerName, pkgpat
|
|||||||
}
|
}
|
||||||
|
|
||||||
func genRouterCode() {
|
func genRouterCode() {
|
||||||
os.Mkdir("routers", 0755)
|
os.Mkdir(path.Join(AppPath, "routers"), 0755)
|
||||||
Info("generate router from comments")
|
Info("generate router from comments")
|
||||||
var (
|
var (
|
||||||
globalinfo string
|
globalinfo string
|
||||||
@ -172,7 +172,7 @@ func genRouterCode() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if globalinfo != "" {
|
if globalinfo != "" {
|
||||||
f, err := os.Create(path.Join("routers", commentFilename))
|
f, err := os.Create(path.Join(AppPath, "routers", commentFilename))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@ -182,7 +182,7 @@ func genRouterCode() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func compareFile(pkgRealpath string) bool {
|
func compareFile(pkgRealpath string) bool {
|
||||||
if !utils.FileExists(path.Join("routers", commentFilename)) {
|
if !utils.FileExists(path.Join(AppPath, "routers", commentFilename)) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if utils.FileExists(lastupdateFilename) {
|
if utils.FileExists(lastupdateFilename) {
|
||||||
|
180
vendor/github.com/astaxie/beego/plugins/apiauth/apiauth.go
generated
vendored
180
vendor/github.com/astaxie/beego/plugins/apiauth/apiauth.go
generated
vendored
@ -1,180 +0,0 @@
|
|||||||
// Copyright 2014 beego Author. All Rights Reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
// Package apiauth provides handlers to enable apiauth support.
|
|
||||||
//
|
|
||||||
// Simple Usage:
|
|
||||||
// import(
|
|
||||||
// "github.com/astaxie/beego"
|
|
||||||
// "github.com/astaxie/beego/plugins/apiauth"
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// func main(){
|
|
||||||
// // apiauth every request
|
|
||||||
// beego.InsertFilter("*", beego.BeforeRouter,apiauth.APIBaiscAuth("appid","appkey"))
|
|
||||||
// beego.Run()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// Advanced Usage:
|
|
||||||
//
|
|
||||||
// func getAppSecret(appid string) string {
|
|
||||||
// // get appsecret by appid
|
|
||||||
// // maybe store in configure, maybe in database
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// beego.InsertFilter("*", beego.BeforeRouter,apiauth.APISecretAuth(getAppSecret, 360))
|
|
||||||
//
|
|
||||||
// Infomation:
|
|
||||||
//
|
|
||||||
// In the request user should include these params in the query
|
|
||||||
//
|
|
||||||
// 1. appid
|
|
||||||
//
|
|
||||||
// appid is assigned to the application
|
|
||||||
//
|
|
||||||
// 2. signature
|
|
||||||
//
|
|
||||||
// get the signature use apiauth.Signature()
|
|
||||||
//
|
|
||||||
// when you send to server remember use url.QueryEscape()
|
|
||||||
//
|
|
||||||
// 3. timestamp:
|
|
||||||
//
|
|
||||||
// send the request time, the format is yyyy-mm-dd HH:ii:ss
|
|
||||||
//
|
|
||||||
package apiauth
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/hmac"
|
|
||||||
"crypto/sha256"
|
|
||||||
"encoding/base64"
|
|
||||||
"fmt"
|
|
||||||
"net/url"
|
|
||||||
"sort"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/astaxie/beego"
|
|
||||||
"github.com/astaxie/beego/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
// AppIDToAppSecret is used to get appsecret throw appid
|
|
||||||
type AppIDToAppSecret func(string) string
|
|
||||||
|
|
||||||
// APIBaiscAuth use the basic appid/appkey as the AppIdToAppSecret
|
|
||||||
func APIBaiscAuth(appid, appkey string) beego.FilterFunc {
|
|
||||||
ft := func(aid string) string {
|
|
||||||
if aid == appid {
|
|
||||||
return appkey
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return APISecretAuth(ft, 300)
|
|
||||||
}
|
|
||||||
|
|
||||||
// APISecretAuth use AppIdToAppSecret verify and
|
|
||||||
func APISecretAuth(f AppIDToAppSecret, timeout int) beego.FilterFunc {
|
|
||||||
return func(ctx *context.Context) {
|
|
||||||
if ctx.Input.Query("appid") == "" {
|
|
||||||
ctx.ResponseWriter.WriteHeader(403)
|
|
||||||
ctx.WriteString("miss query param: appid")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
appsecret := f(ctx.Input.Query("appid"))
|
|
||||||
if appsecret == "" {
|
|
||||||
ctx.ResponseWriter.WriteHeader(403)
|
|
||||||
ctx.WriteString("not exist this appid")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if ctx.Input.Query("signature") == "" {
|
|
||||||
ctx.ResponseWriter.WriteHeader(403)
|
|
||||||
ctx.WriteString("miss query param: signature")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if ctx.Input.Query("timestamp") == "" {
|
|
||||||
ctx.ResponseWriter.WriteHeader(403)
|
|
||||||
ctx.WriteString("miss query param: timestamp")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
u, err := time.Parse("2006-01-02 15:04:05", ctx.Input.Query("timestamp"))
|
|
||||||
if err != nil {
|
|
||||||
ctx.ResponseWriter.WriteHeader(403)
|
|
||||||
ctx.WriteString("timestamp format is error, should 2006-01-02 15:04:05")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
t := time.Now()
|
|
||||||
if t.Sub(u).Seconds() > float64(timeout) {
|
|
||||||
ctx.ResponseWriter.WriteHeader(403)
|
|
||||||
ctx.WriteString("timeout! the request time is long ago, please try again")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if ctx.Input.Query("signature") !=
|
|
||||||
Signature(appsecret, ctx.Input.Method(), ctx.Request.Form, ctx.Input.URI()) {
|
|
||||||
ctx.ResponseWriter.WriteHeader(403)
|
|
||||||
ctx.WriteString("auth failed")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Signature used to generate signature with the appsecret/method/params/RequestURI
|
|
||||||
func Signature(appsecret, method string, params url.Values, RequestURI string) (result string) {
|
|
||||||
var query string
|
|
||||||
pa := make(map[string]string)
|
|
||||||
for k, v := range params {
|
|
||||||
pa[k] = v[0]
|
|
||||||
}
|
|
||||||
vs := mapSorter(pa)
|
|
||||||
vs.Sort()
|
|
||||||
for i := 0; i < vs.Len(); i++ {
|
|
||||||
if vs.Keys[i] == "signature" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if vs.Keys[i] != "" && vs.Vals[i] != "" {
|
|
||||||
query = fmt.Sprintf("%v%v%v", query, vs.Keys[i], vs.Vals[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stringToSign := fmt.Sprintf("%v\n%v\n%v\n", method, query, RequestURI)
|
|
||||||
|
|
||||||
sha256 := sha256.New
|
|
||||||
hash := hmac.New(sha256, []byte(appsecret))
|
|
||||||
hash.Write([]byte(stringToSign))
|
|
||||||
return base64.StdEncoding.EncodeToString(hash.Sum(nil))
|
|
||||||
}
|
|
||||||
|
|
||||||
type valSorter struct {
|
|
||||||
Keys []string
|
|
||||||
Vals []string
|
|
||||||
}
|
|
||||||
|
|
||||||
func mapSorter(m map[string]string) *valSorter {
|
|
||||||
vs := &valSorter{
|
|
||||||
Keys: make([]string, 0, len(m)),
|
|
||||||
Vals: make([]string, 0, len(m)),
|
|
||||||
}
|
|
||||||
for k, v := range m {
|
|
||||||
vs.Keys = append(vs.Keys, k)
|
|
||||||
vs.Vals = append(vs.Vals, v)
|
|
||||||
}
|
|
||||||
return vs
|
|
||||||
}
|
|
||||||
|
|
||||||
func (vs *valSorter) Sort() {
|
|
||||||
sort.Sort(vs)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (vs *valSorter) Len() int { return len(vs.Keys) }
|
|
||||||
func (vs *valSorter) Less(i, j int) bool { return vs.Keys[i] < vs.Keys[j] }
|
|
||||||
func (vs *valSorter) Swap(i, j int) {
|
|
||||||
vs.Vals[i], vs.Vals[j] = vs.Vals[j], vs.Vals[i]
|
|
||||||
vs.Keys[i], vs.Keys[j] = vs.Keys[j], vs.Keys[i]
|
|
||||||
}
|
|
107
vendor/github.com/astaxie/beego/plugins/auth/basic.go
generated
vendored
107
vendor/github.com/astaxie/beego/plugins/auth/basic.go
generated
vendored
@ -1,107 +0,0 @@
|
|||||||
// Copyright 2014 beego Author. All Rights Reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
// Package auth provides handlers to enable basic auth support.
|
|
||||||
// Simple Usage:
|
|
||||||
// import(
|
|
||||||
// "github.com/astaxie/beego"
|
|
||||||
// "github.com/astaxie/beego/plugins/auth"
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// func main(){
|
|
||||||
// // authenticate every request
|
|
||||||
// beego.InsertFilter("*", beego.BeforeRouter,auth.Basic("username","secretpassword"))
|
|
||||||
// beego.Run()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Advanced Usage:
|
|
||||||
//
|
|
||||||
// func SecretAuth(username, password string) bool {
|
|
||||||
// return username == "astaxie" && password == "helloBeego"
|
|
||||||
// }
|
|
||||||
// authPlugin := auth.NewBasicAuthenticator(SecretAuth, "Authorization Required")
|
|
||||||
// beego.InsertFilter("*", beego.BeforeRouter,authPlugin)
|
|
||||||
package auth
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/base64"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/astaxie/beego"
|
|
||||||
"github.com/astaxie/beego/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
var defaultRealm = "Authorization Required"
|
|
||||||
|
|
||||||
// Basic is the http basic auth
|
|
||||||
func Basic(username string, password string) beego.FilterFunc {
|
|
||||||
secrets := func(user, pass string) bool {
|
|
||||||
return user == username && pass == password
|
|
||||||
}
|
|
||||||
return NewBasicAuthenticator(secrets, defaultRealm)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewBasicAuthenticator return the BasicAuth
|
|
||||||
func NewBasicAuthenticator(secrets SecretProvider, Realm string) beego.FilterFunc {
|
|
||||||
return func(ctx *context.Context) {
|
|
||||||
a := &BasicAuth{Secrets: secrets, Realm: Realm}
|
|
||||||
if username := a.CheckAuth(ctx.Request); username == "" {
|
|
||||||
a.RequireAuth(ctx.ResponseWriter, ctx.Request)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SecretProvider is the SecretProvider function
|
|
||||||
type SecretProvider func(user, pass string) bool
|
|
||||||
|
|
||||||
// BasicAuth store the SecretProvider and Realm
|
|
||||||
type BasicAuth struct {
|
|
||||||
Secrets SecretProvider
|
|
||||||
Realm string
|
|
||||||
}
|
|
||||||
|
|
||||||
// CheckAuth Checks the username/password combination from the request. Returns
|
|
||||||
// either an empty string (authentication failed) or the name of the
|
|
||||||
// authenticated user.
|
|
||||||
// Supports MD5 and SHA1 password entries
|
|
||||||
func (a *BasicAuth) CheckAuth(r *http.Request) string {
|
|
||||||
s := strings.SplitN(r.Header.Get("Authorization"), " ", 2)
|
|
||||||
if len(s) != 2 || s[0] != "Basic" {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
b, err := base64.StdEncoding.DecodeString(s[1])
|
|
||||||
if err != nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
pair := strings.SplitN(string(b), ":", 2)
|
|
||||||
if len(pair) != 2 {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
if a.Secrets(pair[0], pair[1]) {
|
|
||||||
return pair[0]
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// RequireAuth http.Handler for BasicAuth which initiates the authentication process
|
|
||||||
// (or requires reauthentication).
|
|
||||||
func (a *BasicAuth) RequireAuth(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.Header().Set("WWW-Authenticate", `Basic realm="`+a.Realm+`"`)
|
|
||||||
w.WriteHeader(401)
|
|
||||||
w.Write([]byte("401 Unauthorized\n"))
|
|
||||||
}
|
|
226
vendor/github.com/astaxie/beego/plugins/cors/cors.go
generated
vendored
226
vendor/github.com/astaxie/beego/plugins/cors/cors.go
generated
vendored
@ -1,226 +0,0 @@
|
|||||||
// Copyright 2014 beego Author. All Rights Reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
// Package cors provides handlers to enable CORS support.
|
|
||||||
// Usage
|
|
||||||
// import (
|
|
||||||
// "github.com/astaxie/beego"
|
|
||||||
// "github.com/astaxie/beego/plugins/cors"
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// func main() {
|
|
||||||
// // CORS for https://foo.* origins, allowing:
|
|
||||||
// // - PUT and PATCH methods
|
|
||||||
// // - Origin header
|
|
||||||
// // - Credentials share
|
|
||||||
// beego.InsertFilter("*", beego.BeforeRouter, cors.Allow(&cors.Options{
|
|
||||||
// AllowOrigins: []string{"https://*.foo.com"},
|
|
||||||
// AllowMethods: []string{"PUT", "PATCH"},
|
|
||||||
// AllowHeaders: []string{"Origin"},
|
|
||||||
// ExposeHeaders: []string{"Content-Length"},
|
|
||||||
// AllowCredentials: true,
|
|
||||||
// }))
|
|
||||||
// beego.Run()
|
|
||||||
// }
|
|
||||||
package cors
|
|
||||||
|
|
||||||
import (
|
|
||||||
"regexp"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/astaxie/beego"
|
|
||||||
"github.com/astaxie/beego/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
headerAllowOrigin = "Access-Control-Allow-Origin"
|
|
||||||
headerAllowCredentials = "Access-Control-Allow-Credentials"
|
|
||||||
headerAllowHeaders = "Access-Control-Allow-Headers"
|
|
||||||
headerAllowMethods = "Access-Control-Allow-Methods"
|
|
||||||
headerExposeHeaders = "Access-Control-Expose-Headers"
|
|
||||||
headerMaxAge = "Access-Control-Max-Age"
|
|
||||||
|
|
||||||
headerOrigin = "Origin"
|
|
||||||
headerRequestMethod = "Access-Control-Request-Method"
|
|
||||||
headerRequestHeaders = "Access-Control-Request-Headers"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
defaultAllowHeaders = []string{"Origin", "Accept", "Content-Type", "Authorization"}
|
|
||||||
// Regex patterns are generated from AllowOrigins. These are used and generated internally.
|
|
||||||
allowOriginPatterns = []string{}
|
|
||||||
)
|
|
||||||
|
|
||||||
// Options represents Access Control options.
|
|
||||||
type Options struct {
|
|
||||||
// If set, all origins are allowed.
|
|
||||||
AllowAllOrigins bool
|
|
||||||
// A list of allowed origins. Wild cards and FQDNs are supported.
|
|
||||||
AllowOrigins []string
|
|
||||||
// If set, allows to share auth credentials such as cookies.
|
|
||||||
AllowCredentials bool
|
|
||||||
// A list of allowed HTTP methods.
|
|
||||||
AllowMethods []string
|
|
||||||
// A list of allowed HTTP headers.
|
|
||||||
AllowHeaders []string
|
|
||||||
// A list of exposed HTTP headers.
|
|
||||||
ExposeHeaders []string
|
|
||||||
// Max age of the CORS headers.
|
|
||||||
MaxAge time.Duration
|
|
||||||
}
|
|
||||||
|
|
||||||
// Header converts options into CORS headers.
|
|
||||||
func (o *Options) Header(origin string) (headers map[string]string) {
|
|
||||||
headers = make(map[string]string)
|
|
||||||
// if origin is not allowed, don't extend the headers
|
|
||||||
// with CORS headers.
|
|
||||||
if !o.AllowAllOrigins && !o.IsOriginAllowed(origin) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// add allow origin
|
|
||||||
if o.AllowAllOrigins {
|
|
||||||
headers[headerAllowOrigin] = "*"
|
|
||||||
} else {
|
|
||||||
headers[headerAllowOrigin] = origin
|
|
||||||
}
|
|
||||||
|
|
||||||
// add allow credentials
|
|
||||||
headers[headerAllowCredentials] = strconv.FormatBool(o.AllowCredentials)
|
|
||||||
|
|
||||||
// add allow methods
|
|
||||||
if len(o.AllowMethods) > 0 {
|
|
||||||
headers[headerAllowMethods] = strings.Join(o.AllowMethods, ",")
|
|
||||||
}
|
|
||||||
|
|
||||||
// add allow headers
|
|
||||||
if len(o.AllowHeaders) > 0 {
|
|
||||||
headers[headerAllowHeaders] = strings.Join(o.AllowHeaders, ",")
|
|
||||||
}
|
|
||||||
|
|
||||||
// add exposed header
|
|
||||||
if len(o.ExposeHeaders) > 0 {
|
|
||||||
headers[headerExposeHeaders] = strings.Join(o.ExposeHeaders, ",")
|
|
||||||
}
|
|
||||||
// add a max age header
|
|
||||||
if o.MaxAge > time.Duration(0) {
|
|
||||||
headers[headerMaxAge] = strconv.FormatInt(int64(o.MaxAge/time.Second), 10)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// PreflightHeader converts options into CORS headers for a preflight response.
|
|
||||||
func (o *Options) PreflightHeader(origin, rMethod, rHeaders string) (headers map[string]string) {
|
|
||||||
headers = make(map[string]string)
|
|
||||||
if !o.AllowAllOrigins && !o.IsOriginAllowed(origin) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// verify if requested method is allowed
|
|
||||||
for _, method := range o.AllowMethods {
|
|
||||||
if method == rMethod {
|
|
||||||
headers[headerAllowMethods] = strings.Join(o.AllowMethods, ",")
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// verify if requested headers are allowed
|
|
||||||
var allowed []string
|
|
||||||
for _, rHeader := range strings.Split(rHeaders, ",") {
|
|
||||||
rHeader = strings.TrimSpace(rHeader)
|
|
||||||
lookupLoop:
|
|
||||||
for _, allowedHeader := range o.AllowHeaders {
|
|
||||||
if strings.ToLower(rHeader) == strings.ToLower(allowedHeader) {
|
|
||||||
allowed = append(allowed, rHeader)
|
|
||||||
break lookupLoop
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
headers[headerAllowCredentials] = strconv.FormatBool(o.AllowCredentials)
|
|
||||||
// add allow origin
|
|
||||||
if o.AllowAllOrigins {
|
|
||||||
headers[headerAllowOrigin] = "*"
|
|
||||||
} else {
|
|
||||||
headers[headerAllowOrigin] = origin
|
|
||||||
}
|
|
||||||
|
|
||||||
// add allowed headers
|
|
||||||
if len(allowed) > 0 {
|
|
||||||
headers[headerAllowHeaders] = strings.Join(allowed, ",")
|
|
||||||
}
|
|
||||||
|
|
||||||
// add exposed headers
|
|
||||||
if len(o.ExposeHeaders) > 0 {
|
|
||||||
headers[headerExposeHeaders] = strings.Join(o.ExposeHeaders, ",")
|
|
||||||
}
|
|
||||||
// add a max age header
|
|
||||||
if o.MaxAge > time.Duration(0) {
|
|
||||||
headers[headerMaxAge] = strconv.FormatInt(int64(o.MaxAge/time.Second), 10)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsOriginAllowed looks up if the origin matches one of the patterns
|
|
||||||
// generated from Options.AllowOrigins patterns.
|
|
||||||
func (o *Options) IsOriginAllowed(origin string) (allowed bool) {
|
|
||||||
for _, pattern := range allowOriginPatterns {
|
|
||||||
allowed, _ = regexp.MatchString(pattern, origin)
|
|
||||||
if allowed {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allow enables CORS for requests those match the provided options.
|
|
||||||
func Allow(opts *Options) beego.FilterFunc {
|
|
||||||
// Allow default headers if nothing is specified.
|
|
||||||
if len(opts.AllowHeaders) == 0 {
|
|
||||||
opts.AllowHeaders = defaultAllowHeaders
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, origin := range opts.AllowOrigins {
|
|
||||||
pattern := regexp.QuoteMeta(origin)
|
|
||||||
pattern = strings.Replace(pattern, "\\*", ".*", -1)
|
|
||||||
pattern = strings.Replace(pattern, "\\?", ".", -1)
|
|
||||||
allowOriginPatterns = append(allowOriginPatterns, "^"+pattern+"$")
|
|
||||||
}
|
|
||||||
|
|
||||||
return func(ctx *context.Context) {
|
|
||||||
var (
|
|
||||||
origin = ctx.Input.Header(headerOrigin)
|
|
||||||
requestedMethod = ctx.Input.Header(headerRequestMethod)
|
|
||||||
requestedHeaders = ctx.Input.Header(headerRequestHeaders)
|
|
||||||
// additional headers to be added
|
|
||||||
// to the response.
|
|
||||||
headers map[string]string
|
|
||||||
)
|
|
||||||
|
|
||||||
if ctx.Input.Method() == "OPTIONS" &&
|
|
||||||
(requestedMethod != "" || requestedHeaders != "") {
|
|
||||||
headers = opts.PreflightHeader(origin, requestedMethod, requestedHeaders)
|
|
||||||
for key, value := range headers {
|
|
||||||
ctx.Output.Header(key, value)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
headers = opts.Header(origin)
|
|
||||||
|
|
||||||
for key, value := range headers {
|
|
||||||
ctx.Output.Header(key, value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
7
vendor/github.com/astaxie/beego/router.go
generated
vendored
7
vendor/github.com/astaxie/beego/router.go
generated
vendored
@ -62,12 +62,12 @@ var (
|
|||||||
}
|
}
|
||||||
// these beego.Controller's methods shouldn't reflect to AutoRouter
|
// these beego.Controller's methods shouldn't reflect to AutoRouter
|
||||||
exceptMethod = []string{"Init", "Prepare", "Finish", "Render", "RenderString",
|
exceptMethod = []string{"Init", "Prepare", "Finish", "Render", "RenderString",
|
||||||
"RenderBytes", "Redirect", "Abort", "StopRun", "UrlFor", "ServeJson", "ServeJsonp",
|
"RenderBytes", "Redirect", "Abort", "StopRun", "UrlFor", "ServeJSON", "ServeJSONP",
|
||||||
"ServeXml", "Input", "ParseForm", "GetString", "GetStrings", "GetInt", "GetBool",
|
"ServeXML", "Input", "ParseForm", "GetString", "GetStrings", "GetInt", "GetBool",
|
||||||
"GetFloat", "GetFile", "SaveToFile", "StartSession", "SetSession", "GetSession",
|
"GetFloat", "GetFile", "SaveToFile", "StartSession", "SetSession", "GetSession",
|
||||||
"DelSession", "SessionRegenerateID", "DestroySession", "IsAjax", "GetSecureCookie",
|
"DelSession", "SessionRegenerateID", "DestroySession", "IsAjax", "GetSecureCookie",
|
||||||
"SetSecureCookie", "XsrfToken", "CheckXsrfCookie", "XsrfFormHtml",
|
"SetSecureCookie", "XsrfToken", "CheckXsrfCookie", "XsrfFormHtml",
|
||||||
"GetControllerAndAction"}
|
"GetControllerAndAction", "ServeFormatted"}
|
||||||
|
|
||||||
urlPlaceholder = "{{placeholder}}"
|
urlPlaceholder = "{{placeholder}}"
|
||||||
// DefaultAccessLogFilter will skip the accesslog if return true
|
// DefaultAccessLogFilter will skip the accesslog if return true
|
||||||
@ -607,6 +607,7 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request)
|
|||||||
)
|
)
|
||||||
context := p.pool.Get().(*beecontext.Context)
|
context := p.pool.Get().(*beecontext.Context)
|
||||||
context.Reset(rw, r)
|
context.Reset(rw, r)
|
||||||
|
|
||||||
defer p.pool.Put(context)
|
defer p.pool.Put(context)
|
||||||
defer p.recoverPanic(context)
|
defer p.recoverPanic(context)
|
||||||
|
|
||||||
|
243
vendor/github.com/astaxie/beego/session/couchbase/sess_couchbase.go
generated
vendored
243
vendor/github.com/astaxie/beego/session/couchbase/sess_couchbase.go
generated
vendored
@ -1,243 +0,0 @@
|
|||||||
// Copyright 2014 beego Author. All Rights Reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
// Package couchbase for session provider
|
|
||||||
//
|
|
||||||
// depend on github.com/couchbaselabs/go-couchbasee
|
|
||||||
//
|
|
||||||
// go install github.com/couchbaselabs/go-couchbase
|
|
||||||
//
|
|
||||||
// Usage:
|
|
||||||
// import(
|
|
||||||
// _ "github.com/astaxie/beego/session/couchbase"
|
|
||||||
// "github.com/astaxie/beego/session"
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// func init() {
|
|
||||||
// globalSessions, _ = session.NewManager("couchbase", ``{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"http://host:port/, Pool, Bucket"}``)
|
|
||||||
// go globalSessions.GC()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// more docs: http://beego.me/docs/module/session.md
|
|
||||||
package couchbase
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
couchbase "github.com/couchbase/go-couchbase"
|
|
||||||
|
|
||||||
"github.com/astaxie/beego/session"
|
|
||||||
)
|
|
||||||
|
|
||||||
var couchbpder = &Provider{}
|
|
||||||
|
|
||||||
// SessionStore store each session
|
|
||||||
type SessionStore struct {
|
|
||||||
b *couchbase.Bucket
|
|
||||||
sid string
|
|
||||||
lock sync.RWMutex
|
|
||||||
values map[interface{}]interface{}
|
|
||||||
maxlifetime int64
|
|
||||||
}
|
|
||||||
|
|
||||||
// Provider couchabse provided
|
|
||||||
type Provider struct {
|
|
||||||
maxlifetime int64
|
|
||||||
savePath string
|
|
||||||
pool string
|
|
||||||
bucket string
|
|
||||||
b *couchbase.Bucket
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set value to couchabse session
|
|
||||||
func (cs *SessionStore) Set(key, value interface{}) error {
|
|
||||||
cs.lock.Lock()
|
|
||||||
defer cs.lock.Unlock()
|
|
||||||
cs.values[key] = value
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get value from couchabse session
|
|
||||||
func (cs *SessionStore) Get(key interface{}) interface{} {
|
|
||||||
cs.lock.RLock()
|
|
||||||
defer cs.lock.RUnlock()
|
|
||||||
if v, ok := cs.values[key]; ok {
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete value in couchbase session by given key
|
|
||||||
func (cs *SessionStore) Delete(key interface{}) error {
|
|
||||||
cs.lock.Lock()
|
|
||||||
defer cs.lock.Unlock()
|
|
||||||
delete(cs.values, key)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flush Clean all values in couchbase session
|
|
||||||
func (cs *SessionStore) Flush() error {
|
|
||||||
cs.lock.Lock()
|
|
||||||
defer cs.lock.Unlock()
|
|
||||||
cs.values = make(map[interface{}]interface{})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionID Get couchbase session store id
|
|
||||||
func (cs *SessionStore) SessionID() string {
|
|
||||||
return cs.sid
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionRelease Write couchbase session with Gob string
|
|
||||||
func (cs *SessionStore) SessionRelease(w http.ResponseWriter) {
|
|
||||||
defer cs.b.Close()
|
|
||||||
|
|
||||||
bo, err := session.EncodeGob(cs.values)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
cs.b.Set(cs.sid, int(cs.maxlifetime), bo)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cp *Provider) getBucket() *couchbase.Bucket {
|
|
||||||
c, err := couchbase.Connect(cp.savePath)
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
pool, err := c.GetPool(cp.pool)
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
bucket, err := pool.GetBucket(cp.bucket)
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return bucket
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionInit init couchbase session
|
|
||||||
// savepath like couchbase server REST/JSON URL
|
|
||||||
// e.g. http://host:port/, Pool, Bucket
|
|
||||||
func (cp *Provider) SessionInit(maxlifetime int64, savePath string) error {
|
|
||||||
cp.maxlifetime = maxlifetime
|
|
||||||
configs := strings.Split(savePath, ",")
|
|
||||||
if len(configs) > 0 {
|
|
||||||
cp.savePath = configs[0]
|
|
||||||
}
|
|
||||||
if len(configs) > 1 {
|
|
||||||
cp.pool = configs[1]
|
|
||||||
}
|
|
||||||
if len(configs) > 2 {
|
|
||||||
cp.bucket = configs[2]
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionRead read couchbase session by sid
|
|
||||||
func (cp *Provider) SessionRead(sid string) (session.Store, error) {
|
|
||||||
cp.b = cp.getBucket()
|
|
||||||
|
|
||||||
var doc []byte
|
|
||||||
|
|
||||||
err := cp.b.Get(sid, &doc)
|
|
||||||
var kv map[interface{}]interface{}
|
|
||||||
if doc == nil {
|
|
||||||
kv = make(map[interface{}]interface{})
|
|
||||||
} else {
|
|
||||||
kv, err = session.DecodeGob(doc)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cs := &SessionStore{b: cp.b, sid: sid, values: kv, maxlifetime: cp.maxlifetime}
|
|
||||||
return cs, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionExist Check couchbase session exist.
|
|
||||||
// it checkes sid exist or not.
|
|
||||||
func (cp *Provider) SessionExist(sid string) bool {
|
|
||||||
cp.b = cp.getBucket()
|
|
||||||
defer cp.b.Close()
|
|
||||||
|
|
||||||
var doc []byte
|
|
||||||
|
|
||||||
if err := cp.b.Get(sid, &doc); err != nil || doc == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionRegenerate remove oldsid and use sid to generate new session
|
|
||||||
func (cp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error) {
|
|
||||||
cp.b = cp.getBucket()
|
|
||||||
|
|
||||||
var doc []byte
|
|
||||||
if err := cp.b.Get(oldsid, &doc); err != nil || doc == nil {
|
|
||||||
cp.b.Set(sid, int(cp.maxlifetime), "")
|
|
||||||
} else {
|
|
||||||
err := cp.b.Delete(oldsid)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
_, _ = cp.b.Add(sid, int(cp.maxlifetime), doc)
|
|
||||||
}
|
|
||||||
|
|
||||||
err := cp.b.Get(sid, &doc)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
var kv map[interface{}]interface{}
|
|
||||||
if doc == nil {
|
|
||||||
kv = make(map[interface{}]interface{})
|
|
||||||
} else {
|
|
||||||
kv, err = session.DecodeGob(doc)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cs := &SessionStore{b: cp.b, sid: sid, values: kv, maxlifetime: cp.maxlifetime}
|
|
||||||
return cs, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionDestroy Remove bucket in this couchbase
|
|
||||||
func (cp *Provider) SessionDestroy(sid string) error {
|
|
||||||
cp.b = cp.getBucket()
|
|
||||||
defer cp.b.Close()
|
|
||||||
|
|
||||||
cp.b.Delete(sid)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionGC Recycle
|
|
||||||
func (cp *Provider) SessionGC() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionAll return all active session
|
|
||||||
func (cp *Provider) SessionAll() int {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
session.Register("couchbase", couchbpder)
|
|
||||||
}
|
|
179
vendor/github.com/astaxie/beego/session/ledis/ledis_session.go
generated
vendored
179
vendor/github.com/astaxie/beego/session/ledis/ledis_session.go
generated
vendored
@ -1,179 +0,0 @@
|
|||||||
// Package ledis provide session Provider
|
|
||||||
package ledis
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/astaxie/beego/session"
|
|
||||||
"github.com/siddontang/ledisdb/config"
|
|
||||||
"github.com/siddontang/ledisdb/ledis"
|
|
||||||
)
|
|
||||||
|
|
||||||
var ledispder = &Provider{}
|
|
||||||
var c *ledis.DB
|
|
||||||
|
|
||||||
// SessionStore ledis session store
|
|
||||||
type SessionStore struct {
|
|
||||||
sid string
|
|
||||||
lock sync.RWMutex
|
|
||||||
values map[interface{}]interface{}
|
|
||||||
maxlifetime int64
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set value in ledis session
|
|
||||||
func (ls *SessionStore) Set(key, value interface{}) error {
|
|
||||||
ls.lock.Lock()
|
|
||||||
defer ls.lock.Unlock()
|
|
||||||
ls.values[key] = value
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get value in ledis session
|
|
||||||
func (ls *SessionStore) Get(key interface{}) interface{} {
|
|
||||||
ls.lock.RLock()
|
|
||||||
defer ls.lock.RUnlock()
|
|
||||||
if v, ok := ls.values[key]; ok {
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete value in ledis session
|
|
||||||
func (ls *SessionStore) Delete(key interface{}) error {
|
|
||||||
ls.lock.Lock()
|
|
||||||
defer ls.lock.Unlock()
|
|
||||||
delete(ls.values, key)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flush clear all values in ledis session
|
|
||||||
func (ls *SessionStore) Flush() error {
|
|
||||||
ls.lock.Lock()
|
|
||||||
defer ls.lock.Unlock()
|
|
||||||
ls.values = make(map[interface{}]interface{})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionID get ledis session id
|
|
||||||
func (ls *SessionStore) SessionID() string {
|
|
||||||
return ls.sid
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionRelease save session values to ledis
|
|
||||||
func (ls *SessionStore) SessionRelease(w http.ResponseWriter) {
|
|
||||||
b, err := session.EncodeGob(ls.values)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.Set([]byte(ls.sid), b)
|
|
||||||
c.Expire([]byte(ls.sid), ls.maxlifetime)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Provider ledis session provider
|
|
||||||
type Provider struct {
|
|
||||||
maxlifetime int64
|
|
||||||
savePath string
|
|
||||||
db int
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionInit init ledis session
|
|
||||||
// savepath like ledis server saveDataPath,pool size
|
|
||||||
// e.g. 127.0.0.1:6379,100,astaxie
|
|
||||||
func (lp *Provider) SessionInit(maxlifetime int64, savePath string) error {
|
|
||||||
var err error
|
|
||||||
lp.maxlifetime = maxlifetime
|
|
||||||
configs := strings.Split(savePath, ",")
|
|
||||||
if len(configs) == 1 {
|
|
||||||
lp.savePath = configs[0]
|
|
||||||
} else if len(configs) == 2 {
|
|
||||||
lp.savePath = configs[0]
|
|
||||||
lp.db, err = strconv.Atoi(configs[1])
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cfg := new(config.Config)
|
|
||||||
cfg.DataDir = lp.savePath
|
|
||||||
nowLedis, err := ledis.Open(cfg)
|
|
||||||
c, err = nowLedis.Select(lp.db)
|
|
||||||
if err != nil {
|
|
||||||
println(err)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionRead read ledis session by sid
|
|
||||||
func (lp *Provider) SessionRead(sid string) (session.Store, error) {
|
|
||||||
kvs, err := c.Get([]byte(sid))
|
|
||||||
var kv map[interface{}]interface{}
|
|
||||||
if len(kvs) == 0 {
|
|
||||||
kv = make(map[interface{}]interface{})
|
|
||||||
} else {
|
|
||||||
kv, err = session.DecodeGob(kvs)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ls := &SessionStore{sid: sid, values: kv, maxlifetime: lp.maxlifetime}
|
|
||||||
return ls, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionExist check ledis session exist by sid
|
|
||||||
func (lp *Provider) SessionExist(sid string) bool {
|
|
||||||
count, _ := c.Exists([]byte(sid))
|
|
||||||
if count == 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionRegenerate generate new sid for ledis session
|
|
||||||
func (lp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error) {
|
|
||||||
count, _ := c.Exists([]byte(sid))
|
|
||||||
if count == 0 {
|
|
||||||
// oldsid doesn't exists, set the new sid directly
|
|
||||||
// ignore error here, since if it return error
|
|
||||||
// the existed value will be 0
|
|
||||||
c.Set([]byte(sid), []byte(""))
|
|
||||||
c.Expire([]byte(sid), lp.maxlifetime)
|
|
||||||
} else {
|
|
||||||
data, _ := c.Get([]byte(oldsid))
|
|
||||||
c.Set([]byte(sid), data)
|
|
||||||
c.Expire([]byte(sid), lp.maxlifetime)
|
|
||||||
}
|
|
||||||
kvs, err := c.Get([]byte(sid))
|
|
||||||
var kv map[interface{}]interface{}
|
|
||||||
if len(kvs) == 0 {
|
|
||||||
kv = make(map[interface{}]interface{})
|
|
||||||
} else {
|
|
||||||
kv, err = session.DecodeGob([]byte(kvs))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ls := &SessionStore{sid: sid, values: kv, maxlifetime: lp.maxlifetime}
|
|
||||||
return ls, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionDestroy delete ledis session by id
|
|
||||||
func (lp *Provider) SessionDestroy(sid string) error {
|
|
||||||
c.Del([]byte(sid))
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionGC Impelment method, no used.
|
|
||||||
func (lp *Provider) SessionGC() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionAll return all active session
|
|
||||||
func (lp *Provider) SessionAll() int {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
func init() {
|
|
||||||
session.Register("ledis", ledispder)
|
|
||||||
}
|
|
232
vendor/github.com/astaxie/beego/session/memcache/sess_memcache.go
generated
vendored
232
vendor/github.com/astaxie/beego/session/memcache/sess_memcache.go
generated
vendored
@ -1,232 +0,0 @@
|
|||||||
// Copyright 2014 beego Author. All Rights Reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
// Package memcache for session provider
|
|
||||||
//
|
|
||||||
// depend on github.com/bradfitz/gomemcache/memcache
|
|
||||||
//
|
|
||||||
// go install github.com/bradfitz/gomemcache/memcache
|
|
||||||
//
|
|
||||||
// Usage:
|
|
||||||
// import(
|
|
||||||
// _ "github.com/astaxie/beego/session/memcache"
|
|
||||||
// "github.com/astaxie/beego/session"
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// func init() {
|
|
||||||
// globalSessions, _ = session.NewManager("memcache", ``{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"127.0.0.1:11211"}``)
|
|
||||||
// go globalSessions.GC()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// more docs: http://beego.me/docs/module/session.md
|
|
||||||
package memcache
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/astaxie/beego/session"
|
|
||||||
|
|
||||||
"github.com/bradfitz/gomemcache/memcache"
|
|
||||||
)
|
|
||||||
|
|
||||||
var mempder = &MemProvider{}
|
|
||||||
var client *memcache.Client
|
|
||||||
|
|
||||||
// SessionStore memcache session store
|
|
||||||
type SessionStore struct {
|
|
||||||
sid string
|
|
||||||
lock sync.RWMutex
|
|
||||||
values map[interface{}]interface{}
|
|
||||||
maxlifetime int64
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set value in memcache session
|
|
||||||
func (rs *SessionStore) Set(key, value interface{}) error {
|
|
||||||
rs.lock.Lock()
|
|
||||||
defer rs.lock.Unlock()
|
|
||||||
rs.values[key] = value
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get value in memcache session
|
|
||||||
func (rs *SessionStore) Get(key interface{}) interface{} {
|
|
||||||
rs.lock.RLock()
|
|
||||||
defer rs.lock.RUnlock()
|
|
||||||
if v, ok := rs.values[key]; ok {
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete value in memcache session
|
|
||||||
func (rs *SessionStore) Delete(key interface{}) error {
|
|
||||||
rs.lock.Lock()
|
|
||||||
defer rs.lock.Unlock()
|
|
||||||
delete(rs.values, key)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flush clear all values in memcache session
|
|
||||||
func (rs *SessionStore) Flush() error {
|
|
||||||
rs.lock.Lock()
|
|
||||||
defer rs.lock.Unlock()
|
|
||||||
rs.values = make(map[interface{}]interface{})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionID get memcache session id
|
|
||||||
func (rs *SessionStore) SessionID() string {
|
|
||||||
return rs.sid
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionRelease save session values to memcache
|
|
||||||
func (rs *SessionStore) SessionRelease(w http.ResponseWriter) {
|
|
||||||
b, err := session.EncodeGob(rs.values)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
item := memcache.Item{Key: rs.sid, Value: b, Expiration: int32(rs.maxlifetime)}
|
|
||||||
client.Set(&item)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MemProvider memcache session provider
|
|
||||||
type MemProvider struct {
|
|
||||||
maxlifetime int64
|
|
||||||
conninfo []string
|
|
||||||
poolsize int
|
|
||||||
password string
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionInit init memcache session
|
|
||||||
// savepath like
|
|
||||||
// e.g. 127.0.0.1:9090
|
|
||||||
func (rp *MemProvider) SessionInit(maxlifetime int64, savePath string) error {
|
|
||||||
rp.maxlifetime = maxlifetime
|
|
||||||
rp.conninfo = strings.Split(savePath, ";")
|
|
||||||
client = memcache.New(rp.conninfo...)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionRead read memcache session by sid
|
|
||||||
func (rp *MemProvider) SessionRead(sid string) (session.Store, error) {
|
|
||||||
if client == nil {
|
|
||||||
if err := rp.connectInit(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
item, err := client.Get(sid)
|
|
||||||
if err != nil && err == memcache.ErrCacheMiss {
|
|
||||||
rs := &SessionStore{sid: sid, values: make(map[interface{}]interface{}), maxlifetime: rp.maxlifetime}
|
|
||||||
return rs, nil
|
|
||||||
}
|
|
||||||
var kv map[interface{}]interface{}
|
|
||||||
if len(item.Value) == 0 {
|
|
||||||
kv = make(map[interface{}]interface{})
|
|
||||||
} else {
|
|
||||||
kv, err = session.DecodeGob(item.Value)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rs := &SessionStore{sid: sid, values: kv, maxlifetime: rp.maxlifetime}
|
|
||||||
return rs, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionExist check memcache session exist by sid
|
|
||||||
func (rp *MemProvider) SessionExist(sid string) bool {
|
|
||||||
if client == nil {
|
|
||||||
if err := rp.connectInit(); err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if item, err := client.Get(sid); err != nil || len(item.Value) == 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionRegenerate generate new sid for memcache session
|
|
||||||
func (rp *MemProvider) SessionRegenerate(oldsid, sid string) (session.Store, error) {
|
|
||||||
if client == nil {
|
|
||||||
if err := rp.connectInit(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var contain []byte
|
|
||||||
if item, err := client.Get(sid); err != nil || len(item.Value) == 0 {
|
|
||||||
// oldsid doesn't exists, set the new sid directly
|
|
||||||
// ignore error here, since if it return error
|
|
||||||
// the existed value will be 0
|
|
||||||
item.Key = sid
|
|
||||||
item.Value = []byte("")
|
|
||||||
item.Expiration = int32(rp.maxlifetime)
|
|
||||||
client.Set(item)
|
|
||||||
} else {
|
|
||||||
client.Delete(oldsid)
|
|
||||||
item.Key = sid
|
|
||||||
item.Expiration = int32(rp.maxlifetime)
|
|
||||||
client.Set(item)
|
|
||||||
contain = item.Value
|
|
||||||
}
|
|
||||||
|
|
||||||
var kv map[interface{}]interface{}
|
|
||||||
if len(contain) == 0 {
|
|
||||||
kv = make(map[interface{}]interface{})
|
|
||||||
} else {
|
|
||||||
var err error
|
|
||||||
kv, err = session.DecodeGob(contain)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rs := &SessionStore{sid: sid, values: kv, maxlifetime: rp.maxlifetime}
|
|
||||||
return rs, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionDestroy delete memcache session by id
|
|
||||||
func (rp *MemProvider) SessionDestroy(sid string) error {
|
|
||||||
if client == nil {
|
|
||||||
if err := rp.connectInit(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.Delete(sid)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rp *MemProvider) connectInit() error {
|
|
||||||
client = memcache.New(rp.conninfo...)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionGC Impelment method, no used.
|
|
||||||
func (rp *MemProvider) SessionGC() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionAll return all activeSession
|
|
||||||
func (rp *MemProvider) SessionAll() int {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
session.Register("memcache", mempder)
|
|
||||||
}
|
|
233
vendor/github.com/astaxie/beego/session/mysql/sess_mysql.go
generated
vendored
233
vendor/github.com/astaxie/beego/session/mysql/sess_mysql.go
generated
vendored
@ -1,233 +0,0 @@
|
|||||||
// Copyright 2014 beego Author. All Rights Reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
// Package mysql for session provider
|
|
||||||
//
|
|
||||||
// depends on github.com/go-sql-driver/mysql:
|
|
||||||
//
|
|
||||||
// go install github.com/go-sql-driver/mysql
|
|
||||||
//
|
|
||||||
// mysql session support need create table as sql:
|
|
||||||
// CREATE TABLE `session` (
|
|
||||||
// `session_key` char(64) NOT NULL,
|
|
||||||
// `session_data` blob,
|
|
||||||
// `session_expiry` int(11) unsigned NOT NULL,
|
|
||||||
// PRIMARY KEY (`session_key`)
|
|
||||||
// ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
|
||||||
//
|
|
||||||
// Usage:
|
|
||||||
// import(
|
|
||||||
// _ "github.com/astaxie/beego/session/mysql"
|
|
||||||
// "github.com/astaxie/beego/session"
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// func init() {
|
|
||||||
// globalSessions, _ = session.NewManager("mysql", ``{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"[username[:password]@][protocol[(address)]]/dbname[?param1=value1&...¶mN=valueN]"}``)
|
|
||||||
// go globalSessions.GC()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// more docs: http://beego.me/docs/module/session.md
|
|
||||||
package mysql
|
|
||||||
|
|
||||||
import (
|
|
||||||
"database/sql"
|
|
||||||
"net/http"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/astaxie/beego/session"
|
|
||||||
// import mysql driver
|
|
||||||
_ "github.com/go-sql-driver/mysql"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// TableName store the session in MySQL
|
|
||||||
TableName = "session"
|
|
||||||
mysqlpder = &Provider{}
|
|
||||||
)
|
|
||||||
|
|
||||||
// SessionStore mysql session store
|
|
||||||
type SessionStore struct {
|
|
||||||
c *sql.DB
|
|
||||||
sid string
|
|
||||||
lock sync.RWMutex
|
|
||||||
values map[interface{}]interface{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set value in mysql session.
|
|
||||||
// it is temp value in map.
|
|
||||||
func (st *SessionStore) Set(key, value interface{}) error {
|
|
||||||
st.lock.Lock()
|
|
||||||
defer st.lock.Unlock()
|
|
||||||
st.values[key] = value
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get value from mysql session
|
|
||||||
func (st *SessionStore) Get(key interface{}) interface{} {
|
|
||||||
st.lock.RLock()
|
|
||||||
defer st.lock.RUnlock()
|
|
||||||
if v, ok := st.values[key]; ok {
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete value in mysql session
|
|
||||||
func (st *SessionStore) Delete(key interface{}) error {
|
|
||||||
st.lock.Lock()
|
|
||||||
defer st.lock.Unlock()
|
|
||||||
delete(st.values, key)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flush clear all values in mysql session
|
|
||||||
func (st *SessionStore) Flush() error {
|
|
||||||
st.lock.Lock()
|
|
||||||
defer st.lock.Unlock()
|
|
||||||
st.values = make(map[interface{}]interface{})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionID get session id of this mysql session store
|
|
||||||
func (st *SessionStore) SessionID() string {
|
|
||||||
return st.sid
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionRelease save mysql session values to database.
|
|
||||||
// must call this method to save values to database.
|
|
||||||
func (st *SessionStore) SessionRelease(w http.ResponseWriter) {
|
|
||||||
defer st.c.Close()
|
|
||||||
b, err := session.EncodeGob(st.values)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
st.c.Exec("UPDATE "+TableName+" set `session_data`=?, `session_expiry`=? where session_key=?",
|
|
||||||
b, time.Now().Unix(), st.sid)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Provider mysql session provider
|
|
||||||
type Provider struct {
|
|
||||||
maxlifetime int64
|
|
||||||
savePath string
|
|
||||||
}
|
|
||||||
|
|
||||||
// connect to mysql
|
|
||||||
func (mp *Provider) connectInit() *sql.DB {
|
|
||||||
db, e := sql.Open("mysql", mp.savePath)
|
|
||||||
if e != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return db
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionInit init mysql session.
|
|
||||||
// savepath is the connection string of mysql.
|
|
||||||
func (mp *Provider) SessionInit(maxlifetime int64, savePath string) error {
|
|
||||||
mp.maxlifetime = maxlifetime
|
|
||||||
mp.savePath = savePath
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionRead get mysql session by sid
|
|
||||||
func (mp *Provider) SessionRead(sid string) (session.Store, error) {
|
|
||||||
c := mp.connectInit()
|
|
||||||
row := c.QueryRow("select session_data from "+TableName+" where session_key=?", sid)
|
|
||||||
var sessiondata []byte
|
|
||||||
err := row.Scan(&sessiondata)
|
|
||||||
if err == sql.ErrNoRows {
|
|
||||||
c.Exec("insert into "+TableName+"(`session_key`,`session_data`,`session_expiry`) values(?,?,?)",
|
|
||||||
sid, "", time.Now().Unix())
|
|
||||||
}
|
|
||||||
var kv map[interface{}]interface{}
|
|
||||||
if len(sessiondata) == 0 {
|
|
||||||
kv = make(map[interface{}]interface{})
|
|
||||||
} else {
|
|
||||||
kv, err = session.DecodeGob(sessiondata)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rs := &SessionStore{c: c, sid: sid, values: kv}
|
|
||||||
return rs, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionExist check mysql session exist
|
|
||||||
func (mp *Provider) SessionExist(sid string) bool {
|
|
||||||
c := mp.connectInit()
|
|
||||||
defer c.Close()
|
|
||||||
row := c.QueryRow("select session_data from "+TableName+" where session_key=?", sid)
|
|
||||||
var sessiondata []byte
|
|
||||||
err := row.Scan(&sessiondata)
|
|
||||||
if err == sql.ErrNoRows {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionRegenerate generate new sid for mysql session
|
|
||||||
func (mp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error) {
|
|
||||||
c := mp.connectInit()
|
|
||||||
row := c.QueryRow("select session_data from "+TableName+" where session_key=?", oldsid)
|
|
||||||
var sessiondata []byte
|
|
||||||
err := row.Scan(&sessiondata)
|
|
||||||
if err == sql.ErrNoRows {
|
|
||||||
c.Exec("insert into "+TableName+"(`session_key`,`session_data`,`session_expiry`) values(?,?,?)", oldsid, "", time.Now().Unix())
|
|
||||||
}
|
|
||||||
c.Exec("update "+TableName+" set `session_key`=? where session_key=?", sid, oldsid)
|
|
||||||
var kv map[interface{}]interface{}
|
|
||||||
if len(sessiondata) == 0 {
|
|
||||||
kv = make(map[interface{}]interface{})
|
|
||||||
} else {
|
|
||||||
kv, err = session.DecodeGob(sessiondata)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rs := &SessionStore{c: c, sid: sid, values: kv}
|
|
||||||
return rs, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionDestroy delete mysql session by sid
|
|
||||||
func (mp *Provider) SessionDestroy(sid string) error {
|
|
||||||
c := mp.connectInit()
|
|
||||||
c.Exec("DELETE FROM "+TableName+" where session_key=?", sid)
|
|
||||||
c.Close()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionGC delete expired values in mysql session
|
|
||||||
func (mp *Provider) SessionGC() {
|
|
||||||
c := mp.connectInit()
|
|
||||||
c.Exec("DELETE from "+TableName+" where session_expiry < ?", time.Now().Unix()-mp.maxlifetime)
|
|
||||||
c.Close()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionAll count values in mysql session
|
|
||||||
func (mp *Provider) SessionAll() int {
|
|
||||||
c := mp.connectInit()
|
|
||||||
defer c.Close()
|
|
||||||
var total int
|
|
||||||
err := c.QueryRow("SELECT count(*) as num from " + TableName).Scan(&total)
|
|
||||||
if err != nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return total
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
session.Register("mysql", mysqlpder)
|
|
||||||
}
|
|
248
vendor/github.com/astaxie/beego/session/postgres/sess_postgresql.go
generated
vendored
248
vendor/github.com/astaxie/beego/session/postgres/sess_postgresql.go
generated
vendored
@ -1,248 +0,0 @@
|
|||||||
// Copyright 2014 beego Author. All Rights Reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
// Package postgres for session provider
|
|
||||||
//
|
|
||||||
// depends on github.com/lib/pq:
|
|
||||||
//
|
|
||||||
// go install github.com/lib/pq
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// needs this table in your database:
|
|
||||||
//
|
|
||||||
// CREATE TABLE session (
|
|
||||||
// session_key char(64) NOT NULL,
|
|
||||||
// session_data bytea,
|
|
||||||
// session_expiry timestamp NOT NULL,
|
|
||||||
// CONSTRAINT session_key PRIMARY KEY(session_key)
|
|
||||||
// );
|
|
||||||
//
|
|
||||||
// will be activated with these settings in app.conf:
|
|
||||||
//
|
|
||||||
// SessionOn = true
|
|
||||||
// SessionProvider = postgresql
|
|
||||||
// SessionSavePath = "user=a password=b dbname=c sslmode=disable"
|
|
||||||
// SessionName = session
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Usage:
|
|
||||||
// import(
|
|
||||||
// _ "github.com/astaxie/beego/session/postgresql"
|
|
||||||
// "github.com/astaxie/beego/session"
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// func init() {
|
|
||||||
// globalSessions, _ = session.NewManager("postgresql", ``{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"user=pqgotest dbname=pqgotest sslmode=verify-full"}``)
|
|
||||||
// go globalSessions.GC()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// more docs: http://beego.me/docs/module/session.md
|
|
||||||
package postgres
|
|
||||||
|
|
||||||
import (
|
|
||||||
"database/sql"
|
|
||||||
"net/http"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/astaxie/beego/session"
|
|
||||||
// import postgresql Driver
|
|
||||||
_ "github.com/lib/pq"
|
|
||||||
)
|
|
||||||
|
|
||||||
var postgresqlpder = &Provider{}
|
|
||||||
|
|
||||||
// SessionStore postgresql session store
|
|
||||||
type SessionStore struct {
|
|
||||||
c *sql.DB
|
|
||||||
sid string
|
|
||||||
lock sync.RWMutex
|
|
||||||
values map[interface{}]interface{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set value in postgresql session.
|
|
||||||
// it is temp value in map.
|
|
||||||
func (st *SessionStore) Set(key, value interface{}) error {
|
|
||||||
st.lock.Lock()
|
|
||||||
defer st.lock.Unlock()
|
|
||||||
st.values[key] = value
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get value from postgresql session
|
|
||||||
func (st *SessionStore) Get(key interface{}) interface{} {
|
|
||||||
st.lock.RLock()
|
|
||||||
defer st.lock.RUnlock()
|
|
||||||
if v, ok := st.values[key]; ok {
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete value in postgresql session
|
|
||||||
func (st *SessionStore) Delete(key interface{}) error {
|
|
||||||
st.lock.Lock()
|
|
||||||
defer st.lock.Unlock()
|
|
||||||
delete(st.values, key)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flush clear all values in postgresql session
|
|
||||||
func (st *SessionStore) Flush() error {
|
|
||||||
st.lock.Lock()
|
|
||||||
defer st.lock.Unlock()
|
|
||||||
st.values = make(map[interface{}]interface{})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionID get session id of this postgresql session store
|
|
||||||
func (st *SessionStore) SessionID() string {
|
|
||||||
return st.sid
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionRelease save postgresql session values to database.
|
|
||||||
// must call this method to save values to database.
|
|
||||||
func (st *SessionStore) SessionRelease(w http.ResponseWriter) {
|
|
||||||
defer st.c.Close()
|
|
||||||
b, err := session.EncodeGob(st.values)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
st.c.Exec("UPDATE session set session_data=$1, session_expiry=$2 where session_key=$3",
|
|
||||||
b, time.Now().Format(time.RFC3339), st.sid)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Provider postgresql session provider
|
|
||||||
type Provider struct {
|
|
||||||
maxlifetime int64
|
|
||||||
savePath string
|
|
||||||
}
|
|
||||||
|
|
||||||
// connect to postgresql
|
|
||||||
func (mp *Provider) connectInit() *sql.DB {
|
|
||||||
db, e := sql.Open("postgres", mp.savePath)
|
|
||||||
if e != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return db
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionInit init postgresql session.
|
|
||||||
// savepath is the connection string of postgresql.
|
|
||||||
func (mp *Provider) SessionInit(maxlifetime int64, savePath string) error {
|
|
||||||
mp.maxlifetime = maxlifetime
|
|
||||||
mp.savePath = savePath
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionRead get postgresql session by sid
|
|
||||||
func (mp *Provider) SessionRead(sid string) (session.Store, error) {
|
|
||||||
c := mp.connectInit()
|
|
||||||
row := c.QueryRow("select session_data from session where session_key=$1", sid)
|
|
||||||
var sessiondata []byte
|
|
||||||
err := row.Scan(&sessiondata)
|
|
||||||
if err == sql.ErrNoRows {
|
|
||||||
_, err = c.Exec("insert into session(session_key,session_data,session_expiry) values($1,$2,$3)",
|
|
||||||
sid, "", time.Now().Format(time.RFC3339))
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
} else if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var kv map[interface{}]interface{}
|
|
||||||
if len(sessiondata) == 0 {
|
|
||||||
kv = make(map[interface{}]interface{})
|
|
||||||
} else {
|
|
||||||
kv, err = session.DecodeGob(sessiondata)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rs := &SessionStore{c: c, sid: sid, values: kv}
|
|
||||||
return rs, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionExist check postgresql session exist
|
|
||||||
func (mp *Provider) SessionExist(sid string) bool {
|
|
||||||
c := mp.connectInit()
|
|
||||||
defer c.Close()
|
|
||||||
row := c.QueryRow("select session_data from session where session_key=$1", sid)
|
|
||||||
var sessiondata []byte
|
|
||||||
err := row.Scan(&sessiondata)
|
|
||||||
|
|
||||||
if err == sql.ErrNoRows {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionRegenerate generate new sid for postgresql session
|
|
||||||
func (mp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error) {
|
|
||||||
c := mp.connectInit()
|
|
||||||
row := c.QueryRow("select session_data from session where session_key=$1", oldsid)
|
|
||||||
var sessiondata []byte
|
|
||||||
err := row.Scan(&sessiondata)
|
|
||||||
if err == sql.ErrNoRows {
|
|
||||||
c.Exec("insert into session(session_key,session_data,session_expiry) values($1,$2,$3)",
|
|
||||||
oldsid, "", time.Now().Format(time.RFC3339))
|
|
||||||
}
|
|
||||||
c.Exec("update session set session_key=$1 where session_key=$2", sid, oldsid)
|
|
||||||
var kv map[interface{}]interface{}
|
|
||||||
if len(sessiondata) == 0 {
|
|
||||||
kv = make(map[interface{}]interface{})
|
|
||||||
} else {
|
|
||||||
kv, err = session.DecodeGob(sessiondata)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rs := &SessionStore{c: c, sid: sid, values: kv}
|
|
||||||
return rs, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionDestroy delete postgresql session by sid
|
|
||||||
func (mp *Provider) SessionDestroy(sid string) error {
|
|
||||||
c := mp.connectInit()
|
|
||||||
c.Exec("DELETE FROM session where session_key=$1", sid)
|
|
||||||
c.Close()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionGC delete expired values in postgresql session
|
|
||||||
func (mp *Provider) SessionGC() {
|
|
||||||
c := mp.connectInit()
|
|
||||||
c.Exec("DELETE from session where EXTRACT(EPOCH FROM (current_timestamp - session_expiry)) > $1", mp.maxlifetime)
|
|
||||||
c.Close()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionAll count values in postgresql session
|
|
||||||
func (mp *Provider) SessionAll() int {
|
|
||||||
c := mp.connectInit()
|
|
||||||
defer c.Close()
|
|
||||||
var total int
|
|
||||||
err := c.QueryRow("SELECT count(*) as num from session").Scan(&total)
|
|
||||||
if err != nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return total
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
session.Register("postgresql", postgresqlpder)
|
|
||||||
}
|
|
256
vendor/github.com/astaxie/beego/session/redis/sess_redis.go
generated
vendored
256
vendor/github.com/astaxie/beego/session/redis/sess_redis.go
generated
vendored
@ -1,256 +0,0 @@
|
|||||||
// Copyright 2014 beego Author. All Rights Reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
// Package redis for session provider
|
|
||||||
//
|
|
||||||
// depend on github.com/garyburd/redigo/redis
|
|
||||||
//
|
|
||||||
// go install github.com/garyburd/redigo/redis
|
|
||||||
//
|
|
||||||
// Usage:
|
|
||||||
// import(
|
|
||||||
// _ "github.com/astaxie/beego/session/redis"
|
|
||||||
// "github.com/astaxie/beego/session"
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// func init() {
|
|
||||||
// globalSessions, _ = session.NewManager("redis", ``{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"127.0.0.1:7070"}``)
|
|
||||||
// go globalSessions.GC()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// more docs: http://beego.me/docs/module/session.md
|
|
||||||
package redis
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/astaxie/beego/session"
|
|
||||||
|
|
||||||
"github.com/garyburd/redigo/redis"
|
|
||||||
)
|
|
||||||
|
|
||||||
var redispder = &Provider{}
|
|
||||||
|
|
||||||
// MaxPoolSize redis max pool size
|
|
||||||
var MaxPoolSize = 100
|
|
||||||
|
|
||||||
// SessionStore redis session store
|
|
||||||
type SessionStore struct {
|
|
||||||
p *redis.Pool
|
|
||||||
sid string
|
|
||||||
lock sync.RWMutex
|
|
||||||
values map[interface{}]interface{}
|
|
||||||
maxlifetime int64
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set value in redis session
|
|
||||||
func (rs *SessionStore) Set(key, value interface{}) error {
|
|
||||||
rs.lock.Lock()
|
|
||||||
defer rs.lock.Unlock()
|
|
||||||
rs.values[key] = value
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get value in redis session
|
|
||||||
func (rs *SessionStore) Get(key interface{}) interface{} {
|
|
||||||
rs.lock.RLock()
|
|
||||||
defer rs.lock.RUnlock()
|
|
||||||
if v, ok := rs.values[key]; ok {
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete value in redis session
|
|
||||||
func (rs *SessionStore) Delete(key interface{}) error {
|
|
||||||
rs.lock.Lock()
|
|
||||||
defer rs.lock.Unlock()
|
|
||||||
delete(rs.values, key)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flush clear all values in redis session
|
|
||||||
func (rs *SessionStore) Flush() error {
|
|
||||||
rs.lock.Lock()
|
|
||||||
defer rs.lock.Unlock()
|
|
||||||
rs.values = make(map[interface{}]interface{})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionID get redis session id
|
|
||||||
func (rs *SessionStore) SessionID() string {
|
|
||||||
return rs.sid
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionRelease save session values to redis
|
|
||||||
func (rs *SessionStore) SessionRelease(w http.ResponseWriter) {
|
|
||||||
b, err := session.EncodeGob(rs.values)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c := rs.p.Get()
|
|
||||||
defer c.Close()
|
|
||||||
c.Do("SETEX", rs.sid, rs.maxlifetime, string(b))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Provider redis session provider
|
|
||||||
type Provider struct {
|
|
||||||
maxlifetime int64
|
|
||||||
savePath string
|
|
||||||
poolsize int
|
|
||||||
password string
|
|
||||||
dbNum int
|
|
||||||
poollist *redis.Pool
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionInit init redis session
|
|
||||||
// savepath like redis server addr,pool size,password,dbnum
|
|
||||||
// e.g. 127.0.0.1:6379,100,astaxie,0
|
|
||||||
func (rp *Provider) SessionInit(maxlifetime int64, savePath string) error {
|
|
||||||
rp.maxlifetime = maxlifetime
|
|
||||||
configs := strings.Split(savePath, ",")
|
|
||||||
if len(configs) > 0 {
|
|
||||||
rp.savePath = configs[0]
|
|
||||||
}
|
|
||||||
if len(configs) > 1 {
|
|
||||||
poolsize, err := strconv.Atoi(configs[1])
|
|
||||||
if err != nil || poolsize <= 0 {
|
|
||||||
rp.poolsize = MaxPoolSize
|
|
||||||
} else {
|
|
||||||
rp.poolsize = poolsize
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
rp.poolsize = MaxPoolSize
|
|
||||||
}
|
|
||||||
if len(configs) > 2 {
|
|
||||||
rp.password = configs[2]
|
|
||||||
}
|
|
||||||
if len(configs) > 3 {
|
|
||||||
dbnum, err := strconv.Atoi(configs[3])
|
|
||||||
if err != nil || dbnum < 0 {
|
|
||||||
rp.dbNum = 0
|
|
||||||
} else {
|
|
||||||
rp.dbNum = dbnum
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
rp.dbNum = 0
|
|
||||||
}
|
|
||||||
rp.poollist = redis.NewPool(func() (redis.Conn, error) {
|
|
||||||
c, err := redis.Dial("tcp", rp.savePath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if rp.password != "" {
|
|
||||||
if _, err := c.Do("AUTH", rp.password); err != nil {
|
|
||||||
c.Close()
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_, err = c.Do("SELECT", rp.dbNum)
|
|
||||||
if err != nil {
|
|
||||||
c.Close()
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return c, err
|
|
||||||
}, rp.poolsize)
|
|
||||||
|
|
||||||
return rp.poollist.Get().Err()
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionRead read redis session by sid
|
|
||||||
func (rp *Provider) SessionRead(sid string) (session.Store, error) {
|
|
||||||
c := rp.poollist.Get()
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
kvs, err := redis.String(c.Do("GET", sid))
|
|
||||||
var kv map[interface{}]interface{}
|
|
||||||
if len(kvs) == 0 {
|
|
||||||
kv = make(map[interface{}]interface{})
|
|
||||||
} else {
|
|
||||||
kv, err = session.DecodeGob([]byte(kvs))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rs := &SessionStore{p: rp.poollist, sid: sid, values: kv, maxlifetime: rp.maxlifetime}
|
|
||||||
return rs, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionExist check redis session exist by sid
|
|
||||||
func (rp *Provider) SessionExist(sid string) bool {
|
|
||||||
c := rp.poollist.Get()
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
if existed, err := redis.Int(c.Do("EXISTS", sid)); err != nil || existed == 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionRegenerate generate new sid for redis session
|
|
||||||
func (rp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error) {
|
|
||||||
c := rp.poollist.Get()
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
if existed, _ := redis.Int(c.Do("EXISTS", oldsid)); existed == 0 {
|
|
||||||
// oldsid doesn't exists, set the new sid directly
|
|
||||||
// ignore error here, since if it return error
|
|
||||||
// the existed value will be 0
|
|
||||||
c.Do("SET", sid, "", "EX", rp.maxlifetime)
|
|
||||||
} else {
|
|
||||||
c.Do("RENAME", oldsid, sid)
|
|
||||||
c.Do("EXPIRE", sid, rp.maxlifetime)
|
|
||||||
}
|
|
||||||
|
|
||||||
kvs, err := redis.String(c.Do("GET", sid))
|
|
||||||
var kv map[interface{}]interface{}
|
|
||||||
if len(kvs) == 0 {
|
|
||||||
kv = make(map[interface{}]interface{})
|
|
||||||
} else {
|
|
||||||
kv, err = session.DecodeGob([]byte(kvs))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rs := &SessionStore{p: rp.poollist, sid: sid, values: kv, maxlifetime: rp.maxlifetime}
|
|
||||||
return rs, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionDestroy delete redis session by id
|
|
||||||
func (rp *Provider) SessionDestroy(sid string) error {
|
|
||||||
c := rp.poollist.Get()
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
c.Do("DEL", sid)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionGC Impelment method, no used.
|
|
||||||
func (rp *Provider) SessionGC() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// SessionAll return all activeSession
|
|
||||||
func (rp *Provider) SessionAll() int {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
session.Register("redis", redispder)
|
|
||||||
}
|
|
4
vendor/github.com/astaxie/beego/session/sess_mem.go
generated
vendored
4
vendor/github.com/astaxie/beego/session/sess_mem.go
generated
vendored
@ -102,7 +102,7 @@ func (pder *MemProvider) SessionRead(sid string) (Store, error) {
|
|||||||
pder.lock.RUnlock()
|
pder.lock.RUnlock()
|
||||||
pder.lock.Lock()
|
pder.lock.Lock()
|
||||||
newsess := &MemSessionStore{sid: sid, timeAccessed: time.Now(), value: make(map[interface{}]interface{})}
|
newsess := &MemSessionStore{sid: sid, timeAccessed: time.Now(), value: make(map[interface{}]interface{})}
|
||||||
element := pder.list.PushBack(newsess)
|
element := pder.list.PushFront(newsess)
|
||||||
pder.sessions[sid] = element
|
pder.sessions[sid] = element
|
||||||
pder.lock.Unlock()
|
pder.lock.Unlock()
|
||||||
return newsess, nil
|
return newsess, nil
|
||||||
@ -134,7 +134,7 @@ func (pder *MemProvider) SessionRegenerate(oldsid, sid string) (Store, error) {
|
|||||||
pder.lock.RUnlock()
|
pder.lock.RUnlock()
|
||||||
pder.lock.Lock()
|
pder.lock.Lock()
|
||||||
newsess := &MemSessionStore{sid: sid, timeAccessed: time.Now(), value: make(map[interface{}]interface{})}
|
newsess := &MemSessionStore{sid: sid, timeAccessed: time.Now(), value: make(map[interface{}]interface{})}
|
||||||
element := pder.list.PushBack(newsess)
|
element := pder.list.PushFront(newsess)
|
||||||
pder.sessions[sid] = element
|
pder.sessions[sid] = element
|
||||||
pder.lock.Unlock()
|
pder.lock.Unlock()
|
||||||
return newsess, nil
|
return newsess, nil
|
||||||
|
4
vendor/github.com/astaxie/beego/session/session.go
generated
vendored
4
vendor/github.com/astaxie/beego/session/session.go
generated
vendored
@ -201,7 +201,9 @@ func (manager *Manager) SessionDestroy(w http.ResponseWriter, r *http.Request) {
|
|||||||
if err != nil || cookie.Value == "" {
|
if err != nil || cookie.Value == "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
manager.provider.SessionDestroy(cookie.Value)
|
|
||||||
|
sid, _ := url.QueryUnescape(cookie.Value)
|
||||||
|
manager.provider.SessionDestroy(sid)
|
||||||
if manager.config.EnableSetCookie {
|
if manager.config.EnableSetCookie {
|
||||||
expiration := time.Now()
|
expiration := time.Now()
|
||||||
cookie = &http.Cookie{Name: manager.config.CookieName,
|
cookie = &http.Cookie{Name: manager.config.CookieName,
|
||||||
|
4
vendor/github.com/astaxie/beego/staticfile.go
generated
vendored
4
vendor/github.com/astaxie/beego/staticfile.go
generated
vendored
@ -93,12 +93,14 @@ type serveContentHolder struct {
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
staticFileMap = make(map[string]*serveContentHolder)
|
staticFileMap = make(map[string]*serveContentHolder)
|
||||||
mapLock sync.Mutex
|
mapLock sync.RWMutex
|
||||||
)
|
)
|
||||||
|
|
||||||
func openFile(filePath string, fi os.FileInfo, acceptEncoding string) (bool, string, *serveContentHolder, error) {
|
func openFile(filePath string, fi os.FileInfo, acceptEncoding string) (bool, string, *serveContentHolder, error) {
|
||||||
mapKey := acceptEncoding + ":" + filePath
|
mapKey := acceptEncoding + ":" + filePath
|
||||||
|
mapLock.RLock()
|
||||||
mapFile, _ := staticFileMap[mapKey]
|
mapFile, _ := staticFileMap[mapKey]
|
||||||
|
mapLock.RUnlock()
|
||||||
if isOk(mapFile, fi) {
|
if isOk(mapFile, fi) {
|
||||||
return mapFile.encoding != "", mapFile.encoding, mapFile, nil
|
return mapFile.encoding != "", mapFile.encoding, mapFile, nil
|
||||||
}
|
}
|
||||||
|
160
vendor/github.com/astaxie/beego/swagger/docs_spec.go
generated
vendored
160
vendor/github.com/astaxie/beego/swagger/docs_spec.go
generated
vendored
@ -1,160 +0,0 @@
|
|||||||
// Copyright 2014 beego Author. All Rights Reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
// Package swagger struct definition
|
|
||||||
package swagger
|
|
||||||
|
|
||||||
// SwaggerVersion show the current swagger version
|
|
||||||
const SwaggerVersion = "1.2"
|
|
||||||
|
|
||||||
// ResourceListing list the resource
|
|
||||||
type ResourceListing struct {
|
|
||||||
APIVersion string `json:"apiVersion"`
|
|
||||||
SwaggerVersion string `json:"swaggerVersion"` // e.g 1.2
|
|
||||||
// BasePath string `json:"basePath"` obsolete in 1.1
|
|
||||||
APIs []APIRef `json:"apis"`
|
|
||||||
Info Information `json:"info"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// APIRef description the api path and description
|
|
||||||
type APIRef struct {
|
|
||||||
Path string `json:"path"` // relative or absolute, must start with /
|
|
||||||
Description string `json:"description"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Information show the API Information
|
|
||||||
type Information struct {
|
|
||||||
Title string `json:"title,omitempty"`
|
|
||||||
Description string `json:"description,omitempty"`
|
|
||||||
Contact string `json:"contact,omitempty"`
|
|
||||||
TermsOfServiceURL string `json:"termsOfServiceUrl,omitempty"`
|
|
||||||
License string `json:"license,omitempty"`
|
|
||||||
LicenseURL string `json:"licenseUrl,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// APIDeclaration see https://github.com/wordnik/swagger-core/blob/scala_2.10-1.3-RC3/schemas/api-declaration-schema.json
|
|
||||||
type APIDeclaration struct {
|
|
||||||
APIVersion string `json:"apiVersion"`
|
|
||||||
SwaggerVersion string `json:"swaggerVersion"`
|
|
||||||
BasePath string `json:"basePath"`
|
|
||||||
ResourcePath string `json:"resourcePath"` // must start with /
|
|
||||||
Consumes []string `json:"consumes,omitempty"`
|
|
||||||
Produces []string `json:"produces,omitempty"`
|
|
||||||
APIs []API `json:"apis,omitempty"`
|
|
||||||
Models map[string]Model `json:"models,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// API show tha API struct
|
|
||||||
type API struct {
|
|
||||||
Path string `json:"path"` // relative or absolute, must start with /
|
|
||||||
Description string `json:"description"`
|
|
||||||
Operations []Operation `json:"operations,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Operation desc the Operation
|
|
||||||
type Operation struct {
|
|
||||||
HTTPMethod string `json:"httpMethod"`
|
|
||||||
Nickname string `json:"nickname"`
|
|
||||||
Type string `json:"type"` // in 1.1 = DataType
|
|
||||||
// ResponseClass string `json:"responseClass"` obsolete in 1.2
|
|
||||||
Summary string `json:"summary,omitempty"`
|
|
||||||
Notes string `json:"notes,omitempty"`
|
|
||||||
Parameters []Parameter `json:"parameters,omitempty"`
|
|
||||||
ResponseMessages []ResponseMessage `json:"responseMessages,omitempty"` // optional
|
|
||||||
Consumes []string `json:"consumes,omitempty"`
|
|
||||||
Produces []string `json:"produces,omitempty"`
|
|
||||||
Authorizations []Authorization `json:"authorizations,omitempty"`
|
|
||||||
Protocols []Protocol `json:"protocols,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Protocol support which Protocol
|
|
||||||
type Protocol struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
// ResponseMessage Show the
|
|
||||||
type ResponseMessage struct {
|
|
||||||
Code int `json:"code"`
|
|
||||||
Message string `json:"message"`
|
|
||||||
ResponseModel string `json:"responseModel"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parameter desc the request parameters
|
|
||||||
type Parameter struct {
|
|
||||||
ParamType string `json:"paramType"` // path,query,body,header,form
|
|
||||||
Name string `json:"name"`
|
|
||||||
Description string `json:"description"`
|
|
||||||
DataType string `json:"dataType"` // 1.2 needed?
|
|
||||||
Type string `json:"type"` // integer
|
|
||||||
Format string `json:"format"` // int64
|
|
||||||
AllowMultiple bool `json:"allowMultiple"`
|
|
||||||
Required bool `json:"required"`
|
|
||||||
Minimum int `json:"minimum"`
|
|
||||||
Maximum int `json:"maximum"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// ErrorResponse desc response
|
|
||||||
type ErrorResponse struct {
|
|
||||||
Code int `json:"code"`
|
|
||||||
Reason string `json:"reason"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Model define the data model
|
|
||||||
type Model struct {
|
|
||||||
ID string `json:"id"`
|
|
||||||
Required []string `json:"required,omitempty"`
|
|
||||||
Properties map[string]ModelProperty `json:"properties"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// ModelProperty define the properties
|
|
||||||
type ModelProperty struct {
|
|
||||||
Type string `json:"type"`
|
|
||||||
Description string `json:"description"`
|
|
||||||
Items map[string]string `json:"items,omitempty"`
|
|
||||||
Format string `json:"format"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Authorization see https://github.com/wordnik/swagger-core/wiki/authorizations
|
|
||||||
type Authorization struct {
|
|
||||||
LocalOAuth OAuth `json:"local-oauth"`
|
|
||||||
APIKey APIKey `json:"apiKey"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// OAuth see https://github.com/wordnik/swagger-core/wiki/authorizations
|
|
||||||
type OAuth struct {
|
|
||||||
Type string `json:"type"` // e.g. oauth2
|
|
||||||
Scopes []string `json:"scopes"` // e.g. PUBLIC
|
|
||||||
GrantTypes map[string]GrantType `json:"grantTypes"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// GrantType see https://github.com/wordnik/swagger-core/wiki/authorizations
|
|
||||||
type GrantType struct {
|
|
||||||
LoginEndpoint Endpoint `json:"loginEndpoint"`
|
|
||||||
TokenName string `json:"tokenName"` // e.g. access_code
|
|
||||||
TokenRequestEndpoint Endpoint `json:"tokenRequestEndpoint"`
|
|
||||||
TokenEndpoint Endpoint `json:"tokenEndpoint"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Endpoint see https://github.com/wordnik/swagger-core/wiki/authorizations
|
|
||||||
type Endpoint struct {
|
|
||||||
URL string `json:"url"`
|
|
||||||
ClientIDName string `json:"clientIdName"`
|
|
||||||
ClientSecretName string `json:"clientSecretName"`
|
|
||||||
TokenName string `json:"tokenName"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// APIKey see https://github.com/wordnik/swagger-core/wiki/authorizations
|
|
||||||
type APIKey struct {
|
|
||||||
Type string `json:"type"` // e.g. apiKey
|
|
||||||
PassAs string `json:"passAs"` // e.g. header
|
|
||||||
}
|
|
139
vendor/github.com/astaxie/beego/template.go
generated
vendored
139
vendor/github.com/astaxie/beego/template.go
generated
vendored
@ -18,23 +18,41 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"html/template"
|
"html/template"
|
||||||
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/astaxie/beego/utils"
|
"github.com/astaxie/beego/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
beegoTplFuncMap = make(template.FuncMap)
|
beegoTplFuncMap = make(template.FuncMap)
|
||||||
// BeeTemplates caching map and supported template file extensions.
|
// beeTemplates caching map and supported template file extensions.
|
||||||
BeeTemplates = make(map[string]*template.Template)
|
beeTemplates = make(map[string]*template.Template)
|
||||||
// BeeTemplateExt stores the template extension which will build
|
templatesLock sync.RWMutex
|
||||||
BeeTemplateExt = []string{"tpl", "html"}
|
// beeTemplateExt stores the template extension which will build
|
||||||
|
beeTemplateExt = []string{"tpl", "html"}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func executeTemplate(wr io.Writer, name string, data interface{}) error {
|
||||||
|
if BConfig.RunMode == DEV {
|
||||||
|
templatesLock.RLock()
|
||||||
|
defer templatesLock.RUnlock()
|
||||||
|
}
|
||||||
|
if t, ok := beeTemplates[name]; ok {
|
||||||
|
err := t.ExecuteTemplate(wr, name, data)
|
||||||
|
if err != nil {
|
||||||
|
Trace("template Execute err:", err)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
panic("can't find templatefile in the path:" + name)
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
beegoTplFuncMap["dateformat"] = DateFormat
|
beegoTplFuncMap["dateformat"] = DateFormat
|
||||||
beegoTplFuncMap["date"] = Date
|
beegoTplFuncMap["date"] = Date
|
||||||
@ -53,7 +71,6 @@ func init() {
|
|||||||
beegoTplFuncMap["config"] = GetConfig
|
beegoTplFuncMap["config"] = GetConfig
|
||||||
beegoTplFuncMap["map_get"] = MapGet
|
beegoTplFuncMap["map_get"] = MapGet
|
||||||
|
|
||||||
// go1.2 added template funcs
|
|
||||||
// Comparisons
|
// Comparisons
|
||||||
beegoTplFuncMap["eq"] = eq // ==
|
beegoTplFuncMap["eq"] = eq // ==
|
||||||
beegoTplFuncMap["ge"] = ge // >=
|
beegoTplFuncMap["ge"] = ge // >=
|
||||||
@ -62,21 +79,25 @@ func init() {
|
|||||||
beegoTplFuncMap["lt"] = lt // <
|
beegoTplFuncMap["lt"] = lt // <
|
||||||
beegoTplFuncMap["ne"] = ne // !=
|
beegoTplFuncMap["ne"] = ne // !=
|
||||||
|
|
||||||
beegoTplFuncMap["urlfor"] = URLFor // !=
|
beegoTplFuncMap["urlfor"] = URLFor // build a URL to match a Controller and it's method
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddFuncMap let user to register a func in the template.
|
// AddFuncMap let user to register a func in the template.
|
||||||
func AddFuncMap(key string, funname interface{}) error {
|
func AddFuncMap(key string, fn interface{}) error {
|
||||||
beegoTplFuncMap[key] = funname
|
beegoTplFuncMap[key] = fn
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type templatefile struct {
|
type templateFile struct {
|
||||||
root string
|
root string
|
||||||
files map[string][]string
|
files map[string][]string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tf *templatefile) visit(paths string, f os.FileInfo, err error) error {
|
// visit will make the paths into two part,the first is subDir (without tf.root),the second is full path(without tf.root).
|
||||||
|
// if tf.root="views" and
|
||||||
|
// paths is "views/errors/404.html",the subDir will be "errors",the file will be "errors/404.html"
|
||||||
|
// paths is "views/admin/errors/404.html",the subDir will be "admin/errors",the file will be "admin/errors/404.html"
|
||||||
|
func (tf *templateFile) visit(paths string, f os.FileInfo, err error) error {
|
||||||
if f == nil {
|
if f == nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -88,24 +109,16 @@ func (tf *templatefile) visit(paths string, f os.FileInfo, err error) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
replace := strings.NewReplacer("\\", "/")
|
replace := strings.NewReplacer("\\", "/")
|
||||||
a := []byte(paths)
|
file := strings.TrimLeft(replace.Replace(paths[len(tf.root):]), "/")
|
||||||
a = a[len([]byte(tf.root)):]
|
subDir := filepath.Dir(file)
|
||||||
file := strings.TrimLeft(replace.Replace(string(a)), "/")
|
|
||||||
subdir := filepath.Dir(file)
|
|
||||||
if _, ok := tf.files[subdir]; ok {
|
|
||||||
tf.files[subdir] = append(tf.files[subdir], file)
|
|
||||||
} else {
|
|
||||||
m := make([]string, 1)
|
|
||||||
m[0] = file
|
|
||||||
tf.files[subdir] = m
|
|
||||||
}
|
|
||||||
|
|
||||||
|
tf.files[subDir] = append(tf.files[subDir], file)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasTemplateExt return this path contains supported template extension of beego or not.
|
// HasTemplateExt return this path contains supported template extension of beego or not.
|
||||||
func HasTemplateExt(paths string) bool {
|
func HasTemplateExt(paths string) bool {
|
||||||
for _, v := range BeeTemplateExt {
|
for _, v := range beeTemplateExt {
|
||||||
if strings.HasSuffix(paths, "."+v) {
|
if strings.HasSuffix(paths, "."+v) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -115,12 +128,12 @@ func HasTemplateExt(paths string) bool {
|
|||||||
|
|
||||||
// AddTemplateExt add new extension for template.
|
// AddTemplateExt add new extension for template.
|
||||||
func AddTemplateExt(ext string) {
|
func AddTemplateExt(ext string) {
|
||||||
for _, v := range BeeTemplateExt {
|
for _, v := range beeTemplateExt {
|
||||||
if v == ext {
|
if v == ext {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BeeTemplateExt = append(BeeTemplateExt, ext)
|
beeTemplateExt = append(beeTemplateExt, ext)
|
||||||
}
|
}
|
||||||
|
|
||||||
// BuildTemplate will build all template files in a directory.
|
// BuildTemplate will build all template files in a directory.
|
||||||
@ -132,7 +145,7 @@ func BuildTemplate(dir string, files ...string) error {
|
|||||||
}
|
}
|
||||||
return errors.New("dir open err")
|
return errors.New("dir open err")
|
||||||
}
|
}
|
||||||
self := &templatefile{
|
self := &templateFile{
|
||||||
root: dir,
|
root: dir,
|
||||||
files: make(map[string][]string),
|
files: make(map[string][]string),
|
||||||
}
|
}
|
||||||
@ -146,12 +159,14 @@ func BuildTemplate(dir string, files ...string) error {
|
|||||||
for _, v := range self.files {
|
for _, v := range self.files {
|
||||||
for _, file := range v {
|
for _, file := range v {
|
||||||
if len(files) == 0 || utils.InSlice(file, files) {
|
if len(files) == 0 || utils.InSlice(file, files) {
|
||||||
|
templatesLock.Lock()
|
||||||
t, err := getTemplate(self.root, file, v...)
|
t, err := getTemplate(self.root, file, v...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Trace("parse template err:", file, err)
|
Trace("parse template err:", file, err)
|
||||||
} else {
|
} else {
|
||||||
BeeTemplates[file] = t
|
beeTemplates[file] = t
|
||||||
}
|
}
|
||||||
|
templatesLock.Unlock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -159,16 +174,16 @@ func BuildTemplate(dir string, files ...string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getTplDeep(root, file, parent string, t *template.Template) (*template.Template, [][]string, error) {
|
func getTplDeep(root, file, parent string, t *template.Template) (*template.Template, [][]string, error) {
|
||||||
var fileabspath string
|
var fileAbsPath string
|
||||||
if filepath.HasPrefix(file, "../") {
|
if filepath.HasPrefix(file, "../") {
|
||||||
fileabspath = filepath.Join(root, filepath.Dir(parent), file)
|
fileAbsPath = filepath.Join(root, filepath.Dir(parent), file)
|
||||||
} else {
|
} else {
|
||||||
fileabspath = filepath.Join(root, file)
|
fileAbsPath = filepath.Join(root, file)
|
||||||
}
|
}
|
||||||
if e := utils.FileExists(fileabspath); !e {
|
if e := utils.FileExists(fileAbsPath); !e {
|
||||||
panic("can't find template file:" + file)
|
panic("can't find template file:" + file)
|
||||||
}
|
}
|
||||||
data, err := ioutil.ReadFile(fileabspath)
|
data, err := ioutil.ReadFile(fileAbsPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, [][]string{}, err
|
return nil, [][]string{}, err
|
||||||
}
|
}
|
||||||
@ -177,11 +192,11 @@ func getTplDeep(root, file, parent string, t *template.Template) (*template.Temp
|
|||||||
return nil, [][]string{}, err
|
return nil, [][]string{}, err
|
||||||
}
|
}
|
||||||
reg := regexp.MustCompile(BConfig.WebConfig.TemplateLeft + "[ ]*template[ ]+\"([^\"]+)\"")
|
reg := regexp.MustCompile(BConfig.WebConfig.TemplateLeft + "[ ]*template[ ]+\"([^\"]+)\"")
|
||||||
allsub := reg.FindAllStringSubmatch(string(data), -1)
|
allSub := reg.FindAllStringSubmatch(string(data), -1)
|
||||||
for _, m := range allsub {
|
for _, m := range allSub {
|
||||||
if len(m) == 2 {
|
if len(m) == 2 {
|
||||||
tlook := t.Lookup(m[1])
|
tl := t.Lookup(m[1])
|
||||||
if tlook != nil {
|
if tl != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if !HasTemplateExt(m[1]) {
|
if !HasTemplateExt(m[1]) {
|
||||||
@ -193,17 +208,17 @@ func getTplDeep(root, file, parent string, t *template.Template) (*template.Temp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return t, allsub, nil
|
return t, allSub, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getTemplate(root, file string, others ...string) (t *template.Template, err error) {
|
func getTemplate(root, file string, others ...string) (t *template.Template, err error) {
|
||||||
t = template.New(file).Delims(BConfig.WebConfig.TemplateLeft, BConfig.WebConfig.TemplateRight).Funcs(beegoTplFuncMap)
|
t = template.New(file).Delims(BConfig.WebConfig.TemplateLeft, BConfig.WebConfig.TemplateRight).Funcs(beegoTplFuncMap)
|
||||||
var submods [][]string
|
var subMods [][]string
|
||||||
t, submods, err = getTplDeep(root, file, "", t)
|
t, subMods, err = getTplDeep(root, file, "", t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
t, err = _getTemplate(t, root, submods, others...)
|
t, err = _getTemplate(t, root, subMods, others...)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -211,44 +226,44 @@ func getTemplate(root, file string, others ...string) (t *template.Template, err
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func _getTemplate(t0 *template.Template, root string, submods [][]string, others ...string) (t *template.Template, err error) {
|
func _getTemplate(t0 *template.Template, root string, subMods [][]string, others ...string) (t *template.Template, err error) {
|
||||||
t = t0
|
t = t0
|
||||||
for _, m := range submods {
|
for _, m := range subMods {
|
||||||
if len(m) == 2 {
|
if len(m) == 2 {
|
||||||
templ := t.Lookup(m[1])
|
tpl := t.Lookup(m[1])
|
||||||
if templ != nil {
|
if tpl != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
//first check filename
|
//first check filename
|
||||||
for _, otherfile := range others {
|
for _, otherFile := range others {
|
||||||
if otherfile == m[1] {
|
if otherFile == m[1] {
|
||||||
var submods1 [][]string
|
var subMods1 [][]string
|
||||||
t, submods1, err = getTplDeep(root, otherfile, "", t)
|
t, subMods1, err = getTplDeep(root, otherFile, "", t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Trace("template parse file err:", err)
|
Trace("template parse file err:", err)
|
||||||
} else if submods1 != nil && len(submods1) > 0 {
|
} else if subMods1 != nil && len(subMods1) > 0 {
|
||||||
t, err = _getTemplate(t, root, submods1, others...)
|
t, err = _getTemplate(t, root, subMods1, others...)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//second check define
|
//second check define
|
||||||
for _, otherfile := range others {
|
for _, otherFile := range others {
|
||||||
fileabspath := filepath.Join(root, otherfile)
|
fileAbsPath := filepath.Join(root, otherFile)
|
||||||
data, err := ioutil.ReadFile(fileabspath)
|
data, err := ioutil.ReadFile(fileAbsPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
reg := regexp.MustCompile(BConfig.WebConfig.TemplateLeft + "[ ]*define[ ]+\"([^\"]+)\"")
|
reg := regexp.MustCompile(BConfig.WebConfig.TemplateLeft + "[ ]*define[ ]+\"([^\"]+)\"")
|
||||||
allsub := reg.FindAllStringSubmatch(string(data), -1)
|
allSub := reg.FindAllStringSubmatch(string(data), -1)
|
||||||
for _, sub := range allsub {
|
for _, sub := range allSub {
|
||||||
if len(sub) == 2 && sub[1] == m[1] {
|
if len(sub) == 2 && sub[1] == m[1] {
|
||||||
var submods1 [][]string
|
var subMods1 [][]string
|
||||||
t, submods1, err = getTplDeep(root, otherfile, "", t)
|
t, subMods1, err = getTplDeep(root, otherFile, "", t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Trace("template parse file err:", err)
|
Trace("template parse file err:", err)
|
||||||
} else if submods1 != nil && len(submods1) > 0 {
|
} else if subMods1 != nil && len(subMods1) > 0 {
|
||||||
t, err = _getTemplate(t, root, submods1, others...)
|
t, err = _getTemplate(t, root, subMods1, others...)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -272,7 +287,9 @@ func SetStaticPath(url string, path string) *App {
|
|||||||
if !strings.HasPrefix(url, "/") {
|
if !strings.HasPrefix(url, "/") {
|
||||||
url = "/" + url
|
url = "/" + url
|
||||||
}
|
}
|
||||||
url = strings.TrimRight(url, "/")
|
if url != "/" {
|
||||||
|
url = strings.TrimRight(url, "/")
|
||||||
|
}
|
||||||
BConfig.WebConfig.StaticDir[url] = path
|
BConfig.WebConfig.StaticDir[url] = path
|
||||||
return BeeApp
|
return BeeApp
|
||||||
}
|
}
|
||||||
@ -282,7 +299,9 @@ func DelStaticPath(url string) *App {
|
|||||||
if !strings.HasPrefix(url, "/") {
|
if !strings.HasPrefix(url, "/") {
|
||||||
url = "/" + url
|
url = "/" + url
|
||||||
}
|
}
|
||||||
url = strings.TrimRight(url, "/")
|
if url != "/" {
|
||||||
|
url = strings.TrimRight(url, "/")
|
||||||
|
}
|
||||||
delete(BConfig.WebConfig.StaticDir, url)
|
delete(BConfig.WebConfig.StaticDir, url)
|
||||||
return BeeApp
|
return BeeApp
|
||||||
}
|
}
|
||||||
|
15
vendor/github.com/astaxie/beego/testing/assertions.go
generated
vendored
15
vendor/github.com/astaxie/beego/testing/assertions.go
generated
vendored
@ -1,15 +0,0 @@
|
|||||||
// Copyright 2014 beego Author. All Rights Reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package testing
|
|
65
vendor/github.com/astaxie/beego/testing/client.go
generated
vendored
65
vendor/github.com/astaxie/beego/testing/client.go
generated
vendored
@ -1,65 +0,0 @@
|
|||||||
// Copyright 2014 beego Author. All Rights Reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package testing
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/astaxie/beego/config"
|
|
||||||
"github.com/astaxie/beego/httplib"
|
|
||||||
)
|
|
||||||
|
|
||||||
var port = ""
|
|
||||||
var baseURL = "http://localhost:"
|
|
||||||
|
|
||||||
// TestHTTPRequest beego test request client
|
|
||||||
type TestHTTPRequest struct {
|
|
||||||
httplib.BeegoHTTPRequest
|
|
||||||
}
|
|
||||||
|
|
||||||
func getPort() string {
|
|
||||||
if port == "" {
|
|
||||||
config, err := config.NewConfig("ini", "../conf/app.conf")
|
|
||||||
if err != nil {
|
|
||||||
return "8080"
|
|
||||||
}
|
|
||||||
port = config.String("httpport")
|
|
||||||
return port
|
|
||||||
}
|
|
||||||
return port
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get returns test client in GET method
|
|
||||||
func Get(path string) *TestHTTPRequest {
|
|
||||||
return &TestHTTPRequest{*httplib.Get(baseURL + getPort() + path)}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Post returns test client in POST method
|
|
||||||
func Post(path string) *TestHTTPRequest {
|
|
||||||
return &TestHTTPRequest{*httplib.Post(baseURL + getPort() + path)}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Put returns test client in PUT method
|
|
||||||
func Put(path string) *TestHTTPRequest {
|
|
||||||
return &TestHTTPRequest{*httplib.Put(baseURL + getPort() + path)}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete returns test client in DELETE method
|
|
||||||
func Delete(path string) *TestHTTPRequest {
|
|
||||||
return &TestHTTPRequest{*httplib.Delete(baseURL + getPort() + path)}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Head returns test client in HEAD method
|
|
||||||
func Head(path string) *TestHTTPRequest {
|
|
||||||
return &TestHTTPRequest{*httplib.Head(baseURL + getPort() + path)}
|
|
||||||
}
|
|
45
vendor/github.com/astaxie/beego/tree.go
generated
vendored
45
vendor/github.com/astaxie/beego/tree.go
generated
vendored
@ -141,7 +141,7 @@ func (t *Tree) addtree(segments []string, tree *Tree, wildcards []string, reg st
|
|||||||
regexpStr = "([^.]+).(.+)"
|
regexpStr = "([^.]+).(.+)"
|
||||||
params = params[1:]
|
params = params[1:]
|
||||||
} else {
|
} else {
|
||||||
for range params {
|
for _ = range params {
|
||||||
regexpStr = "([^/]+)/" + regexpStr
|
regexpStr = "([^/]+)/" + regexpStr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -254,7 +254,7 @@ func (t *Tree) addseg(segments []string, route interface{}, wildcards []string,
|
|||||||
regexpStr = "/([^.]+).(.+)"
|
regexpStr = "/([^.]+).(.+)"
|
||||||
params = params[1:]
|
params = params[1:]
|
||||||
} else {
|
} else {
|
||||||
for range params {
|
for _ = range params {
|
||||||
regexpStr = "/([^/]+)" + regexpStr
|
regexpStr = "/([^/]+)" + regexpStr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -265,15 +265,14 @@ func (t *Tree) addseg(segments []string, route interface{}, wildcards []string,
|
|||||||
}
|
}
|
||||||
t.wildcard.addseg(segments[1:], route, append(wildcards, params...), reg+regexpStr)
|
t.wildcard.addseg(segments[1:], route, append(wildcards, params...), reg+regexpStr)
|
||||||
} else {
|
} else {
|
||||||
var ok bool
|
|
||||||
var subTree *Tree
|
var subTree *Tree
|
||||||
for _, subTree = range t.fixrouters {
|
for _, sub := range t.fixrouters {
|
||||||
if t.prefix == seg {
|
if sub.prefix == seg {
|
||||||
ok = true
|
subTree = sub
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !ok {
|
if subTree == nil {
|
||||||
subTree = NewTree()
|
subTree = NewTree()
|
||||||
subTree.prefix = seg
|
subTree.prefix = seg
|
||||||
t.fixrouters = append(t.fixrouters, subTree)
|
t.fixrouters = append(t.fixrouters, subTree)
|
||||||
@ -390,7 +389,7 @@ type leafInfo struct {
|
|||||||
func (leaf *leafInfo) match(wildcardValues []string, ctx *context.Context) (ok bool) {
|
func (leaf *leafInfo) match(wildcardValues []string, ctx *context.Context) (ok bool) {
|
||||||
//fmt.Println("Leaf:", wildcardValues, leaf.wildcards, leaf.regexps)
|
//fmt.Println("Leaf:", wildcardValues, leaf.wildcards, leaf.regexps)
|
||||||
if leaf.regexps == nil {
|
if leaf.regexps == nil {
|
||||||
if len(wildcardValues) == 0 { // static path
|
if len(wildcardValues) == 0 && len(leaf.wildcards) == 0 { // static path
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// match *
|
// match *
|
||||||
@ -420,7 +419,11 @@ func (leaf *leafInfo) match(wildcardValues []string, ctx *context.Context) (ok b
|
|||||||
if len(strs) == 2 {
|
if len(strs) == 2 {
|
||||||
ctx.Input.SetParam(":ext", strs[1])
|
ctx.Input.SetParam(":ext", strs[1])
|
||||||
}
|
}
|
||||||
ctx.Input.SetParam(":path", path.Join(path.Join(wildcardValues[index:len(wildcardValues)-1]...), strs[0]))
|
if index > (len(wildcardValues) - 1) {
|
||||||
|
ctx.Input.SetParam(":path", "")
|
||||||
|
} else {
|
||||||
|
ctx.Input.SetParam(":path", path.Join(path.Join(wildcardValues[index:len(wildcardValues)-1]...), strs[0]))
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// match :id
|
// match :id
|
||||||
@ -438,7 +441,9 @@ func (leaf *leafInfo) match(wildcardValues []string, ctx *context.Context) (ok b
|
|||||||
}
|
}
|
||||||
matches := leaf.regexps.FindStringSubmatch(path.Join(wildcardValues...))
|
matches := leaf.regexps.FindStringSubmatch(path.Join(wildcardValues...))
|
||||||
for i, match := range matches[1:] {
|
for i, match := range matches[1:] {
|
||||||
ctx.Input.SetParam(leaf.wildcards[i], match)
|
if i < len(leaf.wildcards) {
|
||||||
|
ctx.Input.SetParam(leaf.wildcards[i], match)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -448,17 +453,11 @@ func (leaf *leafInfo) match(wildcardValues []string, ctx *context.Context) (ok b
|
|||||||
// "/admin/" -> ["admin"]
|
// "/admin/" -> ["admin"]
|
||||||
// "/admin/users" -> ["admin", "users"]
|
// "/admin/users" -> ["admin", "users"]
|
||||||
func splitPath(key string) []string {
|
func splitPath(key string) []string {
|
||||||
|
key = strings.Trim(key, "/ ")
|
||||||
if key == "" {
|
if key == "" {
|
||||||
return []string{}
|
return []string{}
|
||||||
}
|
}
|
||||||
elements := strings.Split(key, "/")
|
return strings.Split(key, "/")
|
||||||
if elements[0] == "" {
|
|
||||||
elements = elements[1:]
|
|
||||||
}
|
|
||||||
if elements[len(elements)-1] == "" {
|
|
||||||
elements = elements[:len(elements)-1]
|
|
||||||
}
|
|
||||||
return elements
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// "admin" -> false, nil, ""
|
// "admin" -> false, nil, ""
|
||||||
@ -542,13 +541,19 @@ func splitSegment(key string) (bool, []string, string) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if v == ':' {
|
// Escape Sequence '\'
|
||||||
|
if i > 0 && key[i-1] == '\\' {
|
||||||
|
out = append(out, v)
|
||||||
|
} else if v == ':' {
|
||||||
param = make([]rune, 0)
|
param = make([]rune, 0)
|
||||||
start = true
|
start = true
|
||||||
} else if v == '(' {
|
} else if v == '(' {
|
||||||
startexp = true
|
startexp = true
|
||||||
start = false
|
start = false
|
||||||
params = append(params, ":"+string(param))
|
if len(param) > 0 {
|
||||||
|
params = append(params, ":"+string(param))
|
||||||
|
param = make([]rune, 0)
|
||||||
|
}
|
||||||
paramsNum++
|
paramsNum++
|
||||||
expt = make([]rune, 0)
|
expt = make([]rune, 0)
|
||||||
expt = append(expt, '(')
|
expt = append(expt, '(')
|
||||||
|
19
vendor/github.com/astaxie/beego/utils/captcha/LICENSE
generated
vendored
19
vendor/github.com/astaxie/beego/utils/captcha/LICENSE
generated
vendored
@ -1,19 +0,0 @@
|
|||||||
Copyright (c) 2011-2014 Dmitry Chestnykh <dmitry@codingrobots.com>
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
45
vendor/github.com/astaxie/beego/utils/captcha/README.md
generated
vendored
45
vendor/github.com/astaxie/beego/utils/captcha/README.md
generated
vendored
@ -1,45 +0,0 @@
|
|||||||
# Captcha
|
|
||||||
|
|
||||||
an example for use captcha
|
|
||||||
|
|
||||||
```
|
|
||||||
package controllers
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/astaxie/beego"
|
|
||||||
"github.com/astaxie/beego/cache"
|
|
||||||
"github.com/astaxie/beego/utils/captcha"
|
|
||||||
)
|
|
||||||
|
|
||||||
var cpt *captcha.Captcha
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
// use beego cache system store the captcha data
|
|
||||||
store := cache.NewMemoryCache()
|
|
||||||
cpt = captcha.NewWithFilter("/captcha/", store)
|
|
||||||
}
|
|
||||||
|
|
||||||
type MainController struct {
|
|
||||||
beego.Controller
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *MainController) Get() {
|
|
||||||
this.TplName = "index.tpl"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *MainController) Post() {
|
|
||||||
this.TplName = "index.tpl"
|
|
||||||
|
|
||||||
this.Data["Success"] = cpt.VerifyReq(this.Ctx.Request)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
template usage
|
|
||||||
|
|
||||||
```
|
|
||||||
{{.Success}}
|
|
||||||
<form action="/" method="post">
|
|
||||||
{{create_captcha}}
|
|
||||||
<input name="captcha" type="text">
|
|
||||||
</form>
|
|
||||||
```
|
|
269
vendor/github.com/astaxie/beego/utils/captcha/captcha.go
generated
vendored
269
vendor/github.com/astaxie/beego/utils/captcha/captcha.go
generated
vendored
@ -1,269 +0,0 @@
|
|||||||
// Copyright 2014 beego Author. All Rights Reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
// Package captcha implements generation and verification of image CAPTCHAs.
|
|
||||||
// an example for use captcha
|
|
||||||
//
|
|
||||||
// ```
|
|
||||||
// package controllers
|
|
||||||
//
|
|
||||||
// import (
|
|
||||||
// "github.com/astaxie/beego"
|
|
||||||
// "github.com/astaxie/beego/cache"
|
|
||||||
// "github.com/astaxie/beego/utils/captcha"
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// var cpt *captcha.Captcha
|
|
||||||
//
|
|
||||||
// func init() {
|
|
||||||
// // use beego cache system store the captcha data
|
|
||||||
// store := cache.NewMemoryCache()
|
|
||||||
// cpt = captcha.NewWithFilter("/captcha/", store)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// type MainController struct {
|
|
||||||
// beego.Controller
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// func (this *MainController) Get() {
|
|
||||||
// this.TplName = "index.tpl"
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// func (this *MainController) Post() {
|
|
||||||
// this.TplName = "index.tpl"
|
|
||||||
//
|
|
||||||
// this.Data["Success"] = cpt.VerifyReq(this.Ctx.Request)
|
|
||||||
// }
|
|
||||||
// ```
|
|
||||||
//
|
|
||||||
// template usage
|
|
||||||
//
|
|
||||||
// ```
|
|
||||||
// {{.Success}}
|
|
||||||
// <form action="/" method="post">
|
|
||||||
// {{create_captcha}}
|
|
||||||
// <input name="captcha" type="text">
|
|
||||||
// </form>
|
|
||||||
// ```
|
|
||||||
package captcha
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"html/template"
|
|
||||||
"net/http"
|
|
||||||
"path"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/astaxie/beego"
|
|
||||||
"github.com/astaxie/beego/cache"
|
|
||||||
"github.com/astaxie/beego/context"
|
|
||||||
"github.com/astaxie/beego/utils"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
defaultChars = []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// default captcha attributes
|
|
||||||
challengeNums = 6
|
|
||||||
expiration = 600 * time.Second
|
|
||||||
fieldIDName = "captcha_id"
|
|
||||||
fieldCaptchaName = "captcha"
|
|
||||||
cachePrefix = "captcha_"
|
|
||||||
defaultURLPrefix = "/captcha/"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Captcha struct
|
|
||||||
type Captcha struct {
|
|
||||||
// beego cache store
|
|
||||||
store cache.Cache
|
|
||||||
|
|
||||||
// url prefix for captcha image
|
|
||||||
URLPrefix string
|
|
||||||
|
|
||||||
// specify captcha id input field name
|
|
||||||
FieldIDName string
|
|
||||||
// specify captcha result input field name
|
|
||||||
FieldCaptchaName string
|
|
||||||
|
|
||||||
// captcha image width and height
|
|
||||||
StdWidth int
|
|
||||||
StdHeight int
|
|
||||||
|
|
||||||
// captcha chars nums
|
|
||||||
ChallengeNums int
|
|
||||||
|
|
||||||
// captcha expiration seconds
|
|
||||||
Expiration time.Duration
|
|
||||||
|
|
||||||
// cache key prefix
|
|
||||||
CachePrefix string
|
|
||||||
}
|
|
||||||
|
|
||||||
// generate key string
|
|
||||||
func (c *Captcha) key(id string) string {
|
|
||||||
return c.CachePrefix + id
|
|
||||||
}
|
|
||||||
|
|
||||||
// generate rand chars with default chars
|
|
||||||
func (c *Captcha) genRandChars() []byte {
|
|
||||||
return utils.RandomCreateBytes(c.ChallengeNums, defaultChars...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handler beego filter handler for serve captcha image
|
|
||||||
func (c *Captcha) Handler(ctx *context.Context) {
|
|
||||||
var chars []byte
|
|
||||||
|
|
||||||
id := path.Base(ctx.Request.RequestURI)
|
|
||||||
if i := strings.Index(id, "."); i != -1 {
|
|
||||||
id = id[:i]
|
|
||||||
}
|
|
||||||
|
|
||||||
key := c.key(id)
|
|
||||||
|
|
||||||
if len(ctx.Input.Query("reload")) > 0 {
|
|
||||||
chars = c.genRandChars()
|
|
||||||
if err := c.store.Put(key, chars, c.Expiration); err != nil {
|
|
||||||
ctx.Output.SetStatus(500)
|
|
||||||
ctx.WriteString("captcha reload error")
|
|
||||||
beego.Error("Reload Create Captcha Error:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if v, ok := c.store.Get(key).([]byte); ok {
|
|
||||||
chars = v
|
|
||||||
} else {
|
|
||||||
ctx.Output.SetStatus(404)
|
|
||||||
ctx.WriteString("captcha not found")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
img := NewImage(chars, c.StdWidth, c.StdHeight)
|
|
||||||
if _, err := img.WriteTo(ctx.ResponseWriter); err != nil {
|
|
||||||
beego.Error("Write Captcha Image Error:", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateCaptchaHTML template func for output html
|
|
||||||
func (c *Captcha) CreateCaptchaHTML() template.HTML {
|
|
||||||
value, err := c.CreateCaptcha()
|
|
||||||
if err != nil {
|
|
||||||
beego.Error("Create Captcha Error:", err)
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// create html
|
|
||||||
return template.HTML(fmt.Sprintf(`<input type="hidden" name="%s" value="%s">`+
|
|
||||||
`<a class="captcha" href="javascript:">`+
|
|
||||||
`<img onclick="this.src=('%s%s.png?reload='+(new Date()).getTime())" class="captcha-img" src="%s%s.png">`+
|
|
||||||
`</a>`, c.FieldIDName, value, c.URLPrefix, value, c.URLPrefix, value))
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateCaptcha create a new captcha id
|
|
||||||
func (c *Captcha) CreateCaptcha() (string, error) {
|
|
||||||
// generate captcha id
|
|
||||||
id := string(utils.RandomCreateBytes(15))
|
|
||||||
|
|
||||||
// get the captcha chars
|
|
||||||
chars := c.genRandChars()
|
|
||||||
|
|
||||||
// save to store
|
|
||||||
if err := c.store.Put(c.key(id), chars, c.Expiration); err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
return id, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// VerifyReq verify from a request
|
|
||||||
func (c *Captcha) VerifyReq(req *http.Request) bool {
|
|
||||||
req.ParseForm()
|
|
||||||
return c.Verify(req.Form.Get(c.FieldIDName), req.Form.Get(c.FieldCaptchaName))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify direct verify id and challenge string
|
|
||||||
func (c *Captcha) Verify(id string, challenge string) (success bool) {
|
|
||||||
if len(challenge) == 0 || len(id) == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var chars []byte
|
|
||||||
|
|
||||||
key := c.key(id)
|
|
||||||
|
|
||||||
if v, ok := c.store.Get(key).([]byte); ok {
|
|
||||||
chars = v
|
|
||||||
} else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
defer func() {
|
|
||||||
// finally remove it
|
|
||||||
c.store.Delete(key)
|
|
||||||
}()
|
|
||||||
|
|
||||||
if len(chars) != len(challenge) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// verify challenge
|
|
||||||
for i, c := range chars {
|
|
||||||
if c != challenge[i]-48 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewCaptcha create a new captcha.Captcha
|
|
||||||
func NewCaptcha(urlPrefix string, store cache.Cache) *Captcha {
|
|
||||||
cpt := &Captcha{}
|
|
||||||
cpt.store = store
|
|
||||||
cpt.FieldIDName = fieldIDName
|
|
||||||
cpt.FieldCaptchaName = fieldCaptchaName
|
|
||||||
cpt.ChallengeNums = challengeNums
|
|
||||||
cpt.Expiration = expiration
|
|
||||||
cpt.CachePrefix = cachePrefix
|
|
||||||
cpt.StdWidth = stdWidth
|
|
||||||
cpt.StdHeight = stdHeight
|
|
||||||
|
|
||||||
if len(urlPrefix) == 0 {
|
|
||||||
urlPrefix = defaultURLPrefix
|
|
||||||
}
|
|
||||||
|
|
||||||
if urlPrefix[len(urlPrefix)-1] != '/' {
|
|
||||||
urlPrefix += "/"
|
|
||||||
}
|
|
||||||
|
|
||||||
cpt.URLPrefix = urlPrefix
|
|
||||||
|
|
||||||
return cpt
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewWithFilter create a new captcha.Captcha and auto AddFilter for serve captacha image
|
|
||||||
// and add a template func for output html
|
|
||||||
func NewWithFilter(urlPrefix string, store cache.Cache) *Captcha {
|
|
||||||
cpt := NewCaptcha(urlPrefix, store)
|
|
||||||
|
|
||||||
// create filter for serve captcha image
|
|
||||||
beego.InsertFilter(cpt.URLPrefix+"*", beego.BeforeRouter, cpt.Handler)
|
|
||||||
|
|
||||||
// add to template func map
|
|
||||||
beego.AddFuncMap("create_captcha", cpt.CreateCaptchaHTML)
|
|
||||||
|
|
||||||
return cpt
|
|
||||||
}
|
|
498
vendor/github.com/astaxie/beego/utils/captcha/image.go
generated
vendored
498
vendor/github.com/astaxie/beego/utils/captcha/image.go
generated
vendored
@ -1,498 +0,0 @@
|
|||||||
// Copyright 2014 beego Author. All Rights Reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package captcha
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"image"
|
|
||||||
"image/color"
|
|
||||||
"image/png"
|
|
||||||
"io"
|
|
||||||
"math"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
fontWidth = 11
|
|
||||||
fontHeight = 18
|
|
||||||
blackChar = 1
|
|
||||||
|
|
||||||
// Standard width and height of a captcha image.
|
|
||||||
stdWidth = 240
|
|
||||||
stdHeight = 80
|
|
||||||
// Maximum absolute skew factor of a single digit.
|
|
||||||
maxSkew = 0.7
|
|
||||||
// Number of background circles.
|
|
||||||
circleCount = 20
|
|
||||||
)
|
|
||||||
|
|
||||||
var font = [][]byte{
|
|
||||||
{ // 0
|
|
||||||
0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0,
|
|
||||||
0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0,
|
|
||||||
0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0,
|
|
||||||
0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0,
|
|
||||||
1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0,
|
|
||||||
1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1,
|
|
||||||
1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1,
|
|
||||||
1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1,
|
|
||||||
1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1,
|
|
||||||
1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1,
|
|
||||||
1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1,
|
|
||||||
1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1,
|
|
||||||
1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1,
|
|
||||||
1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1,
|
|
||||||
0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0,
|
|
||||||
0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0,
|
|
||||||
0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0,
|
|
||||||
0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0,
|
|
||||||
},
|
|
||||||
{ // 1
|
|
||||||
0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0,
|
|
||||||
0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0,
|
|
||||||
0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0,
|
|
||||||
0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0,
|
|
||||||
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
||||||
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
||||||
},
|
|
||||||
{ // 2
|
|
||||||
0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0,
|
|
||||||
0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
|
|
||||||
1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0,
|
|
||||||
0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
||||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
||||||
},
|
|
||||||
{ // 3
|
|
||||||
0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0,
|
|
||||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
|
|
||||||
1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0,
|
|
||||||
0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0,
|
|
||||||
0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
|
|
||||||
1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0,
|
|
||||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
|
|
||||||
0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0,
|
|
||||||
},
|
|
||||||
{ // 4
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0,
|
|
||||||
0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0,
|
|
||||||
0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0,
|
|
||||||
0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0,
|
|
||||||
0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0,
|
|
||||||
0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0,
|
|
||||||
0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0,
|
|
||||||
1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0,
|
|
||||||
1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0,
|
|
||||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
||||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0,
|
|
||||||
},
|
|
||||||
{ // 5
|
|
||||||
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
|
|
||||||
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
|
|
||||||
0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0,
|
|
||||||
0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
|
|
||||||
1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0,
|
|
||||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
|
|
||||||
0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0,
|
|
||||||
},
|
|
||||||
{ // 6
|
|
||||||
0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0,
|
|
||||||
0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0,
|
|
||||||
0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0,
|
|
||||||
1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0,
|
|
||||||
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0,
|
|
||||||
1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1,
|
|
||||||
1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1,
|
|
||||||
1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1,
|
|
||||||
1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1,
|
|
||||||
1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1,
|
|
||||||
0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1,
|
|
||||||
0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0,
|
|
||||||
0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0,
|
|
||||||
0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0,
|
|
||||||
},
|
|
||||||
{ // 7
|
|
||||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
||||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
||||||
1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1,
|
|
||||||
1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0,
|
|
||||||
},
|
|
||||||
{ // 8
|
|
||||||
0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0,
|
|
||||||
0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0,
|
|
||||||
0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1,
|
|
||||||
0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1,
|
|
||||||
0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1,
|
|
||||||
0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1,
|
|
||||||
0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0,
|
|
||||||
0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0,
|
|
||||||
0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0,
|
|
||||||
0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0,
|
|
||||||
0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0,
|
|
||||||
1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1,
|
|
||||||
1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1,
|
|
||||||
1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1,
|
|
||||||
1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1,
|
|
||||||
1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0,
|
|
||||||
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
|
|
||||||
0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0,
|
|
||||||
},
|
|
||||||
{ // 9
|
|
||||||
0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0,
|
|
||||||
0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
|
|
||||||
0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0,
|
|
||||||
1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0,
|
|
||||||
1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1,
|
|
||||||
1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1,
|
|
||||||
1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1,
|
|
||||||
1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1,
|
|
||||||
0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1,
|
|
||||||
0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1,
|
|
||||||
0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0,
|
|
||||||
0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0,
|
|
||||||
0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// Image struct
|
|
||||||
type Image struct {
|
|
||||||
*image.Paletted
|
|
||||||
numWidth int
|
|
||||||
numHeight int
|
|
||||||
dotSize int
|
|
||||||
}
|
|
||||||
|
|
||||||
var prng = &siprng{}
|
|
||||||
|
|
||||||
// randIntn returns a pseudorandom non-negative int in range [0, n).
|
|
||||||
func randIntn(n int) int {
|
|
||||||
return prng.Intn(n)
|
|
||||||
}
|
|
||||||
|
|
||||||
// randInt returns a pseudorandom int in range [from, to].
|
|
||||||
func randInt(from, to int) int {
|
|
||||||
return prng.Intn(to+1-from) + from
|
|
||||||
}
|
|
||||||
|
|
||||||
// randFloat returns a pseudorandom float64 in range [from, to].
|
|
||||||
func randFloat(from, to float64) float64 {
|
|
||||||
return (to-from)*prng.Float64() + from
|
|
||||||
}
|
|
||||||
|
|
||||||
func randomPalette() color.Palette {
|
|
||||||
p := make([]color.Color, circleCount+1)
|
|
||||||
// Transparent color.
|
|
||||||
p[0] = color.RGBA{0xFF, 0xFF, 0xFF, 0x00}
|
|
||||||
// Primary color.
|
|
||||||
prim := color.RGBA{
|
|
||||||
uint8(randIntn(129)),
|
|
||||||
uint8(randIntn(129)),
|
|
||||||
uint8(randIntn(129)),
|
|
||||||
0xFF,
|
|
||||||
}
|
|
||||||
p[1] = prim
|
|
||||||
// Circle colors.
|
|
||||||
for i := 2; i <= circleCount; i++ {
|
|
||||||
p[i] = randomBrightness(prim, 255)
|
|
||||||
}
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewImage returns a new captcha image of the given width and height with the
|
|
||||||
// given digits, where each digit must be in range 0-9.
|
|
||||||
func NewImage(digits []byte, width, height int) *Image {
|
|
||||||
m := new(Image)
|
|
||||||
m.Paletted = image.NewPaletted(image.Rect(0, 0, width, height), randomPalette())
|
|
||||||
m.calculateSizes(width, height, len(digits))
|
|
||||||
// Randomly position captcha inside the image.
|
|
||||||
maxx := width - (m.numWidth+m.dotSize)*len(digits) - m.dotSize
|
|
||||||
maxy := height - m.numHeight - m.dotSize*2
|
|
||||||
var border int
|
|
||||||
if width > height {
|
|
||||||
border = height / 5
|
|
||||||
} else {
|
|
||||||
border = width / 5
|
|
||||||
}
|
|
||||||
x := randInt(border, maxx-border)
|
|
||||||
y := randInt(border, maxy-border)
|
|
||||||
// Draw digits.
|
|
||||||
for _, n := range digits {
|
|
||||||
m.drawDigit(font[n], x, y)
|
|
||||||
x += m.numWidth + m.dotSize
|
|
||||||
}
|
|
||||||
// Draw strike-through line.
|
|
||||||
m.strikeThrough()
|
|
||||||
// Apply wave distortion.
|
|
||||||
m.distort(randFloat(5, 10), randFloat(100, 200))
|
|
||||||
// Fill image with random circles.
|
|
||||||
m.fillWithCircles(circleCount, m.dotSize)
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
|
|
||||||
// encodedPNG encodes an image to PNG and returns
|
|
||||||
// the result as a byte slice.
|
|
||||||
func (m *Image) encodedPNG() []byte {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
if err := png.Encode(&buf, m.Paletted); err != nil {
|
|
||||||
panic(err.Error())
|
|
||||||
}
|
|
||||||
return buf.Bytes()
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteTo writes captcha image in PNG format into the given writer.
|
|
||||||
func (m *Image) WriteTo(w io.Writer) (int64, error) {
|
|
||||||
n, err := w.Write(m.encodedPNG())
|
|
||||||
return int64(n), err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Image) calculateSizes(width, height, ncount int) {
|
|
||||||
// Goal: fit all digits inside the image.
|
|
||||||
var border int
|
|
||||||
if width > height {
|
|
||||||
border = height / 4
|
|
||||||
} else {
|
|
||||||
border = width / 4
|
|
||||||
}
|
|
||||||
// Convert everything to floats for calculations.
|
|
||||||
w := float64(width - border*2)
|
|
||||||
h := float64(height - border*2)
|
|
||||||
// fw takes into account 1-dot spacing between digits.
|
|
||||||
fw := float64(fontWidth + 1)
|
|
||||||
fh := float64(fontHeight)
|
|
||||||
nc := float64(ncount)
|
|
||||||
// Calculate the width of a single digit taking into account only the
|
|
||||||
// width of the image.
|
|
||||||
nw := w / nc
|
|
||||||
// Calculate the height of a digit from this width.
|
|
||||||
nh := nw * fh / fw
|
|
||||||
// Digit too high?
|
|
||||||
if nh > h {
|
|
||||||
// Fit digits based on height.
|
|
||||||
nh = h
|
|
||||||
nw = fw / fh * nh
|
|
||||||
}
|
|
||||||
// Calculate dot size.
|
|
||||||
m.dotSize = int(nh / fh)
|
|
||||||
// Save everything, making the actual width smaller by 1 dot to account
|
|
||||||
// for spacing between digits.
|
|
||||||
m.numWidth = int(nw) - m.dotSize
|
|
||||||
m.numHeight = int(nh)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Image) drawHorizLine(fromX, toX, y int, colorIdx uint8) {
|
|
||||||
for x := fromX; x <= toX; x++ {
|
|
||||||
m.SetColorIndex(x, y, colorIdx)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Image) drawCircle(x, y, radius int, colorIdx uint8) {
|
|
||||||
f := 1 - radius
|
|
||||||
dfx := 1
|
|
||||||
dfy := -2 * radius
|
|
||||||
xo := 0
|
|
||||||
yo := radius
|
|
||||||
|
|
||||||
m.SetColorIndex(x, y+radius, colorIdx)
|
|
||||||
m.SetColorIndex(x, y-radius, colorIdx)
|
|
||||||
m.drawHorizLine(x-radius, x+radius, y, colorIdx)
|
|
||||||
|
|
||||||
for xo < yo {
|
|
||||||
if f >= 0 {
|
|
||||||
yo--
|
|
||||||
dfy += 2
|
|
||||||
f += dfy
|
|
||||||
}
|
|
||||||
xo++
|
|
||||||
dfx += 2
|
|
||||||
f += dfx
|
|
||||||
m.drawHorizLine(x-xo, x+xo, y+yo, colorIdx)
|
|
||||||
m.drawHorizLine(x-xo, x+xo, y-yo, colorIdx)
|
|
||||||
m.drawHorizLine(x-yo, x+yo, y+xo, colorIdx)
|
|
||||||
m.drawHorizLine(x-yo, x+yo, y-xo, colorIdx)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Image) fillWithCircles(n, maxradius int) {
|
|
||||||
maxx := m.Bounds().Max.X
|
|
||||||
maxy := m.Bounds().Max.Y
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
colorIdx := uint8(randInt(1, circleCount-1))
|
|
||||||
r := randInt(1, maxradius)
|
|
||||||
m.drawCircle(randInt(r, maxx-r), randInt(r, maxy-r), r, colorIdx)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Image) strikeThrough() {
|
|
||||||
maxx := m.Bounds().Max.X
|
|
||||||
maxy := m.Bounds().Max.Y
|
|
||||||
y := randInt(maxy/3, maxy-maxy/3)
|
|
||||||
amplitude := randFloat(5, 20)
|
|
||||||
period := randFloat(80, 180)
|
|
||||||
dx := 2.0 * math.Pi / period
|
|
||||||
for x := 0; x < maxx; x++ {
|
|
||||||
xo := amplitude * math.Cos(float64(y)*dx)
|
|
||||||
yo := amplitude * math.Sin(float64(x)*dx)
|
|
||||||
for yn := 0; yn < m.dotSize; yn++ {
|
|
||||||
r := randInt(0, m.dotSize)
|
|
||||||
m.drawCircle(x+int(xo), y+int(yo)+(yn*m.dotSize), r/2, 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Image) drawDigit(digit []byte, x, y int) {
|
|
||||||
skf := randFloat(-maxSkew, maxSkew)
|
|
||||||
xs := float64(x)
|
|
||||||
r := m.dotSize / 2
|
|
||||||
y += randInt(-r, r)
|
|
||||||
for yo := 0; yo < fontHeight; yo++ {
|
|
||||||
for xo := 0; xo < fontWidth; xo++ {
|
|
||||||
if digit[yo*fontWidth+xo] != blackChar {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
m.drawCircle(x+xo*m.dotSize, y+yo*m.dotSize, r, 1)
|
|
||||||
}
|
|
||||||
xs += skf
|
|
||||||
x = int(xs)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Image) distort(amplude float64, period float64) {
|
|
||||||
w := m.Bounds().Max.X
|
|
||||||
h := m.Bounds().Max.Y
|
|
||||||
|
|
||||||
oldm := m.Paletted
|
|
||||||
newm := image.NewPaletted(image.Rect(0, 0, w, h), oldm.Palette)
|
|
||||||
|
|
||||||
dx := 2.0 * math.Pi / period
|
|
||||||
for x := 0; x < w; x++ {
|
|
||||||
for y := 0; y < h; y++ {
|
|
||||||
xo := amplude * math.Sin(float64(y)*dx)
|
|
||||||
yo := amplude * math.Cos(float64(x)*dx)
|
|
||||||
newm.SetColorIndex(x, y, oldm.ColorIndexAt(x+int(xo), y+int(yo)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m.Paletted = newm
|
|
||||||
}
|
|
||||||
|
|
||||||
func randomBrightness(c color.RGBA, max uint8) color.RGBA {
|
|
||||||
minc := min3(c.R, c.G, c.B)
|
|
||||||
maxc := max3(c.R, c.G, c.B)
|
|
||||||
if maxc > max {
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
n := randIntn(int(max-maxc)) - int(minc)
|
|
||||||
return color.RGBA{
|
|
||||||
uint8(int(c.R) + n),
|
|
||||||
uint8(int(c.G) + n),
|
|
||||||
uint8(int(c.B) + n),
|
|
||||||
uint8(c.A),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func min3(x, y, z uint8) (m uint8) {
|
|
||||||
m = x
|
|
||||||
if y < m {
|
|
||||||
m = y
|
|
||||||
}
|
|
||||||
if z < m {
|
|
||||||
m = z
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func max3(x, y, z uint8) (m uint8) {
|
|
||||||
m = x
|
|
||||||
if y > m {
|
|
||||||
m = y
|
|
||||||
}
|
|
||||||
if z > m {
|
|
||||||
m = z
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
277
vendor/github.com/astaxie/beego/utils/captcha/siprng.go
generated
vendored
277
vendor/github.com/astaxie/beego/utils/captcha/siprng.go
generated
vendored
@ -1,277 +0,0 @@
|
|||||||
// Copyright 2014 beego Author. All Rights Reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package captcha
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/rand"
|
|
||||||
"encoding/binary"
|
|
||||||
"io"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
// siprng is PRNG based on SipHash-2-4.
|
|
||||||
type siprng struct {
|
|
||||||
mu sync.Mutex
|
|
||||||
k0, k1, ctr uint64
|
|
||||||
}
|
|
||||||
|
|
||||||
// siphash implements SipHash-2-4, accepting a uint64 as a message.
|
|
||||||
func siphash(k0, k1, m uint64) uint64 {
|
|
||||||
// Initialization.
|
|
||||||
v0 := k0 ^ 0x736f6d6570736575
|
|
||||||
v1 := k1 ^ 0x646f72616e646f6d
|
|
||||||
v2 := k0 ^ 0x6c7967656e657261
|
|
||||||
v3 := k1 ^ 0x7465646279746573
|
|
||||||
t := uint64(8) << 56
|
|
||||||
|
|
||||||
// Compression.
|
|
||||||
v3 ^= m
|
|
||||||
|
|
||||||
// Round 1.
|
|
||||||
v0 += v1
|
|
||||||
v1 = v1<<13 | v1>>(64-13)
|
|
||||||
v1 ^= v0
|
|
||||||
v0 = v0<<32 | v0>>(64-32)
|
|
||||||
|
|
||||||
v2 += v3
|
|
||||||
v3 = v3<<16 | v3>>(64-16)
|
|
||||||
v3 ^= v2
|
|
||||||
|
|
||||||
v0 += v3
|
|
||||||
v3 = v3<<21 | v3>>(64-21)
|
|
||||||
v3 ^= v0
|
|
||||||
|
|
||||||
v2 += v1
|
|
||||||
v1 = v1<<17 | v1>>(64-17)
|
|
||||||
v1 ^= v2
|
|
||||||
v2 = v2<<32 | v2>>(64-32)
|
|
||||||
|
|
||||||
// Round 2.
|
|
||||||
v0 += v1
|
|
||||||
v1 = v1<<13 | v1>>(64-13)
|
|
||||||
v1 ^= v0
|
|
||||||
v0 = v0<<32 | v0>>(64-32)
|
|
||||||
|
|
||||||
v2 += v3
|
|
||||||
v3 = v3<<16 | v3>>(64-16)
|
|
||||||
v3 ^= v2
|
|
||||||
|
|
||||||
v0 += v3
|
|
||||||
v3 = v3<<21 | v3>>(64-21)
|
|
||||||
v3 ^= v0
|
|
||||||
|
|
||||||
v2 += v1
|
|
||||||
v1 = v1<<17 | v1>>(64-17)
|
|
||||||
v1 ^= v2
|
|
||||||
v2 = v2<<32 | v2>>(64-32)
|
|
||||||
|
|
||||||
v0 ^= m
|
|
||||||
|
|
||||||
// Compress last block.
|
|
||||||
v3 ^= t
|
|
||||||
|
|
||||||
// Round 1.
|
|
||||||
v0 += v1
|
|
||||||
v1 = v1<<13 | v1>>(64-13)
|
|
||||||
v1 ^= v0
|
|
||||||
v0 = v0<<32 | v0>>(64-32)
|
|
||||||
|
|
||||||
v2 += v3
|
|
||||||
v3 = v3<<16 | v3>>(64-16)
|
|
||||||
v3 ^= v2
|
|
||||||
|
|
||||||
v0 += v3
|
|
||||||
v3 = v3<<21 | v3>>(64-21)
|
|
||||||
v3 ^= v0
|
|
||||||
|
|
||||||
v2 += v1
|
|
||||||
v1 = v1<<17 | v1>>(64-17)
|
|
||||||
v1 ^= v2
|
|
||||||
v2 = v2<<32 | v2>>(64-32)
|
|
||||||
|
|
||||||
// Round 2.
|
|
||||||
v0 += v1
|
|
||||||
v1 = v1<<13 | v1>>(64-13)
|
|
||||||
v1 ^= v0
|
|
||||||
v0 = v0<<32 | v0>>(64-32)
|
|
||||||
|
|
||||||
v2 += v3
|
|
||||||
v3 = v3<<16 | v3>>(64-16)
|
|
||||||
v3 ^= v2
|
|
||||||
|
|
||||||
v0 += v3
|
|
||||||
v3 = v3<<21 | v3>>(64-21)
|
|
||||||
v3 ^= v0
|
|
||||||
|
|
||||||
v2 += v1
|
|
||||||
v1 = v1<<17 | v1>>(64-17)
|
|
||||||
v1 ^= v2
|
|
||||||
v2 = v2<<32 | v2>>(64-32)
|
|
||||||
|
|
||||||
v0 ^= t
|
|
||||||
|
|
||||||
// Finalization.
|
|
||||||
v2 ^= 0xff
|
|
||||||
|
|
||||||
// Round 1.
|
|
||||||
v0 += v1
|
|
||||||
v1 = v1<<13 | v1>>(64-13)
|
|
||||||
v1 ^= v0
|
|
||||||
v0 = v0<<32 | v0>>(64-32)
|
|
||||||
|
|
||||||
v2 += v3
|
|
||||||
v3 = v3<<16 | v3>>(64-16)
|
|
||||||
v3 ^= v2
|
|
||||||
|
|
||||||
v0 += v3
|
|
||||||
v3 = v3<<21 | v3>>(64-21)
|
|
||||||
v3 ^= v0
|
|
||||||
|
|
||||||
v2 += v1
|
|
||||||
v1 = v1<<17 | v1>>(64-17)
|
|
||||||
v1 ^= v2
|
|
||||||
v2 = v2<<32 | v2>>(64-32)
|
|
||||||
|
|
||||||
// Round 2.
|
|
||||||
v0 += v1
|
|
||||||
v1 = v1<<13 | v1>>(64-13)
|
|
||||||
v1 ^= v0
|
|
||||||
v0 = v0<<32 | v0>>(64-32)
|
|
||||||
|
|
||||||
v2 += v3
|
|
||||||
v3 = v3<<16 | v3>>(64-16)
|
|
||||||
v3 ^= v2
|
|
||||||
|
|
||||||
v0 += v3
|
|
||||||
v3 = v3<<21 | v3>>(64-21)
|
|
||||||
v3 ^= v0
|
|
||||||
|
|
||||||
v2 += v1
|
|
||||||
v1 = v1<<17 | v1>>(64-17)
|
|
||||||
v1 ^= v2
|
|
||||||
v2 = v2<<32 | v2>>(64-32)
|
|
||||||
|
|
||||||
// Round 3.
|
|
||||||
v0 += v1
|
|
||||||
v1 = v1<<13 | v1>>(64-13)
|
|
||||||
v1 ^= v0
|
|
||||||
v0 = v0<<32 | v0>>(64-32)
|
|
||||||
|
|
||||||
v2 += v3
|
|
||||||
v3 = v3<<16 | v3>>(64-16)
|
|
||||||
v3 ^= v2
|
|
||||||
|
|
||||||
v0 += v3
|
|
||||||
v3 = v3<<21 | v3>>(64-21)
|
|
||||||
v3 ^= v0
|
|
||||||
|
|
||||||
v2 += v1
|
|
||||||
v1 = v1<<17 | v1>>(64-17)
|
|
||||||
v1 ^= v2
|
|
||||||
v2 = v2<<32 | v2>>(64-32)
|
|
||||||
|
|
||||||
// Round 4.
|
|
||||||
v0 += v1
|
|
||||||
v1 = v1<<13 | v1>>(64-13)
|
|
||||||
v1 ^= v0
|
|
||||||
v0 = v0<<32 | v0>>(64-32)
|
|
||||||
|
|
||||||
v2 += v3
|
|
||||||
v3 = v3<<16 | v3>>(64-16)
|
|
||||||
v3 ^= v2
|
|
||||||
|
|
||||||
v0 += v3
|
|
||||||
v3 = v3<<21 | v3>>(64-21)
|
|
||||||
v3 ^= v0
|
|
||||||
|
|
||||||
v2 += v1
|
|
||||||
v1 = v1<<17 | v1>>(64-17)
|
|
||||||
v1 ^= v2
|
|
||||||
v2 = v2<<32 | v2>>(64-32)
|
|
||||||
|
|
||||||
return v0 ^ v1 ^ v2 ^ v3
|
|
||||||
}
|
|
||||||
|
|
||||||
// rekey sets a new PRNG key, which is read from crypto/rand.
|
|
||||||
func (p *siprng) rekey() {
|
|
||||||
var k [16]byte
|
|
||||||
if _, err := io.ReadFull(rand.Reader, k[:]); err != nil {
|
|
||||||
panic(err.Error())
|
|
||||||
}
|
|
||||||
p.k0 = binary.LittleEndian.Uint64(k[0:8])
|
|
||||||
p.k1 = binary.LittleEndian.Uint64(k[8:16])
|
|
||||||
p.ctr = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uint64 returns a new pseudorandom uint64.
|
|
||||||
// It rekeys PRNG on the first call and every 64 MB of generated data.
|
|
||||||
func (p *siprng) Uint64() uint64 {
|
|
||||||
p.mu.Lock()
|
|
||||||
if p.ctr == 0 || p.ctr > 8*1024*1024 {
|
|
||||||
p.rekey()
|
|
||||||
}
|
|
||||||
v := siphash(p.k0, p.k1, p.ctr)
|
|
||||||
p.ctr++
|
|
||||||
p.mu.Unlock()
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *siprng) Int63() int64 {
|
|
||||||
return int64(p.Uint64() & 0x7fffffffffffffff)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *siprng) Uint32() uint32 {
|
|
||||||
return uint32(p.Uint64())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *siprng) Int31() int32 {
|
|
||||||
return int32(p.Uint32() & 0x7fffffff)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *siprng) Intn(n int) int {
|
|
||||||
if n <= 0 {
|
|
||||||
panic("invalid argument to Intn")
|
|
||||||
}
|
|
||||||
if n <= 1<<31-1 {
|
|
||||||
return int(p.Int31n(int32(n)))
|
|
||||||
}
|
|
||||||
return int(p.Int63n(int64(n)))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *siprng) Int63n(n int64) int64 {
|
|
||||||
if n <= 0 {
|
|
||||||
panic("invalid argument to Int63n")
|
|
||||||
}
|
|
||||||
max := int64((1 << 63) - 1 - (1<<63)%uint64(n))
|
|
||||||
v := p.Int63()
|
|
||||||
for v > max {
|
|
||||||
v = p.Int63()
|
|
||||||
}
|
|
||||||
return v % n
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *siprng) Int31n(n int32) int32 {
|
|
||||||
if n <= 0 {
|
|
||||||
panic("invalid argument to Int31n")
|
|
||||||
}
|
|
||||||
max := int32((1 << 31) - 1 - (1<<31)%uint32(n))
|
|
||||||
v := p.Int31()
|
|
||||||
for v > max {
|
|
||||||
v = p.Int31()
|
|
||||||
}
|
|
||||||
return v % n
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *siprng) Float64() float64 { return float64(p.Int63()) / (1 << 63) }
|
|
91
vendor/github.com/astaxie/beego/utils/mail.go
generated
vendored
91
vendor/github.com/astaxie/beego/utils/mail.go
generated
vendored
@ -31,10 +31,13 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
maxLineLength = 76
|
maxLineLength = 76
|
||||||
|
|
||||||
|
upperhex = "0123456789ABCDEF"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Email is the type used for email messages
|
// Email is the type used for email messages
|
||||||
@ -74,9 +77,6 @@ func NewEMail(config string) *Email {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if e.From == "" {
|
|
||||||
e.From = e.Username
|
|
||||||
}
|
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,14 +228,21 @@ func (e *Email) Send() error {
|
|||||||
to := make([]string, 0, len(e.To)+len(e.Cc)+len(e.Bcc))
|
to := make([]string, 0, len(e.To)+len(e.Cc)+len(e.Bcc))
|
||||||
to = append(append(append(to, e.To...), e.Cc...), e.Bcc...)
|
to = append(append(append(to, e.To...), e.Cc...), e.Bcc...)
|
||||||
// Check to make sure there is at least one recipient and one "From" address
|
// Check to make sure there is at least one recipient and one "From" address
|
||||||
if e.From == "" || len(to) == 0 {
|
if len(to) == 0 {
|
||||||
return errors.New("Must specify at least one From address and one To address")
|
return errors.New("Must specify at least one To address")
|
||||||
}
|
}
|
||||||
from, err := mail.ParseAddress(e.From)
|
|
||||||
|
from, err := mail.ParseAddress(e.Username)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
e.From = from.String()
|
|
||||||
|
if len(e.From) == 0 {
|
||||||
|
e.From = e.Username
|
||||||
|
}
|
||||||
|
// use mail's RFC 2047 to encode any string
|
||||||
|
e.Subject = qEncode("utf-8", e.Subject)
|
||||||
|
|
||||||
raw, err := e.Bytes()
|
raw, err := e.Bytes()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -342,3 +349,73 @@ func base64Wrap(w io.Writer, b []byte) {
|
|||||||
w.Write(out)
|
w.Write(out)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Encode returns the encoded-word form of s. If s is ASCII without special
|
||||||
|
// characters, it is returned unchanged. The provided charset is the IANA
|
||||||
|
// charset name of s. It is case insensitive.
|
||||||
|
// RFC 2047 encoded-word
|
||||||
|
func qEncode(charset, s string) string {
|
||||||
|
if !needsEncoding(s) {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
return encodeWord(charset, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func needsEncoding(s string) bool {
|
||||||
|
for _, b := range s {
|
||||||
|
if (b < ' ' || b > '~') && b != '\t' {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// encodeWord encodes a string into an encoded-word.
|
||||||
|
func encodeWord(charset, s string) string {
|
||||||
|
buf := getBuffer()
|
||||||
|
|
||||||
|
buf.WriteString("=?")
|
||||||
|
buf.WriteString(charset)
|
||||||
|
buf.WriteByte('?')
|
||||||
|
buf.WriteByte('q')
|
||||||
|
buf.WriteByte('?')
|
||||||
|
|
||||||
|
enc := make([]byte, 3)
|
||||||
|
for i := 0; i < len(s); i++ {
|
||||||
|
b := s[i]
|
||||||
|
switch {
|
||||||
|
case b == ' ':
|
||||||
|
buf.WriteByte('_')
|
||||||
|
case b <= '~' && b >= '!' && b != '=' && b != '?' && b != '_':
|
||||||
|
buf.WriteByte(b)
|
||||||
|
default:
|
||||||
|
enc[0] = '='
|
||||||
|
enc[1] = upperhex[b>>4]
|
||||||
|
enc[2] = upperhex[b&0x0f]
|
||||||
|
buf.Write(enc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buf.WriteString("?=")
|
||||||
|
|
||||||
|
es := buf.String()
|
||||||
|
putBuffer(buf)
|
||||||
|
return es
|
||||||
|
}
|
||||||
|
|
||||||
|
var bufPool = sync.Pool{
|
||||||
|
New: func() interface{} {
|
||||||
|
return new(bytes.Buffer)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func getBuffer() *bytes.Buffer {
|
||||||
|
return bufPool.Get().(*bytes.Buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
func putBuffer(buf *bytes.Buffer) {
|
||||||
|
if buf.Len() > 1024 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
buf.Reset()
|
||||||
|
bufPool.Put(buf)
|
||||||
|
}
|
||||||
|
26
vendor/github.com/astaxie/beego/utils/pagination/controller.go
generated
vendored
26
vendor/github.com/astaxie/beego/utils/pagination/controller.go
generated
vendored
@ -1,26 +0,0 @@
|
|||||||
// Copyright 2014 beego Author. All Rights Reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package pagination
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/astaxie/beego/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SetPaginator Instantiates a Paginator and assigns it to context.Input.Data["paginator"].
|
|
||||||
func SetPaginator(context *context.Context, per int, nums int64) (paginator *Paginator) {
|
|
||||||
paginator = NewPaginator(context.Request, per, nums)
|
|
||||||
context.Input.SetData("paginator", &paginator)
|
|
||||||
return
|
|
||||||
}
|
|
58
vendor/github.com/astaxie/beego/utils/pagination/doc.go
generated
vendored
58
vendor/github.com/astaxie/beego/utils/pagination/doc.go
generated
vendored
@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
Package pagination provides utilities to setup a paginator within the
|
|
||||||
context of a http request.
|
|
||||||
|
|
||||||
Usage
|
|
||||||
|
|
||||||
In your beego.Controller:
|
|
||||||
|
|
||||||
package controllers
|
|
||||||
|
|
||||||
import "github.com/astaxie/beego/utils/pagination"
|
|
||||||
|
|
||||||
type PostsController struct {
|
|
||||||
beego.Controller
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *PostsController) ListAllPosts() {
|
|
||||||
// sets this.Data["paginator"] with the current offset (from the url query param)
|
|
||||||
postsPerPage := 20
|
|
||||||
paginator := pagination.SetPaginator(this.Ctx, postsPerPage, CountPosts())
|
|
||||||
|
|
||||||
// fetch the next 20 posts
|
|
||||||
this.Data["posts"] = ListPostsByOffsetAndLimit(paginator.Offset(), postsPerPage)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
In your view templates:
|
|
||||||
|
|
||||||
{{if .paginator.HasPages}}
|
|
||||||
<ul class="pagination pagination">
|
|
||||||
{{if .paginator.HasPrev}}
|
|
||||||
<li><a href="{{.paginator.PageLinkFirst}}">{{ i18n .Lang "paginator.first_page"}}</a></li>
|
|
||||||
<li><a href="{{.paginator.PageLinkPrev}}">«</a></li>
|
|
||||||
{{else}}
|
|
||||||
<li class="disabled"><a>{{ i18n .Lang "paginator.first_page"}}</a></li>
|
|
||||||
<li class="disabled"><a>«</a></li>
|
|
||||||
{{end}}
|
|
||||||
{{range $index, $page := .paginator.Pages}}
|
|
||||||
<li{{if $.paginator.IsActive .}} class="active"{{end}}>
|
|
||||||
<a href="{{$.paginator.PageLink $page}}">{{$page}}</a>
|
|
||||||
</li>
|
|
||||||
{{end}}
|
|
||||||
{{if .paginator.HasNext}}
|
|
||||||
<li><a href="{{.paginator.PageLinkNext}}">»</a></li>
|
|
||||||
<li><a href="{{.paginator.PageLinkLast}}">{{ i18n .Lang "paginator.last_page"}}</a></li>
|
|
||||||
{{else}}
|
|
||||||
<li class="disabled"><a>»</a></li>
|
|
||||||
<li class="disabled"><a>{{ i18n .Lang "paginator.last_page"}}</a></li>
|
|
||||||
{{end}}
|
|
||||||
</ul>
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
See also
|
|
||||||
|
|
||||||
http://beego.me/docs/mvc/view/page.md
|
|
||||||
|
|
||||||
*/
|
|
||||||
package pagination
|
|
189
vendor/github.com/astaxie/beego/utils/pagination/paginator.go
generated
vendored
189
vendor/github.com/astaxie/beego/utils/pagination/paginator.go
generated
vendored
@ -1,189 +0,0 @@
|
|||||||
// Copyright 2014 beego Author. All Rights Reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package pagination
|
|
||||||
|
|
||||||
import (
|
|
||||||
"math"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Paginator within the state of a http request.
|
|
||||||
type Paginator struct {
|
|
||||||
Request *http.Request
|
|
||||||
PerPageNums int
|
|
||||||
MaxPages int
|
|
||||||
|
|
||||||
nums int64
|
|
||||||
pageRange []int
|
|
||||||
pageNums int
|
|
||||||
page int
|
|
||||||
}
|
|
||||||
|
|
||||||
// PageNums Returns the total number of pages.
|
|
||||||
func (p *Paginator) PageNums() int {
|
|
||||||
if p.pageNums != 0 {
|
|
||||||
return p.pageNums
|
|
||||||
}
|
|
||||||
pageNums := math.Ceil(float64(p.nums) / float64(p.PerPageNums))
|
|
||||||
if p.MaxPages > 0 {
|
|
||||||
pageNums = math.Min(pageNums, float64(p.MaxPages))
|
|
||||||
}
|
|
||||||
p.pageNums = int(pageNums)
|
|
||||||
return p.pageNums
|
|
||||||
}
|
|
||||||
|
|
||||||
// Nums Returns the total number of items (e.g. from doing SQL count).
|
|
||||||
func (p *Paginator) Nums() int64 {
|
|
||||||
return p.nums
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetNums Sets the total number of items.
|
|
||||||
func (p *Paginator) SetNums(nums interface{}) {
|
|
||||||
p.nums, _ = toInt64(nums)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Page Returns the current page.
|
|
||||||
func (p *Paginator) Page() int {
|
|
||||||
if p.page != 0 {
|
|
||||||
return p.page
|
|
||||||
}
|
|
||||||
if p.Request.Form == nil {
|
|
||||||
p.Request.ParseForm()
|
|
||||||
}
|
|
||||||
p.page, _ = strconv.Atoi(p.Request.Form.Get("p"))
|
|
||||||
if p.page > p.PageNums() {
|
|
||||||
p.page = p.PageNums()
|
|
||||||
}
|
|
||||||
if p.page <= 0 {
|
|
||||||
p.page = 1
|
|
||||||
}
|
|
||||||
return p.page
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pages Returns a list of all pages.
|
|
||||||
//
|
|
||||||
// Usage (in a view template):
|
|
||||||
//
|
|
||||||
// {{range $index, $page := .paginator.Pages}}
|
|
||||||
// <li{{if $.paginator.IsActive .}} class="active"{{end}}>
|
|
||||||
// <a href="{{$.paginator.PageLink $page}}">{{$page}}</a>
|
|
||||||
// </li>
|
|
||||||
// {{end}}
|
|
||||||
func (p *Paginator) Pages() []int {
|
|
||||||
if p.pageRange == nil && p.nums > 0 {
|
|
||||||
var pages []int
|
|
||||||
pageNums := p.PageNums()
|
|
||||||
page := p.Page()
|
|
||||||
switch {
|
|
||||||
case page >= pageNums-4 && pageNums > 9:
|
|
||||||
start := pageNums - 9 + 1
|
|
||||||
pages = make([]int, 9)
|
|
||||||
for i := range pages {
|
|
||||||
pages[i] = start + i
|
|
||||||
}
|
|
||||||
case page >= 5 && pageNums > 9:
|
|
||||||
start := page - 5 + 1
|
|
||||||
pages = make([]int, int(math.Min(9, float64(page+4+1))))
|
|
||||||
for i := range pages {
|
|
||||||
pages[i] = start + i
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
pages = make([]int, int(math.Min(9, float64(pageNums))))
|
|
||||||
for i := range pages {
|
|
||||||
pages[i] = i + 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
p.pageRange = pages
|
|
||||||
}
|
|
||||||
return p.pageRange
|
|
||||||
}
|
|
||||||
|
|
||||||
// PageLink Returns URL for a given page index.
|
|
||||||
func (p *Paginator) PageLink(page int) string {
|
|
||||||
link, _ := url.ParseRequestURI(p.Request.URL.String())
|
|
||||||
values := link.Query()
|
|
||||||
if page == 1 {
|
|
||||||
values.Del("p")
|
|
||||||
} else {
|
|
||||||
values.Set("p", strconv.Itoa(page))
|
|
||||||
}
|
|
||||||
link.RawQuery = values.Encode()
|
|
||||||
return link.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// PageLinkPrev Returns URL to the previous page.
|
|
||||||
func (p *Paginator) PageLinkPrev() (link string) {
|
|
||||||
if p.HasPrev() {
|
|
||||||
link = p.PageLink(p.Page() - 1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// PageLinkNext Returns URL to the next page.
|
|
||||||
func (p *Paginator) PageLinkNext() (link string) {
|
|
||||||
if p.HasNext() {
|
|
||||||
link = p.PageLink(p.Page() + 1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// PageLinkFirst Returns URL to the first page.
|
|
||||||
func (p *Paginator) PageLinkFirst() (link string) {
|
|
||||||
return p.PageLink(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// PageLinkLast Returns URL to the last page.
|
|
||||||
func (p *Paginator) PageLinkLast() (link string) {
|
|
||||||
return p.PageLink(p.PageNums())
|
|
||||||
}
|
|
||||||
|
|
||||||
// HasPrev Returns true if the current page has a predecessor.
|
|
||||||
func (p *Paginator) HasPrev() bool {
|
|
||||||
return p.Page() > 1
|
|
||||||
}
|
|
||||||
|
|
||||||
// HasNext Returns true if the current page has a successor.
|
|
||||||
func (p *Paginator) HasNext() bool {
|
|
||||||
return p.Page() < p.PageNums()
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsActive Returns true if the given page index points to the current page.
|
|
||||||
func (p *Paginator) IsActive(page int) bool {
|
|
||||||
return p.Page() == page
|
|
||||||
}
|
|
||||||
|
|
||||||
// Offset Returns the current offset.
|
|
||||||
func (p *Paginator) Offset() int {
|
|
||||||
return (p.Page() - 1) * p.PerPageNums
|
|
||||||
}
|
|
||||||
|
|
||||||
// HasPages Returns true if there is more than one page.
|
|
||||||
func (p *Paginator) HasPages() bool {
|
|
||||||
return p.PageNums() > 1
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewPaginator Instantiates a paginator struct for the current http request.
|
|
||||||
func NewPaginator(req *http.Request, per int, nums interface{}) *Paginator {
|
|
||||||
p := Paginator{}
|
|
||||||
p.Request = req
|
|
||||||
if per <= 0 {
|
|
||||||
per = 10
|
|
||||||
}
|
|
||||||
p.PerPageNums = per
|
|
||||||
p.SetNums(nums)
|
|
||||||
return &p
|
|
||||||
}
|
|
34
vendor/github.com/astaxie/beego/utils/pagination/utils.go
generated
vendored
34
vendor/github.com/astaxie/beego/utils/pagination/utils.go
generated
vendored
@ -1,34 +0,0 @@
|
|||||||
// Copyright 2014 beego Author. All Rights Reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package pagination
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"reflect"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ToInt64 convert any numeric value to int64
|
|
||||||
func toInt64(value interface{}) (d int64, err error) {
|
|
||||||
val := reflect.ValueOf(value)
|
|
||||||
switch value.(type) {
|
|
||||||
case int, int8, int16, int32, int64:
|
|
||||||
d = val.Int()
|
|
||||||
case uint, uint8, uint16, uint32, uint64:
|
|
||||||
d = int64(val.Uint())
|
|
||||||
default:
|
|
||||||
err = fmt.Errorf("ToInt64 need numeric not `%T`", value)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
2
vendor/github.com/astaxie/beego/validation/validators.go
generated
vendored
2
vendor/github.com/astaxie/beego/validation/validators.go
generated
vendored
@ -588,7 +588,7 @@ func (b Base64) GetLimitValue() interface{} {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// just for chinese mobile phone number
|
// just for chinese mobile phone number
|
||||||
var mobilePattern = regexp.MustCompile("^((\\+86)|(86))?(1(([35][0-9])|[8][0-9]|[7][0679]|[4][579]))\\d{8}$")
|
var mobilePattern = regexp.MustCompile("^((\\+86)|(86))?(1(([35][0-9])|[8][0-9]|[7][06789]|[4][579]))\\d{8}$")
|
||||||
|
|
||||||
// Mobile check struct
|
// Mobile check struct
|
||||||
type Mobile struct {
|
type Mobile struct {
|
||||||
|
89
vendor/vendor.json
vendored
Normal file
89
vendor/vendor.json
vendored
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
{
|
||||||
|
"comment": "",
|
||||||
|
"ignore": "test",
|
||||||
|
"package": [
|
||||||
|
{
|
||||||
|
"checksumSHA1": "G0MBhApkgOH9++JlIA8FPfU7j9Y=",
|
||||||
|
"path": "github.com/astaxie/beego",
|
||||||
|
"revision": "1aeb3d90512734def678c7aa9f612fe6f659e6b5",
|
||||||
|
"revisionTime": "2016-03-11T03:35:24Z",
|
||||||
|
"version": "v1.6.1",
|
||||||
|
"versionExact": "v1.6.1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"checksumSHA1": "gSSu0SO0GZIZrBgQpybXeNMWSJs=",
|
||||||
|
"path": "github.com/astaxie/beego/cache",
|
||||||
|
"revision": "88c5dfa6ead42e624c2e7d9e04eab6cb2d07412a",
|
||||||
|
"revisionTime": "2016-03-23T09:05:40Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"checksumSHA1": "raJhf500jq7AzIGIclRQBo0B5+s=",
|
||||||
|
"path": "github.com/astaxie/beego/config",
|
||||||
|
"revision": "1aeb3d90512734def678c7aa9f612fe6f659e6b5",
|
||||||
|
"revisionTime": "2016-03-11T03:35:24Z",
|
||||||
|
"version": "v1.6.1",
|
||||||
|
"versionExact": "v1.6.1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"checksumSHA1": "52Cnm/rmogm6vPa2jW9D6SuKm3g=",
|
||||||
|
"path": "github.com/astaxie/beego/context",
|
||||||
|
"revision": "1aeb3d90512734def678c7aa9f612fe6f659e6b5",
|
||||||
|
"revisionTime": "2016-03-11T03:35:24Z",
|
||||||
|
"version": "v1.6.1",
|
||||||
|
"versionExact": "v1.6.1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"checksumSHA1": "PDNn16w89zWODshT9zlPzSmWZFA=",
|
||||||
|
"path": "github.com/astaxie/beego/grace",
|
||||||
|
"revision": "1aeb3d90512734def678c7aa9f612fe6f659e6b5",
|
||||||
|
"revisionTime": "2016-03-11T03:35:24Z",
|
||||||
|
"version": "v1.6.1",
|
||||||
|
"versionExact": "v1.6.1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"checksumSHA1": "xxtx4xJs8UcrvaXNQ9A5QM9+oFg=",
|
||||||
|
"path": "github.com/astaxie/beego/logs",
|
||||||
|
"revision": "1aeb3d90512734def678c7aa9f612fe6f659e6b5",
|
||||||
|
"revisionTime": "2016-03-11T03:35:24Z",
|
||||||
|
"version": "v1.6.1",
|
||||||
|
"versionExact": "v1.6.1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"checksumSHA1": "4X7wg7DBwdaRW4W2dBf3U0+fTHc=",
|
||||||
|
"path": "github.com/astaxie/beego/orm",
|
||||||
|
"revision": "88c5dfa6ead42e624c2e7d9e04eab6cb2d07412a",
|
||||||
|
"revisionTime": "2016-03-23T09:05:40Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"checksumSHA1": "Zeh58fFq41Ym/YNH47O6gdm1Mh8=",
|
||||||
|
"path": "github.com/astaxie/beego/session",
|
||||||
|
"revision": "1aeb3d90512734def678c7aa9f612fe6f659e6b5",
|
||||||
|
"revisionTime": "2016-03-11T03:35:24Z",
|
||||||
|
"version": "v1.6.1",
|
||||||
|
"versionExact": "v1.6.1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"checksumSHA1": "Mu2lA5Jq0tRk9MjhWllyzcJD6KU=",
|
||||||
|
"path": "github.com/astaxie/beego/toolbox",
|
||||||
|
"revision": "1aeb3d90512734def678c7aa9f612fe6f659e6b5",
|
||||||
|
"revisionTime": "2016-03-11T03:35:24Z",
|
||||||
|
"version": "v1.6.1",
|
||||||
|
"versionExact": "v1.6.1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"checksumSHA1": "x90ZIgNp0dy/saCS+4tBR3gdQ6g=",
|
||||||
|
"path": "github.com/astaxie/beego/utils",
|
||||||
|
"revision": "1aeb3d90512734def678c7aa9f612fe6f659e6b5",
|
||||||
|
"revisionTime": "2016-03-11T03:35:24Z",
|
||||||
|
"version": "v1.6.1",
|
||||||
|
"versionExact": "v1.6.1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"checksumSHA1": "pt/trdXvFa8AvhR67iMhfvqNfDU=",
|
||||||
|
"path": "github.com/astaxie/beego/validation",
|
||||||
|
"revision": "88c5dfa6ead42e624c2e7d9e04eab6cb2d07412a",
|
||||||
|
"revisionTime": "2016-03-23T09:05:40Z"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"rootPath": "github.com/vmware/harbor"
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user