commit
f49c763025
@ -4,8 +4,8 @@ beego is an open source project.
|
|||||||
|
|
||||||
It is the work of hundreds of contributors. We appreciate your help!
|
It is the work of hundreds of contributors. We appreciate your help!
|
||||||
|
|
||||||
Here are instructions to get you started. They are probably not perfect,
|
Here are instructions to get you started. They are probably not perfect, please let us know if anything feels wrong or
|
||||||
please let us know if anything feels wrong or incomplete.
|
incomplete.
|
||||||
|
|
||||||
## Prepare environment
|
## Prepare environment
|
||||||
|
|
||||||
@ -18,6 +18,7 @@ go get -u github.com/gordonklaus/ineffassign
|
|||||||
```
|
```
|
||||||
|
|
||||||
Put those lines into your pre-commit githook script:
|
Put those lines into your pre-commit githook script:
|
||||||
|
|
||||||
```shell script
|
```shell script
|
||||||
goimports -w -format-only ./
|
goimports -w -format-only ./
|
||||||
|
|
||||||
@ -33,10 +34,13 @@ Beego uses many middlewares, including MySQL, Redis, SSDB and so on.
|
|||||||
We provide docker compose file to start all middlewares.
|
We provide docker compose file to start all middlewares.
|
||||||
|
|
||||||
You can run:
|
You can run:
|
||||||
|
|
||||||
```shell script
|
```shell script
|
||||||
docker-compose -f scripts/test_docker_compose.yml up -d
|
docker-compose -f scripts/test_docker_compose.yml up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
Unit tests read addresses from environment, here is an example:
|
Unit tests read addresses from environment, here is an example:
|
||||||
|
|
||||||
```shell script
|
```shell script
|
||||||
export ORM_DRIVER=mysql
|
export ORM_DRIVER=mysql
|
||||||
export ORM_SOURCE="beego:test@tcp(192.168.0.105:13306)/orm_test?charset=utf8"
|
export ORM_SOURCE="beego:test@tcp(192.168.0.105:13306)/orm_test?charset=utf8"
|
||||||
@ -45,34 +49,28 @@ export REDIS_ADDR="192.168.0.105:6379"
|
|||||||
export SSDB_ADDR="192.168.0.105:8888"
|
export SSDB_ADDR="192.168.0.105:8888"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## Contribution guidelines
|
## Contribution guidelines
|
||||||
|
|
||||||
### Pull requests
|
### Pull requests
|
||||||
|
|
||||||
First of all. beego follow the gitflow. So please send you pull request
|
First of all. beego follow the gitflow. So please send you pull request to **develop-2** branch. We will close the pull
|
||||||
to **develop-2** branch. We will close the pull request to master branch.
|
request to master branch.
|
||||||
|
|
||||||
We are always happy to receive pull requests, and do our best to
|
We are always happy to receive pull requests, and do our best to review them as fast as possible. Not sure if that typo
|
||||||
review them as fast as possible. Not sure if that typo is worth a pull
|
is worth a pull request? Do it! We will appreciate it.
|
||||||
request? Do it! We will appreciate it.
|
|
||||||
|
|
||||||
Don't forget to rebase your commits!
|
Don't forget to rebase your commits!
|
||||||
|
|
||||||
If your pull request is not accepted on the first try, don't be
|
If your pull request is not accepted on the first try, don't be discouraged! Sometimes we can make a mistake, please do
|
||||||
discouraged! Sometimes we can make a mistake, please do more explaining
|
more explaining for us. We will appreciate it.
|
||||||
for us. We will appreciate it.
|
|
||||||
|
|
||||||
We're trying very hard to keep beego simple and fast. We don't want it
|
We're trying very hard to keep beego simple and fast. We don't want it to do everything for everybody. This means that
|
||||||
to do everything for everybody. This means that we might decide against
|
we might decide against incorporating a new feature. But we will give you some advice on how to do it in other way.
|
||||||
incorporating a new feature. But we will give you some advice on how to
|
|
||||||
do it in other way.
|
|
||||||
|
|
||||||
### Create issues
|
### Create issues
|
||||||
|
|
||||||
Any significant improvement should be documented as [a GitHub
|
Any significant improvement should be documented as [a GitHub issue](https://github.com/beego/beego/v2/issues) before
|
||||||
issue](https://github.com/beego/beego/v2/issues) before anybody
|
anybody starts working on it.
|
||||||
starts working on it.
|
|
||||||
|
|
||||||
Also when filing an issue, make sure to answer these five questions:
|
Also when filing an issue, make sure to answer these five questions:
|
||||||
|
|
||||||
@ -84,10 +82,8 @@ Also when filing an issue, make sure to answer these five questions:
|
|||||||
|
|
||||||
### but check existing issues and docs first!
|
### but check existing issues and docs first!
|
||||||
|
|
||||||
Please take a moment to check that an issue doesn't already exist
|
Please take a moment to check that an issue doesn't already exist documenting your bug report or improvement proposal.
|
||||||
documenting your bug report or improvement proposal. If it does, it
|
If it does, it never hurts to add a quick "+1" or "I have this problem too". This will help prioritize the most common
|
||||||
never hurts to add a quick "+1" or "I have this problem too". This will
|
problems and requests.
|
||||||
help prioritize the most common problems and requests.
|
|
||||||
|
|
||||||
Also, if you don't know how to use it. please make sure you have read through
|
Also, if you don't know how to use it. please make sure you have read through the docs in http://beego.me/docs
|
||||||
the docs in http://beego.me/docs
|
|
||||||
|
|||||||
@ -9,6 +9,7 @@ embedding.
|
|||||||

|

|
||||||
|
|
||||||
Beego is compos of four parts:
|
Beego is compos of four parts:
|
||||||
|
|
||||||
1. Base modules: including log module, config module, governor module;
|
1. Base modules: including log module, config module, governor module;
|
||||||
2. Task: is used for running timed tasks or periodic tasks;
|
2. Task: is used for running timed tasks or periodic tasks;
|
||||||
3. Client: including ORM module, httplib module, cache module;
|
3. Client: including ORM module, httplib module, cache module;
|
||||||
@ -18,11 +19,10 @@ Beego is compos of four parts:
|
|||||||
|
|
||||||
[Officail website](http://beego.me)
|
[Officail website](http://beego.me)
|
||||||
|
|
||||||
[Example](https://github.com/beego-dev/beego-example)
|
[Example](https://github.com/beego/beego-example)
|
||||||
|
|
||||||
> If you could not open official website, go to [beedoc](https://github.com/beego/beedoc)
|
> If you could not open official website, go to [beedoc](https://github.com/beego/beedoc)
|
||||||
|
|
||||||
|
|
||||||
### Web Application
|
### Web Application
|
||||||
|
|
||||||

|

|
||||||
@ -73,6 +73,7 @@ Congratulations! You've just built your first **beego** app.
|
|||||||
* Full stack for Web & API
|
* Full stack for Web & API
|
||||||
|
|
||||||
## Modules
|
## Modules
|
||||||
|
|
||||||
* [orm](https://github.com/beego/beedoc/tree/master/en-US/mvc/model)
|
* [orm](https://github.com/beego/beedoc/tree/master/en-US/mvc/model)
|
||||||
* [session](https://github.com/beego/beedoc/blob/master/en-US/module/session.md)
|
* [session](https://github.com/beego/beedoc/blob/master/en-US/module/session.md)
|
||||||
* [logs](https://github.com/beego/beedoc/blob/master/en-US/module/logs.md)
|
* [logs](https://github.com/beego/beedoc/blob/master/en-US/module/logs.md)
|
||||||
|
|||||||
8
adapter/cache/cache_test.go
vendored
8
adapter/cache/cache_test.go
vendored
@ -26,7 +26,7 @@ func TestCacheIncr(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error("init err")
|
t.Error("init err")
|
||||||
}
|
}
|
||||||
//timeoutDuration := 10 * time.Second
|
// timeoutDuration := 10 * time.Second
|
||||||
|
|
||||||
bm.Put("edwardhey", 0, time.Second*20)
|
bm.Put("edwardhey", 0, time.Second*20)
|
||||||
wg := sync.WaitGroup{}
|
wg := sync.WaitGroup{}
|
||||||
@ -90,7 +90,7 @@ func TestCache(t *testing.T) {
|
|||||||
t.Error("delete err")
|
t.Error("delete err")
|
||||||
}
|
}
|
||||||
|
|
||||||
//test GetMulti
|
// test GetMulti
|
||||||
if err = bm.Put("astaxie", "author", timeoutDuration); err != nil {
|
if err = bm.Put("astaxie", "author", timeoutDuration); err != nil {
|
||||||
t.Error("set Error", err)
|
t.Error("set Error", err)
|
||||||
}
|
}
|
||||||
@ -157,7 +157,7 @@ func TestFileCache(t *testing.T) {
|
|||||||
t.Error("delete err")
|
t.Error("delete err")
|
||||||
}
|
}
|
||||||
|
|
||||||
//test string
|
// test string
|
||||||
if err = bm.Put("astaxie", "author", timeoutDuration); err != nil {
|
if err = bm.Put("astaxie", "author", timeoutDuration); err != nil {
|
||||||
t.Error("set Error", err)
|
t.Error("set Error", err)
|
||||||
}
|
}
|
||||||
@ -168,7 +168,7 @@ func TestFileCache(t *testing.T) {
|
|||||||
t.Error("get err")
|
t.Error("get err")
|
||||||
}
|
}
|
||||||
|
|
||||||
//test GetMulti
|
// test GetMulti
|
||||||
if err = bm.Put("astaxie1", "author1", timeoutDuration); err != nil {
|
if err = bm.Put("astaxie1", "author1", timeoutDuration); err != nil {
|
||||||
t.Error("set Error", err)
|
t.Error("set Error", err)
|
||||||
}
|
}
|
||||||
|
|||||||
4
adapter/cache/redis/redis_test.go
vendored
4
adapter/cache/redis/redis_test.go
vendored
@ -76,7 +76,7 @@ func TestRedisCache(t *testing.T) {
|
|||||||
t.Error("delete err")
|
t.Error("delete err")
|
||||||
}
|
}
|
||||||
|
|
||||||
//test string
|
// test string
|
||||||
if err = bm.Put("astaxie", "author", timeoutDuration); err != nil {
|
if err = bm.Put("astaxie", "author", timeoutDuration); err != nil {
|
||||||
t.Error("set Error", err)
|
t.Error("set Error", err)
|
||||||
}
|
}
|
||||||
@ -88,7 +88,7 @@ func TestRedisCache(t *testing.T) {
|
|||||||
t.Error("get err")
|
t.Error("get err")
|
||||||
}
|
}
|
||||||
|
|
||||||
//test GetMulti
|
// test GetMulti
|
||||||
if err = bm.Put("astaxie1", "author1", timeoutDuration); err != nil {
|
if err = bm.Put("astaxie1", "author1", timeoutDuration); err != nil {
|
||||||
t.Error("set Error", err)
|
t.Error("set Error", err)
|
||||||
}
|
}
|
||||||
|
|||||||
8
adapter/cache/ssdb/ssdb_test.go
vendored
8
adapter/cache/ssdb/ssdb_test.go
vendored
@ -26,7 +26,7 @@ func TestSsdbcacheCache(t *testing.T) {
|
|||||||
t.Error("check err")
|
t.Error("check err")
|
||||||
}
|
}
|
||||||
timeoutDuration := 10 * time.Second
|
timeoutDuration := 10 * time.Second
|
||||||
//timeoutDuration := -10*time.Second if timeoutDuration is negtive,it means permanent
|
// timeoutDuration := -10*time.Second if timeoutDuration is negtive,it means permanent
|
||||||
if err = ssdb.Put("ssdb", "ssdb", timeoutDuration); err != nil {
|
if err = ssdb.Put("ssdb", "ssdb", timeoutDuration); err != nil {
|
||||||
t.Error("set Error", err)
|
t.Error("set Error", err)
|
||||||
}
|
}
|
||||||
@ -43,7 +43,7 @@ func TestSsdbcacheCache(t *testing.T) {
|
|||||||
t.Error("get Error")
|
t.Error("get Error")
|
||||||
}
|
}
|
||||||
|
|
||||||
//inc/dec test done
|
// inc/dec test done
|
||||||
if err = ssdb.Put("ssdb", "2", timeoutDuration); err != nil {
|
if err = ssdb.Put("ssdb", "2", timeoutDuration); err != nil {
|
||||||
t.Error("set Error", err)
|
t.Error("set Error", err)
|
||||||
}
|
}
|
||||||
@ -72,7 +72,7 @@ func TestSsdbcacheCache(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//test string
|
// test string
|
||||||
if err = ssdb.Put("ssdb", "ssdb", -10*time.Second); err != nil {
|
if err = ssdb.Put("ssdb", "ssdb", -10*time.Second); err != nil {
|
||||||
t.Error("set Error", err)
|
t.Error("set Error", err)
|
||||||
}
|
}
|
||||||
@ -83,7 +83,7 @@ func TestSsdbcacheCache(t *testing.T) {
|
|||||||
t.Error("get err")
|
t.Error("get err")
|
||||||
}
|
}
|
||||||
|
|
||||||
//test GetMulti done
|
// test GetMulti done
|
||||||
if err = ssdb.Put("ssdb1", "ssdb1", -10*time.Second); err != nil {
|
if err = ssdb.Put("ssdb1", "ssdb1", -10*time.Second); err != nil {
|
||||||
t.Error("set Error", err)
|
t.Error("set Error", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,7 +25,7 @@ import (
|
|||||||
func TestXML(t *testing.T) {
|
func TestXML(t *testing.T) {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
//xml parse should incluce in <config></config> tags
|
// xml parse should incluce in <config></config> tags
|
||||||
xmlcontext = `<?xml version="1.0" encoding="UTF-8"?>
|
xmlcontext = `<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<config>
|
<config>
|
||||||
<appname>beeapi</appname>
|
<appname>beeapi</appname>
|
||||||
|
|||||||
@ -212,7 +212,7 @@ func (c *Controller) ServeFormatted(encoding ...bool) {
|
|||||||
|
|
||||||
// Input returns the input data map from POST or PUT request body and query string.
|
// Input returns the input data map from POST or PUT request body and query string.
|
||||||
func (c *Controller) Input() url.Values {
|
func (c *Controller) Input() url.Values {
|
||||||
val, _ := (*web.Controller)(c).Input()
|
val, _ := (*web.Controller)(c).Input()
|
||||||
return val
|
return val
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -19,10 +19,11 @@ import (
|
|||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/casbin/casbin"
|
||||||
|
|
||||||
beego "github.com/beego/beego/v2/adapter"
|
beego "github.com/beego/beego/v2/adapter"
|
||||||
"github.com/beego/beego/v2/adapter/context"
|
"github.com/beego/beego/v2/adapter/context"
|
||||||
"github.com/beego/beego/v2/adapter/plugins/auth"
|
"github.com/beego/beego/v2/adapter/plugins/auth"
|
||||||
"github.com/casbin/casbin"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func testRequest(t *testing.T, handler *beego.ControllerRegister, user string, path string, method string, code int) {
|
func testRequest(t *testing.T, handler *beego.ControllerRegister, user string, path string, method string, code int) {
|
||||||
|
|||||||
11
client/cache/README.md
vendored
11
client/cache/README.md
vendored
@ -1,17 +1,15 @@
|
|||||||
## cache
|
## cache
|
||||||
cache is a Go cache manager. It can use many cache adapters. The repo is inspired by `database/sql` .
|
|
||||||
|
|
||||||
|
cache is a Go cache manager. It can use many cache adapters. The repo is inspired by `database/sql` .
|
||||||
|
|
||||||
## How to install?
|
## How to install?
|
||||||
|
|
||||||
go get github.com/beego/beego/v2/cache
|
go get github.com/beego/beego/v2/cache
|
||||||
|
|
||||||
|
|
||||||
## What adapters are supported?
|
## What adapters are supported?
|
||||||
|
|
||||||
As of now this cache support memory, Memcache and Redis.
|
As of now this cache support memory, Memcache and Redis.
|
||||||
|
|
||||||
|
|
||||||
## How to use it?
|
## How to use it?
|
||||||
|
|
||||||
First you must import it
|
First you must import it
|
||||||
@ -24,14 +22,13 @@ Then init a Cache (example with memory adapter)
|
|||||||
|
|
||||||
bm, err := cache.NewCache("memory", `{"interval":60}`)
|
bm, err := cache.NewCache("memory", `{"interval":60}`)
|
||||||
|
|
||||||
Use it like this:
|
Use it like this:
|
||||||
|
|
||||||
bm.Put("astaxie", 1, 10 * time.Second)
|
bm.Put("astaxie", 1, 10 * time.Second)
|
||||||
bm.Get("astaxie")
|
bm.Get("astaxie")
|
||||||
bm.IsExist("astaxie")
|
bm.IsExist("astaxie")
|
||||||
bm.Delete("astaxie")
|
bm.Delete("astaxie")
|
||||||
|
|
||||||
|
|
||||||
## Memory adapter
|
## Memory adapter
|
||||||
|
|
||||||
Configure memory adapter like this:
|
Configure memory adapter like this:
|
||||||
@ -40,7 +37,6 @@ Configure memory adapter like this:
|
|||||||
|
|
||||||
interval means the gc time. The cache will check at each time interval, whether item has expired.
|
interval means the gc time. The cache will check at each time interval, whether item has expired.
|
||||||
|
|
||||||
|
|
||||||
## Memcache adapter
|
## Memcache adapter
|
||||||
|
|
||||||
Memcache adapter use the [gomemcache](http://github.com/bradfitz/gomemcache) client.
|
Memcache adapter use the [gomemcache](http://github.com/bradfitz/gomemcache) client.
|
||||||
@ -49,7 +45,6 @@ Configure like this:
|
|||||||
|
|
||||||
{"conn":"127.0.0.1:11211"}
|
{"conn":"127.0.0.1:11211"}
|
||||||
|
|
||||||
|
|
||||||
## Redis adapter
|
## Redis adapter
|
||||||
|
|
||||||
Redis adapter use the [redigo](http://github.com/gomodule/redigo) client.
|
Redis adapter use the [redigo](http://github.com/gomodule/redigo) client.
|
||||||
|
|||||||
2
client/cache/ssdb/ssdb.go
vendored
2
client/cache/ssdb/ssdb.go
vendored
@ -20,7 +20,7 @@ type Cache struct {
|
|||||||
conninfo []string
|
conninfo []string
|
||||||
}
|
}
|
||||||
|
|
||||||
//NewSsdbCache creates new ssdb adapter.
|
// NewSsdbCache creates new ssdb adapter.
|
||||||
func NewSsdbCache() cache.Cache {
|
func NewSsdbCache() cache.Cache {
|
||||||
return &Cache{}
|
return &Cache{}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,11 @@
|
|||||||
# httplib
|
# httplib
|
||||||
|
|
||||||
httplib is an libs help you to curl remote url.
|
httplib is an libs help you to curl remote url.
|
||||||
|
|
||||||
# How to use?
|
# How to use?
|
||||||
|
|
||||||
## GET
|
## GET
|
||||||
|
|
||||||
you can use Get to crawl data.
|
you can use Get to crawl data.
|
||||||
|
|
||||||
import "github.com/beego/beego/v2/httplib"
|
import "github.com/beego/beego/v2/httplib"
|
||||||
@ -13,8 +15,9 @@ you can use Get to crawl data.
|
|||||||
// error
|
// error
|
||||||
}
|
}
|
||||||
fmt.Println(str)
|
fmt.Println(str)
|
||||||
|
|
||||||
## POST
|
## POST
|
||||||
|
|
||||||
POST data to remote url
|
POST data to remote url
|
||||||
|
|
||||||
req := httplib.Post("http://beego.me/")
|
req := httplib.Post("http://beego.me/")
|
||||||
@ -40,13 +43,12 @@ Example:
|
|||||||
// POST
|
// POST
|
||||||
httplib.Post("http://beego.me/").SetTimeout(100 * time.Second, 30 * time.Second)
|
httplib.Post("http://beego.me/").SetTimeout(100 * time.Second, 30 * time.Second)
|
||||||
|
|
||||||
|
|
||||||
## Debug
|
## Debug
|
||||||
|
|
||||||
If you want to debug the request info, set the debug on
|
If you want to debug the request info, set the debug on
|
||||||
|
|
||||||
httplib.Get("http://beego.me/").Debug(true)
|
httplib.Get("http://beego.me/").Debug(true)
|
||||||
|
|
||||||
## Set HTTP Basic Auth
|
## Set HTTP Basic Auth
|
||||||
|
|
||||||
str, err := Get("http://beego.me/").SetBasicAuth("user", "passwd").String()
|
str, err := Get("http://beego.me/").SetBasicAuth("user", "passwd").String()
|
||||||
@ -54,21 +56,21 @@ If you want to debug the request info, set the debug on
|
|||||||
// error
|
// error
|
||||||
}
|
}
|
||||||
fmt.Println(str)
|
fmt.Println(str)
|
||||||
|
|
||||||
## Set HTTPS
|
## Set HTTPS
|
||||||
|
|
||||||
If request url is https, You can set the client support TSL:
|
If request url is https, You can set the client support TSL:
|
||||||
|
|
||||||
httplib.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true})
|
httplib.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true})
|
||||||
|
|
||||||
More info about the `tls.Config` please visit http://golang.org/pkg/crypto/tls/#Config
|
More info about the `tls.Config` please visit http://golang.org/pkg/crypto/tls/#Config
|
||||||
|
|
||||||
## Set HTTP Version
|
## Set HTTP Version
|
||||||
|
|
||||||
some servers need to specify the protocol version of HTTP
|
some servers need to specify the protocol version of HTTP
|
||||||
|
|
||||||
httplib.Get("http://beego.me/").SetProtocolVersion("HTTP/1.1")
|
httplib.Get("http://beego.me/").SetProtocolVersion("HTTP/1.1")
|
||||||
|
|
||||||
## Set Cookie
|
## Set Cookie
|
||||||
|
|
||||||
some http request need setcookie. So set it like this:
|
some http request need setcookie. So set it like this:
|
||||||
@ -91,7 +93,6 @@ httplib support mutil file upload, use `req.PostFile()`
|
|||||||
}
|
}
|
||||||
fmt.Println(str)
|
fmt.Println(str)
|
||||||
|
|
||||||
|
|
||||||
See godoc for further documentation and examples.
|
See godoc for further documentation and examples.
|
||||||
|
|
||||||
* [godoc.org/github.com/beego/beego/v2/httplib](https://godoc.org/github.com/beego/beego/v2/httplib)
|
* [godoc.org/github.com/beego/beego/v2/httplib](https://godoc.org/github.com/beego/beego/v2/httplib)
|
||||||
|
|||||||
@ -18,10 +18,11 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/beego/beego/v2/client/httplib"
|
|
||||||
logKit "github.com/go-kit/kit/log"
|
logKit "github.com/go-kit/kit/log"
|
||||||
opentracingKit "github.com/go-kit/kit/tracing/opentracing"
|
opentracingKit "github.com/go-kit/kit/tracing/opentracing"
|
||||||
"github.com/opentracing/opentracing-go"
|
"github.com/opentracing/opentracing-go"
|
||||||
|
|
||||||
|
"github.com/beego/beego/v2/client/httplib"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FilterChainBuilder struct {
|
type FilterChainBuilder struct {
|
||||||
|
|||||||
@ -101,7 +101,7 @@ func TestSimplePost(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//func TestPostFile(t *testing.T) {
|
// func TestPostFile(t *testing.T) {
|
||||||
// v := "smallfish"
|
// v := "smallfish"
|
||||||
// req := Post("http://httpbin.org/post")
|
// req := Post("http://httpbin.org/post")
|
||||||
// req.Debug(true)
|
// req.Debug(true)
|
||||||
@ -118,7 +118,7 @@ func TestSimplePost(t *testing.T) {
|
|||||||
// if n == -1 {
|
// if n == -1 {
|
||||||
// t.Fatal(v + " not found in post")
|
// t.Fatal(v + " not found in post")
|
||||||
// }
|
// }
|
||||||
//}
|
// }
|
||||||
|
|
||||||
func TestSimplePut(t *testing.T) {
|
func TestSimplePut(t *testing.T) {
|
||||||
str, err := Put("http://httpbin.org/put").String()
|
str, err := Put("http://httpbin.org/put").String()
|
||||||
|
|||||||
@ -524,7 +524,7 @@ func (d *dbBase) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Value, a
|
|||||||
return 0, fmt.Errorf("`%s` nonsupport InsertOrUpdate in beego", a.DriverName)
|
return 0, fmt.Errorf("`%s` nonsupport InsertOrUpdate in beego", a.DriverName)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Get on the key-value pairs
|
// Get on the key-value pairs
|
||||||
for _, v := range args {
|
for _, v := range args {
|
||||||
kv := strings.Split(v, "=")
|
kv := strings.Split(v, "=")
|
||||||
if len(kv) == 2 {
|
if len(kv) == 2 {
|
||||||
@ -559,7 +559,7 @@ func (d *dbBase) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Value, a
|
|||||||
updates[i] = v + "=" + valueStr
|
updates[i] = v + "=" + valueStr
|
||||||
case DRPostgres:
|
case DRPostgres:
|
||||||
if conflitValue != nil {
|
if conflitValue != nil {
|
||||||
//postgres ON CONFLICT DO UPDATE SET can`t use colu=colu+values
|
// postgres ON CONFLICT DO UPDATE SET can`t use colu=colu+values
|
||||||
updates[i] = fmt.Sprintf("%s=(select %s from %s where %s = ? )", v, valueStr, mi.table, args0)
|
updates[i] = fmt.Sprintf("%s=(select %s from %s where %s = ? )", v, valueStr, mi.table, args0)
|
||||||
updateValues = append(updateValues, conflitValue)
|
updateValues = append(updateValues, conflitValue)
|
||||||
} else {
|
} else {
|
||||||
@ -584,7 +584,7 @@ func (d *dbBase) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Value, a
|
|||||||
if isMulti {
|
if isMulti {
|
||||||
qmarks = strings.Repeat(qmarks+"), (", multi-1) + qmarks
|
qmarks = strings.Repeat(qmarks+"), (", multi-1) + qmarks
|
||||||
}
|
}
|
||||||
//conflitValue maybe is a int,can`t use fmt.Sprintf
|
// conflitValue maybe is a int,can`t use fmt.Sprintf
|
||||||
query := fmt.Sprintf("INSERT INTO %s%s%s (%s%s%s) VALUES (%s) %s "+qupdates, Q, mi.table, Q, Q, columns, Q, qmarks, iouStr)
|
query := fmt.Sprintf("INSERT INTO %s%s%s (%s%s%s) VALUES (%s) %s "+qupdates, Q, mi.table, Q, Q, columns, Q, qmarks, iouStr)
|
||||||
|
|
||||||
d.ins.ReplaceMarks(&query)
|
d.ins.ReplaceMarks(&query)
|
||||||
|
|||||||
@ -111,7 +111,7 @@ func (d *dbBaseMysql) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Val
|
|||||||
|
|
||||||
iouStr = "ON DUPLICATE KEY UPDATE"
|
iouStr = "ON DUPLICATE KEY UPDATE"
|
||||||
|
|
||||||
//Get on the key-value pairs
|
// Get on the key-value pairs
|
||||||
for _, v := range args {
|
for _, v := range args {
|
||||||
kv := strings.Split(v, "=")
|
kv := strings.Split(v, "=")
|
||||||
if len(kv) == 2 {
|
if len(kv) == 2 {
|
||||||
@ -155,7 +155,7 @@ func (d *dbBaseMysql) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Val
|
|||||||
if isMulti {
|
if isMulti {
|
||||||
qmarks = strings.Repeat(qmarks+"), (", multi-1) + qmarks
|
qmarks = strings.Repeat(qmarks+"), (", multi-1) + qmarks
|
||||||
}
|
}
|
||||||
//conflitValue maybe is a int,can`t use fmt.Sprintf
|
// conflitValue maybe is a int,can`t use fmt.Sprintf
|
||||||
query := fmt.Sprintf("INSERT INTO %s%s%s (%s%s%s) VALUES (%s) %s "+qupdates, Q, mi.table, Q, Q, columns, Q, qmarks, iouStr)
|
query := fmt.Sprintf("INSERT INTO %s%s%s (%s%s%s) VALUES (%s) %s "+qupdates, Q, mi.table, Q, Q, columns, Q, qmarks, iouStr)
|
||||||
|
|
||||||
d.ins.ReplaceMarks(&query)
|
d.ins.ReplaceMarks(&query)
|
||||||
|
|||||||
@ -77,7 +77,7 @@ func (d *dbBaseOracle) DbTypes() map[string]string {
|
|||||||
return oracleTypes
|
return oracleTypes
|
||||||
}
|
}
|
||||||
|
|
||||||
//ShowTablesQuery show all the tables in database
|
// ShowTablesQuery show all the tables in database
|
||||||
func (d *dbBaseOracle) ShowTablesQuery() string {
|
func (d *dbBaseOracle) ShowTablesQuery() string {
|
||||||
return "SELECT TABLE_NAME FROM USER_TABLES"
|
return "SELECT TABLE_NAME FROM USER_TABLES"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,7 +19,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
//query level
|
// query level
|
||||||
KeyForceIndex = iota
|
KeyForceIndex = iota
|
||||||
KeyUseIndex
|
KeyUseIndex
|
||||||
KeyIgnoreIndex
|
KeyIgnoreIndex
|
||||||
|
|||||||
@ -52,7 +52,7 @@ type Migrationer interface {
|
|||||||
GetCreated() int64
|
GetCreated() int64
|
||||||
}
|
}
|
||||||
|
|
||||||
//Migration defines the migrations by either SQL or DDL
|
// Migration defines the migrations by either SQL or DDL
|
||||||
type Migration struct {
|
type Migration struct {
|
||||||
sqls []string
|
sqls []string
|
||||||
Created string
|
Created string
|
||||||
@ -104,7 +104,7 @@ func (m *Migration) Down() {
|
|||||||
m.sqls = append(m.sqls, m.GetSQL())
|
m.sqls = append(m.sqls, m.GetSQL())
|
||||||
}
|
}
|
||||||
|
|
||||||
//Migrate adds the SQL to the execution list
|
// Migrate adds the SQL to the execution list
|
||||||
func (m *Migration) Migrate(migrationType string) {
|
func (m *Migration) Migrate(migrationType string) {
|
||||||
m.ModifyType = migrationType
|
m.ModifyType = migrationType
|
||||||
m.sqls = append(m.sqls, m.GetSQL())
|
m.sqls = append(m.sqls, m.GetSQL())
|
||||||
|
|||||||
@ -45,7 +45,7 @@ type _modelCache struct {
|
|||||||
done bool
|
done bool
|
||||||
}
|
}
|
||||||
|
|
||||||
//NewModelCacheHandler generator of _modelCache
|
// NewModelCacheHandler generator of _modelCache
|
||||||
func NewModelCacheHandler() *_modelCache {
|
func NewModelCacheHandler() *_modelCache {
|
||||||
return &_modelCache{
|
return &_modelCache{
|
||||||
cache: make(map[string]*modelInfo),
|
cache: make(map[string]*modelInfo),
|
||||||
@ -113,7 +113,7 @@ func (mc *_modelCache) clean() {
|
|||||||
mc.done = false
|
mc.done = false
|
||||||
}
|
}
|
||||||
|
|
||||||
//bootstrap bootstrap for models
|
// bootstrap bootstrap for models
|
||||||
func (mc *_modelCache) bootstrap() {
|
func (mc *_modelCache) bootstrap() {
|
||||||
mc.Lock()
|
mc.Lock()
|
||||||
defer mc.Unlock()
|
defer mc.Unlock()
|
||||||
@ -407,7 +407,7 @@ func (mc *_modelCache) register(prefixOrSuffixStr string, prefixOrSuffix bool, m
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//getDbDropSQL get database scheme drop sql queries
|
// getDbDropSQL get database scheme drop sql queries
|
||||||
func (mc *_modelCache) getDbDropSQL(al *alias) (queries []string, err error) {
|
func (mc *_modelCache) getDbDropSQL(al *alias) (queries []string, err error) {
|
||||||
if len(mc.cache) == 0 {
|
if len(mc.cache) == 0 {
|
||||||
err = errors.New("no Model found, need register your model")
|
err = errors.New("no Model found, need register your model")
|
||||||
@ -422,7 +422,7 @@ func (mc *_modelCache) getDbDropSQL(al *alias) (queries []string, err error) {
|
|||||||
return queries, nil
|
return queries, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//getDbCreateSQL get database scheme creation sql queries
|
// getDbCreateSQL get database scheme creation sql queries
|
||||||
func (mc *_modelCache) getDbCreateSQL(al *alias) (queries []string, tableIndexes map[string][]dbIndex, err error) {
|
func (mc *_modelCache) getDbCreateSQL(al *alias) (queries []string, tableIndexes map[string][]dbIndex, err error) {
|
||||||
if len(mc.cache) == 0 {
|
if len(mc.cache) == 0 {
|
||||||
err = errors.New("no Model found, need register your model")
|
err = errors.New("no Model found, need register your model")
|
||||||
@ -467,9 +467,9 @@ func (mc *_modelCache) getDbCreateSQL(al *alias) (queries []string, tableIndexes
|
|||||||
column += " " + "NOT NULL"
|
column += " " + "NOT NULL"
|
||||||
}
|
}
|
||||||
|
|
||||||
//if fi.initial.String() != "" {
|
// if fi.initial.String() != "" {
|
||||||
// column += " DEFAULT " + fi.initial.String()
|
// column += " DEFAULT " + fi.initial.String()
|
||||||
//}
|
// }
|
||||||
|
|
||||||
// Append attribute DEFAULT
|
// Append attribute DEFAULT
|
||||||
column += getColumnDefault(fi)
|
column += getColumnDefault(fi)
|
||||||
|
|||||||
@ -74,7 +74,7 @@ func addModelFields(mi *modelInfo, ind reflect.Value, mName string, index []int)
|
|||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
//record current field index
|
// record current field index
|
||||||
fi.fieldIndex = append(fi.fieldIndex, index...)
|
fi.fieldIndex = append(fi.fieldIndex, index...)
|
||||||
fi.fieldIndex = append(fi.fieldIndex, i)
|
fi.fieldIndex = append(fi.fieldIndex, i)
|
||||||
fi.mi = mi
|
fi.mi = mi
|
||||||
|
|||||||
@ -29,7 +29,7 @@ type Log struct {
|
|||||||
*log.Logger
|
*log.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
//costomer log func
|
// costomer log func
|
||||||
var LogFunc func(query map[string]interface{})
|
var LogFunc func(query map[string]interface{})
|
||||||
|
|
||||||
// NewLog set io.Writer to create a Logger.
|
// NewLog set io.Writer to create a Logger.
|
||||||
|
|||||||
@ -95,13 +95,13 @@ type Fielder interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type TxBeginner interface {
|
type TxBeginner interface {
|
||||||
//self control transaction
|
// self control transaction
|
||||||
Begin() (TxOrmer, error)
|
Begin() (TxOrmer, error)
|
||||||
BeginWithCtx(ctx context.Context) (TxOrmer, error)
|
BeginWithCtx(ctx context.Context) (TxOrmer, error)
|
||||||
BeginWithOpts(opts *sql.TxOptions) (TxOrmer, error)
|
BeginWithOpts(opts *sql.TxOptions) (TxOrmer, error)
|
||||||
BeginWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions) (TxOrmer, error)
|
BeginWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions) (TxOrmer, error)
|
||||||
|
|
||||||
//closure control transaction
|
// closure control transaction
|
||||||
DoTx(task func(ctx context.Context, txOrm TxOrmer) error) error
|
DoTx(task func(ctx context.Context, txOrm TxOrmer) error) error
|
||||||
DoTxWithCtx(ctx context.Context, task func(ctx context.Context, txOrm TxOrmer) error) error
|
DoTxWithCtx(ctx context.Context, task func(ctx context.Context, txOrm TxOrmer) error) error
|
||||||
DoTxWithOpts(opts *sql.TxOptions, task func(ctx context.Context, txOrm TxOrmer) error) error
|
DoTxWithOpts(opts *sql.TxOptions, task func(ctx context.Context, txOrm TxOrmer) error) error
|
||||||
@ -113,7 +113,7 @@ type TxCommitter interface {
|
|||||||
Rollback() error
|
Rollback() error
|
||||||
}
|
}
|
||||||
|
|
||||||
//Data Manipulation Language
|
// Data Manipulation Language
|
||||||
type DML interface {
|
type DML interface {
|
||||||
// insert model data to database
|
// insert model data to database
|
||||||
// for example:
|
// for example:
|
||||||
|
|||||||
@ -1,17 +1,15 @@
|
|||||||
## logs
|
## logs
|
||||||
logs is a Go logs manager. It can use many logs adapters. The repo is inspired by `database/sql` .
|
|
||||||
|
|
||||||
|
logs is a Go logs manager. It can use many logs adapters. The repo is inspired by `database/sql` .
|
||||||
|
|
||||||
## How to install?
|
## How to install?
|
||||||
|
|
||||||
go get github.com/beego/beego/v2/logs
|
go get github.com/beego/beego/v2/logs
|
||||||
|
|
||||||
|
|
||||||
## What adapters are supported?
|
## What adapters are supported?
|
||||||
|
|
||||||
As of now this logs support console, file,smtp and conn.
|
As of now this logs support console, file,smtp and conn.
|
||||||
|
|
||||||
|
|
||||||
## How to use it?
|
## How to use it?
|
||||||
|
|
||||||
First you must import it
|
First you must import it
|
||||||
|
|||||||
@ -58,7 +58,7 @@ func TestConsoleAsync(t *testing.T) {
|
|||||||
log := NewLogger(100)
|
log := NewLogger(100)
|
||||||
log.SetLogger("console")
|
log.SetLogger("console")
|
||||||
log.Async()
|
log.Async()
|
||||||
//log.Close()
|
// log.Close()
|
||||||
testConsoleCalls(log)
|
testConsoleCalls(log)
|
||||||
for len(log.msgChan) != 0 {
|
for len(log.msgChan) != 0 {
|
||||||
time.Sleep(1 * time.Millisecond)
|
time.Sleep(1 * time.Millisecond)
|
||||||
|
|||||||
@ -164,7 +164,7 @@ func TestFileDailyRotate_05(t *testing.T) {
|
|||||||
testFileDailyRotate(t, fn1, fn2)
|
testFileDailyRotate(t, fn1, fn2)
|
||||||
os.Remove(fn)
|
os.Remove(fn)
|
||||||
}
|
}
|
||||||
func TestFileDailyRotate_06(t *testing.T) { //test file mode
|
func TestFileDailyRotate_06(t *testing.T) { // test file mode
|
||||||
log := NewLogger(10000)
|
log := NewLogger(10000)
|
||||||
log.SetLogger("file", `{"filename":"test3.log","maxlines":4}`)
|
log.SetLogger("file", `{"filename":"test3.log","maxlines":4}`)
|
||||||
log.Debug("debug")
|
log.Debug("debug")
|
||||||
@ -237,7 +237,7 @@ func TestFileHourlyRotate_05(t *testing.T) {
|
|||||||
os.Remove(fn)
|
os.Remove(fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFileHourlyRotate_06(t *testing.T) { //test file mode
|
func TestFileHourlyRotate_06(t *testing.T) { // test file mode
|
||||||
log := NewLogger(10000)
|
log := NewLogger(10000)
|
||||||
log.SetLogger("file", `{"filename":"test3.log", "hourly":true, "maxlines":4}`)
|
log.SetLogger("file", `{"filename":"test3.log", "hourly":true, "maxlines":4}`)
|
||||||
log.Debug("debug")
|
log.Debug("debug")
|
||||||
|
|||||||
@ -60,7 +60,7 @@ func formatTimeHeader(when time.Time) ([]byte, int, int) {
|
|||||||
y, mo, d := when.Date()
|
y, mo, d := when.Date()
|
||||||
h, mi, s := when.Clock()
|
h, mi, s := when.Clock()
|
||||||
ns := when.Nanosecond() / 1000000
|
ns := when.Nanosecond() / 1000000
|
||||||
//len("2006/01/02 15:04:05.123 ")==24
|
// len("2006/01/02 15:04:05.123 ")==24
|
||||||
var buf [24]byte
|
var buf [24]byte
|
||||||
|
|
||||||
buf[0] = y1[y/1000%10]
|
buf[0] = y1[y/1000%10]
|
||||||
@ -126,12 +126,12 @@ func initColor() {
|
|||||||
cyan = w32Cyan
|
cyan = w32Cyan
|
||||||
}
|
}
|
||||||
colorMap = map[string]string{
|
colorMap = map[string]string{
|
||||||
//by color
|
// by color
|
||||||
"green": green,
|
"green": green,
|
||||||
"white": white,
|
"white": white,
|
||||||
"yellow": yellow,
|
"yellow": yellow,
|
||||||
"red": red,
|
"red": red,
|
||||||
//by method
|
// by method
|
||||||
"GET": blue,
|
"GET": blue,
|
||||||
"POST": cyan,
|
"POST": cyan,
|
||||||
"PUT": yellow,
|
"PUT": yellow,
|
||||||
|
|||||||
@ -188,10 +188,10 @@ func (e *Email) Attach(r io.Reader, filename string, args ...string) (a *Attachm
|
|||||||
err = errors.New("Must specify the file type and number of parameters can not exceed at least two")
|
err = errors.New("Must specify the file type and number of parameters can not exceed at least two")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c := args[0] //Content-Type
|
c := args[0] // Content-Type
|
||||||
id := ""
|
id := ""
|
||||||
if len(args) > 1 {
|
if len(args) > 1 {
|
||||||
id = args[1] //Content-ID
|
id = args[1] // Content-ID
|
||||||
}
|
}
|
||||||
var buffer bytes.Buffer
|
var buffer bytes.Buffer
|
||||||
if _, err = io.Copy(&buffer, r); err != nil {
|
if _, err = io.Copy(&buffer, r); err != nil {
|
||||||
|
|||||||
@ -141,7 +141,6 @@ Struct Tag Functions:
|
|||||||
Phone
|
Phone
|
||||||
ZipCode
|
ZipCode
|
||||||
|
|
||||||
|
|
||||||
## LICENSE
|
## LICENSE
|
||||||
|
|
||||||
BSD License http://creativecommons.org/licenses/BSD/
|
BSD License http://creativecommons.org/licenses/BSD/
|
||||||
|
|||||||
@ -423,7 +423,7 @@ func (v *Validation) Valid(obj interface{}) (b bool, err error) {
|
|||||||
// Step2: If pass on step1, then reflect obj's fields
|
// Step2: If pass on step1, then reflect obj's fields
|
||||||
// Step3: Do the Recursively validation to all struct or struct pointer fields
|
// Step3: Do the Recursively validation to all struct or struct pointer fields
|
||||||
func (v *Validation) RecursiveValid(objc interface{}) (bool, error) {
|
func (v *Validation) RecursiveValid(objc interface{}) (bool, error) {
|
||||||
//Step 1: validate obj itself firstly
|
// Step 1: validate obj itself firstly
|
||||||
// fails if objc is not struct
|
// fails if objc is not struct
|
||||||
pass, err := v.Valid(objc)
|
pass, err := v.Valid(objc)
|
||||||
if err != nil || !pass {
|
if err != nil || !pass {
|
||||||
|
|||||||
@ -65,7 +65,7 @@ type nopResetWriter struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (n nopResetWriter) Reset(w io.Writer) {
|
func (n nopResetWriter) Reset(w io.Writer) {
|
||||||
//do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
type acceptEncoder struct {
|
type acceptEncoder struct {
|
||||||
|
|||||||
@ -222,7 +222,7 @@ func (r *Response) Write(p []byte) (int, error) {
|
|||||||
// and sets `Started` to true.
|
// and sets `Started` to true.
|
||||||
func (r *Response) WriteHeader(code int) {
|
func (r *Response) WriteHeader(code int) {
|
||||||
if r.Status > 0 {
|
if r.Status > 0 {
|
||||||
//prevent multiple response.WriteHeader calls
|
// prevent multiple response.WriteHeader calls
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r.Status = code
|
r.Status = code
|
||||||
|
|||||||
@ -288,7 +288,7 @@ func (output *BeegoOutput) Download(file string, filename ...string) {
|
|||||||
} else {
|
} else {
|
||||||
fName = filepath.Base(file)
|
fName = filepath.Base(file)
|
||||||
}
|
}
|
||||||
//https://tools.ietf.org/html/rfc6266#section-4.3
|
// https://tools.ietf.org/html/rfc6266#section-4.3
|
||||||
fn := url.PathEscape(fName)
|
fn := url.PathEscape(fName)
|
||||||
if fName == fn {
|
if fName == fn {
|
||||||
fn = "filename=" + fn
|
fn = "filename=" + fn
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
//MethodParam keeps param information to be auto passed to controller methods
|
// MethodParam keeps param information to be auto passed to controller methods
|
||||||
type MethodParam struct {
|
type MethodParam struct {
|
||||||
name string
|
name string
|
||||||
in paramType
|
in paramType
|
||||||
|
|||||||
@ -18,7 +18,7 @@ func getParser(param *MethodParam, t reflect.Type) paramParser {
|
|||||||
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
return intParser{}
|
return intParser{}
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
if t.Elem().Kind() == reflect.Uint8 { //treat []byte as string
|
if t.Elem().Kind() == reflect.Uint8 { // treat []byte as string
|
||||||
return stringParser{}
|
return stringParser{}
|
||||||
}
|
}
|
||||||
if param.in == body {
|
if param.in == body {
|
||||||
|
|||||||
@ -14,40 +14,40 @@ type testDefinition struct {
|
|||||||
|
|
||||||
func Test_Parsers(t *testing.T) {
|
func Test_Parsers(t *testing.T) {
|
||||||
|
|
||||||
//ints
|
// ints
|
||||||
checkParser(testDefinition{"1", 1, intParser{}}, t)
|
checkParser(testDefinition{"1", 1, intParser{}}, t)
|
||||||
checkParser(testDefinition{"-1", int64(-1), intParser{}}, t)
|
checkParser(testDefinition{"-1", int64(-1), intParser{}}, t)
|
||||||
checkParser(testDefinition{"1", uint64(1), intParser{}}, t)
|
checkParser(testDefinition{"1", uint64(1), intParser{}}, t)
|
||||||
|
|
||||||
//floats
|
// floats
|
||||||
checkParser(testDefinition{"1.0", float32(1.0), floatParser{}}, t)
|
checkParser(testDefinition{"1.0", float32(1.0), floatParser{}}, t)
|
||||||
checkParser(testDefinition{"-1.0", float64(-1.0), floatParser{}}, t)
|
checkParser(testDefinition{"-1.0", float64(-1.0), floatParser{}}, t)
|
||||||
|
|
||||||
//strings
|
// strings
|
||||||
checkParser(testDefinition{"AB", "AB", stringParser{}}, t)
|
checkParser(testDefinition{"AB", "AB", stringParser{}}, t)
|
||||||
checkParser(testDefinition{"AB", []byte{65, 66}, stringParser{}}, t)
|
checkParser(testDefinition{"AB", []byte{65, 66}, stringParser{}}, t)
|
||||||
|
|
||||||
//bools
|
// bools
|
||||||
checkParser(testDefinition{"true", true, boolParser{}}, t)
|
checkParser(testDefinition{"true", true, boolParser{}}, t)
|
||||||
checkParser(testDefinition{"0", false, boolParser{}}, t)
|
checkParser(testDefinition{"0", false, boolParser{}}, t)
|
||||||
|
|
||||||
//timeParser
|
// timeParser
|
||||||
checkParser(testDefinition{"2017-05-30T13:54:53Z", time.Date(2017, 5, 30, 13, 54, 53, 0, time.UTC), timeParser{}}, t)
|
checkParser(testDefinition{"2017-05-30T13:54:53Z", time.Date(2017, 5, 30, 13, 54, 53, 0, time.UTC), timeParser{}}, t)
|
||||||
checkParser(testDefinition{"2017-05-30", time.Date(2017, 5, 30, 0, 0, 0, 0, time.UTC), timeParser{}}, t)
|
checkParser(testDefinition{"2017-05-30", time.Date(2017, 5, 30, 0, 0, 0, 0, time.UTC), timeParser{}}, t)
|
||||||
|
|
||||||
//json
|
// json
|
||||||
checkParser(testDefinition{`{"X": 5, "Y":"Z"}`, struct {
|
checkParser(testDefinition{`{"X": 5, "Y":"Z"}`, struct {
|
||||||
X int
|
X int
|
||||||
Y string
|
Y string
|
||||||
}{5, "Z"}, jsonParser{}}, t)
|
}{5, "Z"}, jsonParser{}}, t)
|
||||||
|
|
||||||
//slice in query is parsed as comma delimited
|
// slice in query is parsed as comma delimited
|
||||||
checkParser(testDefinition{`1,2`, []int{1, 2}, sliceParser(intParser{})}, t)
|
checkParser(testDefinition{`1,2`, []int{1, 2}, sliceParser(intParser{})}, t)
|
||||||
|
|
||||||
//slice in body is parsed as json
|
// slice in body is parsed as json
|
||||||
checkParser(testDefinition{`["a","b"]`, []string{"a", "b"}, jsonParser{}}, t, MethodParam{in: body})
|
checkParser(testDefinition{`["a","b"]`, []string{"a", "b"}, jsonParser{}}, t, MethodParam{in: body})
|
||||||
|
|
||||||
//pointers
|
// pointers
|
||||||
var someInt = 1
|
var someInt = 1
|
||||||
checkParser(testDefinition{`1`, &someInt, ptrParser(intParser{})}, t)
|
checkParser(testDefinition{`1`, &someInt, ptrParser(intParser{})}, t)
|
||||||
|
|
||||||
|
|||||||
@ -6,10 +6,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
//BadRequest indicates HTTP error 400
|
// BadRequest indicates HTTP error 400
|
||||||
BadRequest StatusCode = http.StatusBadRequest
|
BadRequest StatusCode = http.StatusBadRequest
|
||||||
|
|
||||||
//NotFound indicates HTTP error 404
|
// NotFound indicates HTTP error 404
|
||||||
NotFound StatusCode = http.StatusNotFound
|
NotFound StatusCode = http.StatusNotFound
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -46,7 +46,7 @@ func TestGetInt8(t *testing.T) {
|
|||||||
if val != 40 {
|
if val != 40 {
|
||||||
t.Errorf("TestGetInt8 expect 40,get %T,%v", val, val)
|
t.Errorf("TestGetInt8 expect 40,get %T,%v", val, val)
|
||||||
}
|
}
|
||||||
//Output: int8
|
// Output: int8
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetInt16(t *testing.T) {
|
func TestGetInt16(t *testing.T) {
|
||||||
|
|||||||
@ -444,13 +444,13 @@ func exception(errCode string, ctx *context.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//if 50x error has been removed from errorMap
|
// if 50x error has been removed from errorMap
|
||||||
ctx.ResponseWriter.WriteHeader(atoi(errCode))
|
ctx.ResponseWriter.WriteHeader(atoi(errCode))
|
||||||
ctx.WriteString(errCode)
|
ctx.WriteString(errCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func executeError(err *errorInfo, ctx *context.Context, code int) {
|
func executeError(err *errorInfo, ctx *context.Context, code int) {
|
||||||
//make sure to log the error in the access log
|
// make sure to log the error in the access log
|
||||||
LogAccess(ctx, nil, code)
|
LogAccess(ctx, nil, code)
|
||||||
|
|
||||||
if err.errorType == errorTypeHandler {
|
if err.errorType == errorTypeHandler {
|
||||||
@ -460,16 +460,16 @@ func executeError(err *errorInfo, ctx *context.Context, code int) {
|
|||||||
}
|
}
|
||||||
if err.errorType == errorTypeController {
|
if err.errorType == errorTypeController {
|
||||||
ctx.Output.SetStatus(code)
|
ctx.Output.SetStatus(code)
|
||||||
//Invoke the request handler
|
// Invoke the request handler
|
||||||
vc := reflect.New(err.controllerType)
|
vc := reflect.New(err.controllerType)
|
||||||
execController, ok := vc.Interface().(ControllerInterface)
|
execController, ok := vc.Interface().(ControllerInterface)
|
||||||
if !ok {
|
if !ok {
|
||||||
panic("controller is not ControllerInterface")
|
panic("controller is not ControllerInterface")
|
||||||
}
|
}
|
||||||
//call the controller init function
|
// call the controller init function
|
||||||
execController.Init(ctx, err.controllerType.Name(), err.method, vc.Interface())
|
execController.Init(ctx, err.controllerType.Name(), err.method, vc.Interface())
|
||||||
|
|
||||||
//call prepare function
|
// call prepare function
|
||||||
execController.Prepare()
|
execController.Prepare()
|
||||||
|
|
||||||
execController.URLMapping()
|
execController.URLMapping()
|
||||||
@ -477,7 +477,7 @@ func executeError(err *errorInfo, ctx *context.Context, code int) {
|
|||||||
method := vc.MethodByName(err.method)
|
method := vc.MethodByName(err.method)
|
||||||
method.Call([]reflect.Value{})
|
method.Call([]reflect.Value{})
|
||||||
|
|
||||||
//render template
|
// render template
|
||||||
if BConfig.WebConfig.AutoRender {
|
if BConfig.WebConfig.AutoRender {
|
||||||
if err := execController.Render(); err != nil {
|
if err := execController.Render(); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|||||||
@ -17,11 +17,12 @@ package opentracing
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/beego/beego/v2/server/web"
|
|
||||||
beegoCtx "github.com/beego/beego/v2/server/web/context"
|
|
||||||
logKit "github.com/go-kit/kit/log"
|
logKit "github.com/go-kit/kit/log"
|
||||||
opentracingKit "github.com/go-kit/kit/tracing/opentracing"
|
opentracingKit "github.com/go-kit/kit/tracing/opentracing"
|
||||||
"github.com/opentracing/opentracing-go"
|
"github.com/opentracing/opentracing-go"
|
||||||
|
|
||||||
|
"github.com/beego/beego/v2/server/web"
|
||||||
|
beegoCtx "github.com/beego/beego/v2/server/web/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
// FilterChainBuilder provides an extension point that we can support more configurations if necessary
|
// FilterChainBuilder provides an extension point that we can support more configurations if necessary
|
||||||
|
|||||||
@ -102,7 +102,7 @@ func ReadFromRequest(c *Controller) *FlashData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//read one time then delete it
|
// read one time then delete it
|
||||||
c.Ctx.SetCookie(BConfig.WebConfig.FlashName, "", -1, "/")
|
c.Ctx.SetCookie(BConfig.WebConfig.FlashName, "", -1, "/")
|
||||||
}
|
}
|
||||||
c.Data["flash"] = flash.Data
|
c.Data["flash"] = flash.Data
|
||||||
|
|||||||
@ -138,7 +138,7 @@ func NewServer(addr string, handler http.Handler) (srv *Server) {
|
|||||||
},
|
},
|
||||||
state: StateInit,
|
state: StateInit,
|
||||||
Network: "tcp",
|
Network: "tcp",
|
||||||
terminalChan: make(chan error), //no cache channel
|
terminalChan: make(chan error), // no cache channel
|
||||||
}
|
}
|
||||||
srv.Server = &http.Server{
|
srv.Server = &http.Server{
|
||||||
Addr: addr,
|
Addr: addr,
|
||||||
|
|||||||
@ -189,8 +189,8 @@ func (n *Namespace) Include(cList ...ControllerInterface) *Namespace {
|
|||||||
|
|
||||||
// Namespace add nest Namespace
|
// Namespace add nest Namespace
|
||||||
// usage:
|
// usage:
|
||||||
//ns := beego.NewNamespace(“/v1”).
|
// ns := beego.NewNamespace(“/v1”).
|
||||||
//Namespace(
|
// Namespace(
|
||||||
// beego.NewNamespace("/shop").
|
// beego.NewNamespace("/shop").
|
||||||
// Get("/:id", func(ctx *context.Context) {
|
// Get("/:id", func(ctx *context.Context) {
|
||||||
// ctx.Output.Body([]byte("shopinfo"))
|
// ctx.Output.Body([]byte("shopinfo"))
|
||||||
@ -203,7 +203,7 @@ func (n *Namespace) Include(cList ...ControllerInterface) *Namespace {
|
|||||||
// Get("/:id", func(ctx *context.Context) {
|
// Get("/:id", func(ctx *context.Context) {
|
||||||
// ctx.Output.Body([]byte("crminfo"))
|
// ctx.Output.Body([]byte("crminfo"))
|
||||||
// }),
|
// }),
|
||||||
//)
|
// )
|
||||||
func (n *Namespace) Namespace(ns ...*Namespace) *Namespace {
|
func (n *Namespace) Namespace(ns ...*Namespace) *Namespace {
|
||||||
for _, ni := range ns {
|
for _, ni := range ns {
|
||||||
for k, v := range ni.handlers.routers {
|
for k, v := range ni.handlers.routers {
|
||||||
|
|||||||
@ -1,18 +1,17 @@
|
|||||||
session
|
session
|
||||||
==============
|
==============
|
||||||
|
|
||||||
session is a Go session manager. It can use many session providers. Just like the `database/sql` and `database/sql/driver`.
|
session is a Go session manager. It can use many session providers. Just like the `database/sql`
|
||||||
|
and `database/sql/driver`.
|
||||||
|
|
||||||
## How to install?
|
## How to install?
|
||||||
|
|
||||||
go get github.com/beego/beego/v2/session
|
go get github.com/beego/beego/v2/session
|
||||||
|
|
||||||
|
|
||||||
## What providers are supported?
|
## What providers are supported?
|
||||||
|
|
||||||
As of now this session manager support memory, file, Redis and MySQL.
|
As of now this session manager support memory, file, Redis and MySQL.
|
||||||
|
|
||||||
|
|
||||||
## How to use it?
|
## How to use it?
|
||||||
|
|
||||||
First you must import it
|
First you must import it
|
||||||
@ -22,46 +21,46 @@ First you must import it
|
|||||||
)
|
)
|
||||||
|
|
||||||
Then in you web app init the global session manager
|
Then in you web app init the global session manager
|
||||||
|
|
||||||
var globalSessions *session.Manager
|
var globalSessions *session.Manager
|
||||||
|
|
||||||
* Use **memory** as provider:
|
* Use **memory** as provider:
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
globalSessions, _ = session.NewManager("memory", `{"cookieName":"gosessionid","gclifetime":3600}`)
|
globalSessions, _ = session.NewManager("memory", `{"cookieName":"gosessionid","gclifetime":3600}`)
|
||||||
go globalSessions.GC()
|
go globalSessions.GC()
|
||||||
}
|
}
|
||||||
|
|
||||||
* Use **file** as provider, the last param is the path where you want file to be stored:
|
* Use **file** as provider, the last param is the path where you want file to be stored:
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
globalSessions, _ = session.NewManager("file",`{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"./tmp"}`)
|
globalSessions, _ = session.NewManager("file",`{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"./tmp"}`)
|
||||||
go globalSessions.GC()
|
go globalSessions.GC()
|
||||||
}
|
}
|
||||||
|
|
||||||
* Use **Redis** as provider, the last param is the Redis conn address,poolsize,password:
|
* Use **Redis** as provider, the last param is the Redis conn address,poolsize,password:
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
globalSessions, _ = session.NewManager("redis", `{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"127.0.0.1:6379,100,astaxie"}`)
|
globalSessions, _ = session.NewManager("redis", `{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"127.0.0.1:6379,100,astaxie"}`)
|
||||||
go globalSessions.GC()
|
go globalSessions.GC()
|
||||||
}
|
}
|
||||||
|
|
||||||
* Use **MySQL** as provider, the last param is the DSN, learn more from [mysql](https://github.com/go-sql-driver/mysql#dsn-data-source-name):
|
|
||||||
|
|
||||||
func init() {
|
* Use **MySQL** as provider, the last param is the DSN, learn more
|
||||||
globalSessions, _ = session.NewManager(
|
from [mysql](https://github.com/go-sql-driver/mysql#dsn-data-source-name):
|
||||||
"mysql", `{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"username:password@protocol(address)/dbname?param=value"}`)
|
|
||||||
go globalSessions.GC()
|
func init() {
|
||||||
}
|
globalSessions, _ = session.NewManager(
|
||||||
|
"mysql", `{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"username:password@protocol(address)/dbname?param=value"}`)
|
||||||
|
go globalSessions.GC()
|
||||||
|
}
|
||||||
|
|
||||||
* Use **Cookie** as provider:
|
* Use **Cookie** as provider:
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
globalSessions, _ = session.NewManager(
|
globalSessions, _ = session.NewManager(
|
||||||
"cookie", `{"cookieName":"gosessionid","enableSetCookie":false,"gclifetime":3600,"ProviderConfig":"{\"cookieName\":\"gosessionid\",\"securityKey\":\"beegocookiehashkey\"}"}`)
|
"cookie", `{"cookieName":"gosessionid","enableSetCookie":false,"gclifetime":3600,"ProviderConfig":"{\"cookieName\":\"gosessionid\",\"securityKey\":\"beegocookiehashkey\"}"}`)
|
||||||
go globalSessions.GC()
|
go globalSessions.GC()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Finally in the handlerfunc you can use it like this
|
Finally in the handlerfunc you can use it like this
|
||||||
|
|
||||||
@ -80,14 +79,13 @@ Finally in the handlerfunc you can use it like this
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
## How to write own provider?
|
## How to write own provider?
|
||||||
|
|
||||||
When you develop a web app, maybe you want to write own provider because you must meet the requirements.
|
When you develop a web app, maybe you want to write own provider because you must meet the requirements.
|
||||||
|
|
||||||
Writing a provider is easy. You only need to define two struct types
|
Writing a provider is easy. You only need to define two struct types
|
||||||
(Session and Provider), which satisfy the interface definition.
|
(Session and Provider), which satisfy the interface definition. Maybe you will find the **memory** provider is a good
|
||||||
Maybe you will find the **memory** provider is a good example.
|
example.
|
||||||
|
|
||||||
type SessionStore interface {
|
type SessionStore interface {
|
||||||
Set(key, value interface{}) error //set session value
|
Set(key, value interface{}) error //set session value
|
||||||
@ -108,7 +106,6 @@ Maybe you will find the **memory** provider is a good example.
|
|||||||
SessionGC()
|
SessionGC()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
## LICENSE
|
## LICENSE
|
||||||
|
|
||||||
BSD License http://creativecommons.org/licenses/BSD/
|
BSD License http://creativecommons.org/licenses/BSD/
|
||||||
|
|||||||
@ -27,9 +27,9 @@ var mempder = &MemProvider{list: list.New(), sessions: make(map[string]*list.Ele
|
|||||||
// MemSessionStore memory session store.
|
// MemSessionStore memory session store.
|
||||||
// it saved sessions in a map in memory.
|
// it saved sessions in a map in memory.
|
||||||
type MemSessionStore struct {
|
type MemSessionStore struct {
|
||||||
sid string //session id
|
sid string // session id
|
||||||
timeAccessed time.Time //last access time
|
timeAccessed time.Time // last access time
|
||||||
value map[interface{}]interface{} //session store
|
value map[interface{}]interface{} // session store
|
||||||
lock sync.RWMutex
|
lock sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -44,12 +44,12 @@ import (
|
|||||||
|
|
||||||
// Store contains all data for one session process with specific id.
|
// Store contains all data for one session process with specific id.
|
||||||
type Store interface {
|
type Store interface {
|
||||||
Set(ctx context.Context, key, value interface{}) error //set session value
|
Set(ctx context.Context, key, value interface{}) error // set session value
|
||||||
Get(ctx context.Context, key interface{}) interface{} //get session value
|
Get(ctx context.Context, key interface{}) interface{} // get session value
|
||||||
Delete(ctx context.Context, key interface{}) error //delete session value
|
Delete(ctx context.Context, key interface{}) error // delete session value
|
||||||
SessionID(ctx context.Context) string //back current sessionID
|
SessionID(ctx context.Context) string // back current sessionID
|
||||||
SessionRelease(ctx context.Context, w http.ResponseWriter) // release the resource & save data to provider & return the data
|
SessionRelease(ctx context.Context, w http.ResponseWriter) // release the resource & save data to provider & return the data
|
||||||
Flush(ctx context.Context) error //delete all data
|
Flush(ctx context.Context) error // delete all data
|
||||||
}
|
}
|
||||||
|
|
||||||
// Provider contains global session methods and saved SessionStores.
|
// Provider contains global session methods and saved SessionStores.
|
||||||
@ -60,7 +60,7 @@ type Provider interface {
|
|||||||
SessionExist(ctx context.Context, sid string) (bool, error)
|
SessionExist(ctx context.Context, sid string) (bool, error)
|
||||||
SessionRegenerate(ctx context.Context, oldsid, sid string) (Store, error)
|
SessionRegenerate(ctx context.Context, oldsid, sid string) (Store, error)
|
||||||
SessionDestroy(ctx context.Context, sid string) error
|
SessionDestroy(ctx context.Context, sid string) error
|
||||||
SessionAll(ctx context.Context) int //get all active session
|
SessionAll(ctx context.Context) int // get all active session
|
||||||
SessionGC(ctx context.Context)
|
SessionGC(ctx context.Context)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +82,7 @@ func Register(name string, provide Provider) {
|
|||||||
provides[name] = provide
|
provides[name] = provide
|
||||||
}
|
}
|
||||||
|
|
||||||
//GetProvider
|
// GetProvider
|
||||||
func GetProvider(name string) (Provider, error) {
|
func GetProvider(name string) (Provider, error) {
|
||||||
provider, ok := provides[name]
|
provider, ok := provides[name]
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -308,7 +308,7 @@ func (manager *Manager) SessionRegenerateID(w http.ResponseWriter, r *http.Reque
|
|||||||
|
|
||||||
cookie, err := r.Cookie(manager.config.CookieName)
|
cookie, err := r.Cookie(manager.config.CookieName)
|
||||||
if err != nil || cookie.Value == "" {
|
if err != nil || cookie.Value == "" {
|
||||||
//delete old cookie
|
// delete old cookie
|
||||||
session, err = manager.provider.SessionRead(nil, sid)
|
session, err = manager.provider.SessionRead(nil, sid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@ -26,9 +26,10 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/beego/beego/v2/core/logs"
|
|
||||||
lru "github.com/hashicorp/golang-lru"
|
lru "github.com/hashicorp/golang-lru"
|
||||||
|
|
||||||
|
"github.com/beego/beego/v2/core/logs"
|
||||||
|
|
||||||
"github.com/beego/beego/v2/server/web/context"
|
"github.com/beego/beego/v2/server/web/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -65,12 +66,12 @@ func serverStaticRouter(ctx *context.Context) {
|
|||||||
}
|
}
|
||||||
ctx.Redirect(302, redirectURL)
|
ctx.Redirect(302, redirectURL)
|
||||||
} else {
|
} else {
|
||||||
//serveFile will list dir
|
// serveFile will list dir
|
||||||
http.ServeFile(ctx.ResponseWriter, ctx.Request, filePath)
|
http.ServeFile(ctx.ResponseWriter, ctx.Request, filePath)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
} else if fileInfo.Size() > int64(BConfig.WebConfig.StaticCacheFileSize) {
|
} else if fileInfo.Size() > int64(BConfig.WebConfig.StaticCacheFileSize) {
|
||||||
//over size file serve with http module
|
// over size file serve with http module
|
||||||
http.ServeFile(ctx.ResponseWriter, ctx.Request, filePath)
|
http.ServeFile(ctx.ResponseWriter, ctx.Request, filePath)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -102,7 +103,7 @@ type serveContentHolder struct {
|
|||||||
data []byte
|
data []byte
|
||||||
modTime time.Time
|
modTime time.Time
|
||||||
size int64
|
size int64
|
||||||
originSize int64 //original file size:to judge file changed
|
originSize int64 // original file size:to judge file changed
|
||||||
encoding string
|
encoding string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,7 +118,7 @@ var (
|
|||||||
|
|
||||||
func openFile(filePath string, fi os.FileInfo, acceptEncoding string) (bool, string, *serveContentHolder, *serveContentReader, error) {
|
func openFile(filePath string, fi os.FileInfo, acceptEncoding string) (bool, string, *serveContentHolder, *serveContentReader, error) {
|
||||||
if staticFileLruCache == nil {
|
if staticFileLruCache == nil {
|
||||||
//avoid lru cache error
|
// avoid lru cache error
|
||||||
if BConfig.WebConfig.StaticCacheFileNum >= 1 {
|
if BConfig.WebConfig.StaticCacheFileNum >= 1 {
|
||||||
staticFileLruCache, _ = lru.New(BConfig.WebConfig.StaticCacheFileNum)
|
staticFileLruCache, _ = lru.New(BConfig.WebConfig.StaticCacheFileNum)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -35,7 +35,7 @@ type Statistics struct {
|
|||||||
// URLMap contains several statistics struct to log different data
|
// URLMap contains several statistics struct to log different data
|
||||||
type URLMap struct {
|
type URLMap struct {
|
||||||
lock sync.RWMutex
|
lock sync.RWMutex
|
||||||
LengthLimit int //limit the urlmap's length if it's equal to 0 there's no limit
|
LengthLimit int // limit the urlmap's length if it's equal to 0 there's no limit
|
||||||
urlmap map[string]map[string]*Statistics
|
urlmap map[string]map[string]*Statistics
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -106,7 +106,7 @@ type Parameter struct {
|
|||||||
type ParameterItems struct {
|
type ParameterItems struct {
|
||||||
Type string `json:"type,omitempty" yaml:"type,omitempty"`
|
Type string `json:"type,omitempty" yaml:"type,omitempty"`
|
||||||
Format string `json:"format,omitempty" yaml:"format,omitempty"`
|
Format string `json:"format,omitempty" yaml:"format,omitempty"`
|
||||||
Items []*ParameterItems `json:"items,omitempty" yaml:"items,omitempty"` //Required if type is "array". Describes the type of items in the array.
|
Items []*ParameterItems `json:"items,omitempty" yaml:"items,omitempty"` // Required if type is "array". Describes the type of items in the array.
|
||||||
CollectionFormat string `json:"collectionFormat,omitempty" yaml:"collectionFormat,omitempty"`
|
CollectionFormat string `json:"collectionFormat,omitempty" yaml:"collectionFormat,omitempty"`
|
||||||
Default string `json:"default,omitempty" yaml:"default,omitempty"`
|
Default string `json:"default,omitempty" yaml:"default,omitempty"`
|
||||||
}
|
}
|
||||||
|
|||||||
@ -163,12 +163,12 @@ func AddTemplateExt(ext string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// AddViewPath adds a new path to the supported view paths.
|
// AddViewPath adds a new path to the supported view paths.
|
||||||
//Can later be used by setting a controller ViewPath to this folder
|
// Can later be used by setting a controller ViewPath to this folder
|
||||||
//will panic if called after beego.Run()
|
// will panic if called after beego.Run()
|
||||||
func AddViewPath(viewPath string) error {
|
func AddViewPath(viewPath string) error {
|
||||||
if beeViewPathTemplateLocked {
|
if beeViewPathTemplateLocked {
|
||||||
if _, exist := beeViewPathTemplates[viewPath]; exist {
|
if _, exist := beeViewPathTemplates[viewPath]; exist {
|
||||||
return nil //Ignore if viewpath already exists
|
return nil // Ignore if viewpath already exists
|
||||||
}
|
}
|
||||||
panic("Can not add new view paths after beego.Run()")
|
panic("Can not add new view paths after beego.Run()")
|
||||||
}
|
}
|
||||||
@ -303,7 +303,7 @@ func _getTemplate(t0 *template.Template, root string, fs http.FileSystem, subMod
|
|||||||
if tpl != 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
|
||||||
@ -316,7 +316,7 @@ func _getTemplate(t0 *template.Template, root string, fs http.FileSystem, subMod
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//second check define
|
// second check define
|
||||||
for _, otherFile := range others {
|
for _, otherFile := range others {
|
||||||
var data []byte
|
var data []byte
|
||||||
fileAbsPath := filepath.Join(root, otherFile)
|
fileAbsPath := filepath.Join(root, otherFile)
|
||||||
|
|||||||
@ -117,7 +117,7 @@ func TestRelativeTemplate(t *testing.T) {
|
|||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
dir := filepath.Join(wkdir, "_beeTmp")
|
dir := filepath.Join(wkdir, "_beeTmp")
|
||||||
|
|
||||||
//Just add dir to known viewPaths
|
// Just add dir to known viewPaths
|
||||||
if err := AddViewPath(dir); err != nil {
|
if err := AddViewPath(dir); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -50,7 +50,7 @@ func notMatchTestInfo(pattern, url string) testInfo {
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
routers = make([]testInfo, 0)
|
routers = make([]testInfo, 0)
|
||||||
//match example
|
// match example
|
||||||
routers = append(routers, matchTestInfo("/topic/?:auth:int", "/topic", nil))
|
routers = append(routers, matchTestInfo("/topic/?:auth:int", "/topic", nil))
|
||||||
routers = append(routers, matchTestInfo("/topic/?:auth:int", "/topic/123", map[string]string{":auth": "123"}))
|
routers = append(routers, matchTestInfo("/topic/?:auth:int", "/topic/123", map[string]string{":auth": "123"}))
|
||||||
routers = append(routers, matchTestInfo("/topic/:id/?:auth", "/topic/1", map[string]string{":id": "1"}))
|
routers = append(routers, matchTestInfo("/topic/:id/?:auth", "/topic/1", map[string]string{":id": "1"}))
|
||||||
@ -91,7 +91,7 @@ func init() {
|
|||||||
routers = append(routers, matchTestInfo("/api/projects/:pid/members/?:mid", "/api/projects/1/members", map[string]string{":pid": "1"}))
|
routers = append(routers, matchTestInfo("/api/projects/:pid/members/?:mid", "/api/projects/1/members", map[string]string{":pid": "1"}))
|
||||||
routers = append(routers, matchTestInfo("/api/projects/:pid/members/?:mid", "/api/projects/1/members/2", map[string]string{":pid": "1", ":mid": "2"}))
|
routers = append(routers, matchTestInfo("/api/projects/:pid/members/?:mid", "/api/projects/1/members/2", map[string]string{":pid": "1", ":mid": "2"}))
|
||||||
|
|
||||||
//not match example
|
// not match example
|
||||||
|
|
||||||
// https://github.com/beego/beego/v2/issues/3865
|
// https://github.com/beego/beego/v2/issues/3865
|
||||||
routers = append(routers, notMatchTestInfo("/read_:id:int\\.htm", "/read_222htm"))
|
routers = append(routers, notMatchTestInfo("/read_:id:int\\.htm", "/read_222htm"))
|
||||||
@ -324,7 +324,7 @@ func TestSplitSegment(t *testing.T) {
|
|||||||
":id([0-9]+)": {true, []string{":id"}, `([0-9]+)`},
|
":id([0-9]+)": {true, []string{":id"}, `([0-9]+)`},
|
||||||
":id([0-9]+)_:name": {true, []string{":id", ":name"}, `([0-9]+)_(.+)`},
|
":id([0-9]+)_:name": {true, []string{":id", ":name"}, `([0-9]+)_(.+)`},
|
||||||
":id(.+)_cms.html": {true, []string{":id"}, `(.+)_cms.html`},
|
":id(.+)_cms.html": {true, []string{":id"}, `(.+)_cms.html`},
|
||||||
":id(.+)_cms\\.html": {true, []string{":id"}, `(.+)_cms\.html`},
|
":id(.+)_cms\\.html": {true, []string{":id"}, `(.+)_cms\.html`},
|
||||||
"cms_:id(.+)_:page(.+).html": {true, []string{":id", ":page"}, `cms_(.+)_(.+).html`},
|
"cms_:id(.+)_:page(.+).html": {true, []string{":id", ":page"}, `cms_(.+)_(.+).html`},
|
||||||
`:app(a|b|c)`: {true, []string{":app"}, `(a|b|c)`},
|
`:app(a|b|c)`: {true, []string{":app"}, `(a|b|c)`},
|
||||||
`:app\((a|b|c)\)`: {true, []string{":app"}, `(.+)\((a|b|c)\)`},
|
`:app\((a|b|c)\)`: {true, []string{":app"}, `(.+)\((a|b|c)\)`},
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user