Prepare Release 2.0.6 (#5104)

* add: generic cache random time offset expired.

* bugfix: Csrf token should be Secure and httpOnly, but not now

* fix: expose the Offset property to allow external modifications

* improving the concurrency performance of random value calculation

* add WithOffsetFunc to define private RandomExpireCache.offset field

* fix: add seconds definition

* build(deps): bump github.com/stretchr/testify from 1.7.1 to 1.8.0

Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.7.1 to 1.8.0.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.7.1...v1.8.0)

---
updated-dependencies:
- dependency-name: github.com/stretchr/testify
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* fix 4907: force admin service http only

* Feat: add get all tasks function (#4999)

* feat: add get all tasks function

* Refine Comments : admin/profile.go,bean/mock.go,config/global.go... (#5009)

* Refine Comments

* refine comments for cache.go

* refine comments for log.go

* Update orm.go

* refine comments for orm_log.go,types.go

* Update utils.go

* Update doc.go

* refine comments for for four files (#5011)

* refine comments for cache.go

* refine comments for log.go

* Update orm.go

* refine comments for orm_log.go,types.go

* Update utils.go

* Update doc.go

* Update db.go

* fix pass []any as any in variadic function by asasalint (#5012)

* fix pass []any as any in variadic function

* add change log

* build(deps): bump go.opentelemetry.io/otel/trace from 1.7.0 to 1.8.0 (#5019)

Bumps [go.opentelemetry.io/otel/trace](https://github.com/open-telemetry/opentelemetry-go) from 1.7.0 to 1.8.0.
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.7.0...v1.8.0)

---
updated-dependencies:
- dependency-name: go.opentelemetry.io/otel/trace
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* refine comments for package core  (#5014)

* Refine Comments

* refine comments for cache.go

* refine comments for log.go

* Update orm.go

* refine comments for orm_log.go,types.go

* Update utils.go

* Update doc.go

* refine comments

* refine comments

* Update db.go

* refine comments for core

* build(deps): bump go.opentelemetry.io/otel/exporters/stdout/stdouttrace (#5018)

Bumps [go.opentelemetry.io/otel/exporters/stdout/stdouttrace](https://github.com/open-telemetry/opentelemetry-go) from 1.7.0 to 1.8.0.
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.7.0...v1.8.0)

---
updated-dependencies:
- dependency-name: go.opentelemetry.io/otel/exporters/stdout/stdouttrace
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* fix 5022: Miss assiging ln to graceful Server (#5028)

* prepare for releasing v2.0.5

* prepare for releasing v2.0.5 (#5032)

* feat: make commands and docker compose for ORM unit tests (#5031)

* feat: make commands and docker compose for ORM unit tests

Signed-off-by: mango <xu.weiKyrie@foxmail.com>

* add changelog

Signed-off-by: mango <xu.weiKyrie@foxmail.com>

Signed-off-by: mango <xu.weiKyrie@foxmail.com>

* Modify comment syntax error (#5094)

* fix: revise the body wrapper to handle empty body case (#5102)

Fix the router.go serverHttp method, wrap the body if the request body
is empty, which can avoid panic when calling the CopyBody method.

Signed-off-by: chlins <chenyuzh@vmware.com>

Signed-off-by: chlins <chenyuzh@vmware.com>

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: mango <xu.weiKyrie@foxmail.com>
Signed-off-by: chlins <chenyuzh@vmware.com>
Co-authored-by: auual <ding@ibyte.me>
Co-authored-by: Leon Ding <deen.job@qq.com>
Co-authored-by: dada0z <zhang.guangda@qq.com>
Co-authored-by: kevinzeng <kevinzeng@zego.im>
Co-authored-by: Kevin Tsang <39397413+ktalg@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: 日暮颂歌1991 <448081525@qq.com>
Co-authored-by: Regan Yue <1131625869@qq.com>
Co-authored-by: alingse <alingse@foxmail.com>
Co-authored-by: mango <35127166+mangoGoForward@users.noreply.github.com>
Co-authored-by: 王哈哈 <31426858+wanghaha-dev@users.noreply.github.com>
Co-authored-by: Chlins Zhang <chlins.zhang@gmail.com>
This commit is contained in:
Ming Deng 2022-11-23 00:06:32 +08:00 committed by GitHub
parent f81689dfb1
commit 76343e4422
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 339 additions and 121 deletions

View File

@ -9,6 +9,7 @@ Note: now we force the web admin service serving HTTP only.
- [Feat 4999: add get all tasks function](https://github.com/beego/beego/pull/4999)
- [Fix 5012: fix some bug, pass []any as any in variadic function](https://github.com/beego/beego/pull/5012)
- [Fix 5022: Miss assigning listener to graceful Server](https://github.com/beego/beego/pull/5028)
- [Fix 4955: Make commands and Docker compose for ORM unit tests](https://github.com/beego/beego/pull/5031)
# v2.0.4

64
Makefile Normal file
View File

@ -0,0 +1,64 @@
# Copyright 2020
#
# 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.
##@ General
# The help target prints out all targets with their descriptions organized
# beneath their categories. The categories are represented by '##@' and the
# target descriptions by '##'. The awk commands is responsible for reading the
# entire set of makefiles included in this invocation, looking for lines of the
# file as xyz: ## something, and then pretty-format the target and help. Then,
# if there's a line with ##@ something, that gets pretty-printed as a category.
# More info on the usage of ANSI control characters for terminal formatting:
# https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters
# More info on the awk command:
# http://linuxcommand.org/lc3_adv_awk.php
help: ## Display this help.
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
##@ Test
test-orm-mysql5: ## Run ORM unit tests on mysql5.
docker-compose -f scripts/orm_docker_compose.yaml up -d
export ORM_DRIVER=mysql
export ORM_SOURCE="beego:test@tcp(localhost:13306)/orm_test?charset=utf8"
go test -v github.com/beego/beego/v2/client/orm
docker-compose -f scripts/orm_docker_compose.yaml down
test-orm-mysql8: ## Run ORM unit tests on mysql8.
docker-compose -f scripts/orm_docker_compose.yaml up -d
export ORM_DRIVER=mysql
export ORM_SOURCE="beego:test@tcp(localhost:23306)/orm_test?charset=utf8"
go test -v github.com/beego/beego/v2/client/orm
docker-compose -f scripts/orm_docker_compose.yaml down
test-orm-pgsql: ## Run ORM unit tests on postgresql.
docker-compose -f scripts/orm_docker_compose.yaml up -d
export ORM_DRIVER=postgres
export ORM_SOURCE="user=postgres password=postgres dbname=orm_test sslmode=disable"
go test -v github.com/beego/beego/v2/client/orm
docker-compose -f scripts/orm_docker_compose.yaml down
test-orm-tidb: ## Run ORM unit tests on tidb.
docker-compose -f scripts/orm_docker_compose.yaml up -d
export ORM_DRIVER=tidb
export ORM_SOURCE="memory://test/test"
go test -v github.com/beego/beego/v2/client/orm
docker-compose -f scripts/orm_docker_compose.yaml down
.PHONY: test-orm-all
test-orm-all: test-orm-mysql5 test-orm-mysql8 test-orm-pgsql test-orm-tidb

View File

@ -94,7 +94,7 @@ func (input *BeegoInput) IsHead() bool {
return (*context.BeegoInput)(input).IsHead()
}
// IsOptions Is this a OPTIONS method request?
// IsOptions Is this an OPTIONS method request?
func (input *BeegoInput) IsOptions() bool {
return (*context.BeegoInput)(input).IsOptions()
}

View File

@ -52,7 +52,7 @@ func (c *Condition) AndCond(cond *Condition) *Condition {
return (*Condition)((*orm.Condition)(c).AndCond((*orm.Condition)(cond)))
}
// AndNotCond combine a AND NOT condition to current condition
// AndNotCond combine an AND NOT condition to current condition
func (c *Condition) AndNotCond(cond *Condition) *Condition {
return (*Condition)((*orm.Condition)(c).AndNotCond((*orm.Condition)(cond)))
}
@ -67,12 +67,12 @@ func (c Condition) OrNot(expr string, args ...interface{}) *Condition {
return (*Condition)((orm.Condition)(c).OrNot(expr, args...))
}
// OrCond combine a OR condition to current condition
// OrCond combine an OR condition to current condition
func (c *Condition) OrCond(cond *Condition) *Condition {
return (*Condition)((*orm.Condition)(c).OrCond((*orm.Condition)(cond)))
}
// OrNotCond combine a OR NOT condition to current condition
// OrNotCond combine an OR NOT condition to current condition
func (c *Condition) OrNotCond(cond *Condition) *Condition {
return (*Condition)((*orm.Condition)(c).OrNotCond((*orm.Condition)(cond)))
}

View File

@ -19,17 +19,17 @@ import (
)
var InvalidUrl = berror.DefineCode(4001001, moduleName, "InvalidUrl", `
You pass a invalid url to httplib module. Please check your url, be careful about special character.
You pass an invalid url to httplib module. Please check your url, be careful about special character.
`)
var InvalidUrlProtocolVersion = berror.DefineCode(4001002, moduleName, "InvalidUrlProtocolVersion", `
You pass a invalid protocol version. In practice, we use HTTP/1.0, HTTP/1.1, HTTP/1.2
You pass an invalid protocol version. In practice, we use HTTP/1.0, HTTP/1.1, HTTP/1.2
But something like HTTP/3.2 is valid for client, and the major version is 3, minor version is 2.
but you must confirm that server support those abnormal protocol version.
`)
var UnsupportedBodyType = berror.DefineCode(4001003, moduleName, "UnsupportedBodyType", `
You use a invalid data as request body.
You use an invalid data as request body.
For now, we only support type string and byte[].
`)

View File

@ -112,7 +112,7 @@ func Head(url string) *BeegoHTTPRequest {
return NewBeegoRequest(url, "HEAD")
}
// BeegoHTTPRequest provides more useful methods than http.Request for requesting a url.
// BeegoHTTPRequest provides more useful methods than http.Request for requesting an url.
type BeegoHTTPRequest struct {
url string
req *http.Request

View File

@ -1111,7 +1111,7 @@ func (d *dbBase) ReadBatch(ctx context.Context, q dbQuerier, qs *querySet, mi *m
ind.Set(mind)
} else {
if cnt == 0 {
// you can use a empty & caped container list
// you can use an empty & caped container list
// orm will not replace it
if ind.Len() != 0 {
// if container is not empty
@ -1135,7 +1135,7 @@ func (d *dbBase) ReadBatch(ctx context.Context, q dbQuerier, qs *querySet, mi *m
ind.Set(slice)
} else {
// when a result is empty and container is nil
// to set a empty container
// to set an empty container
if ind.IsNil() {
ind.Set(reflect.MakeSlice(ind.Type(), 0, 0))
}

View File

@ -155,7 +155,7 @@ func (d *dbBaseMysql) InsertOrUpdate(ctx context.Context, q dbQuerier, mi *model
if isMulti {
qmarks = strings.Repeat(qmarks+"), (", multi-1) + qmarks
}
// conflitValue maybe is a int,can`t use fmt.Sprintf
// conflitValue maybe is an 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)
d.ins.ReplaceMarks(&query)

View File

@ -90,7 +90,7 @@ func (c *Condition) AndCond(cond *Condition) *Condition {
return c
}
// AndNotCond combine a AND NOT condition to current condition
// AndNotCond combine an AND NOT condition to current condition
func (c *Condition) AndNotCond(cond *Condition) *Condition {
c = c.clone()
if c == cond {
@ -121,7 +121,7 @@ func (c Condition) OrNot(expr string, args ...interface{}) *Condition {
return &c
}
// OrCond combine a OR condition to current condition
// OrCond combine an OR condition to current condition
func (c *Condition) OrCond(cond *Condition) *Condition {
c = c.clone()
if c == cond {
@ -133,7 +133,7 @@ func (c *Condition) OrCond(cond *Condition) *Condition {
return c
}
// OrNotCond combine a OR NOT condition to current condition
// OrNotCond combine an OR NOT condition to current condition
func (c *Condition) OrNotCond(cond *Condition) *Condition {
c = c.clone()
if c == cond {

View File

@ -257,7 +257,7 @@ func (o *querySet) DeleteWithCtx(ctx context.Context) (int64, error) {
return o.orm.alias.DbBaser.DeleteBatch(ctx, o.orm.db, o, o.mi, o.cond, o.orm.alias.TZ)
}
// return a insert queryer.
// return an insert queryer.
// it can be used in times.
// example:
// i,err := sq.PrepareInsert()

View File

@ -405,7 +405,7 @@ type QuerySeter interface {
// //delete two user who's name is testing1 or testing2
Delete() (int64, error)
DeleteWithCtx(context.Context) (int64, error)
// return a insert queryer.
// return an insert queryer.
// it can be used in times.
// example:
// i,err := sq.PrepareInsert()

View File

@ -98,7 +98,7 @@ func (ini *IniConfig) parseData(dir string, data []byte) (*IniConfigContainer, e
break
}
// It might be a good idea to throw a error on all unknonw errors?
// It might be a good idea to throw an error on all unknonw errors?
if _, ok := err.(*os.PathError); ok {
return nil, err
}

View File

@ -105,11 +105,11 @@ func (el *esLogger) WriteMsg(lm *logs.LogMsg) error {
return err
}
// Destroy is a empty method
// Destroy is an empty method
func (el *esLogger) Destroy() {
}
// Flush is a empty method
// Flush is an empty method
func (el *esLogger) Flush() {
}

View File

@ -0,0 +1,124 @@
# Copyright 2022
#
# 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.
version: "3.8"
services:
# mysql5.7
mysql5:
container_name: "beego-mysql5"
image: mysql:5.7.30
ports:
- "13306:3306"
environment:
- MYSQL_ROOT_PASSWORD=1q2w3e
- MYSQL_DATABASE=orm_test
- MYSQL_USER=beego
- MYSQL_PASSWORD=test
# mysql8.0
mysql8:
container_name: "beego-mysql8"
image: mysql:8.0
ports:
- "23306:3306"
environment:
- MYSQL_ROOT_PASSWORD=1q2w3e
- MYSQL_DATABASE=orm_test
- MYSQL_USER=beego
- MYSQL_PASSWORD=test
# postgresql
postgresql:
container_name: "beego-postgresql"
image: bitnami/postgresql:latest
ports:
- "5432:5432"
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- POSTGRES_DB=orm_test
# tidb
pd0:
image: pingcap/pd:latest
ports:
- "2379:2379"
volumes:
- ./config/pd.toml:/pd.toml:ro
- ./data:/data
- ./logs:/logs
command:
- --name=pd0
- --client-urls=http://0.0.0.0:2379
- --peer-urls=http://0.0.0.0:2380
- --advertise-client-urls=http://pd0:2379
- --advertise-peer-urls=http://pd0:2380
- --initial-cluster=pd0=http://pd0:2380
- --data-dir=/data/pd0
- --config=/pd.toml
- --log-file=/logs/pd0.log
restart: on-failure
tikv0:
image: pingcap/tikv:latest
volumes:
- ./config/tikv.toml:/tikv.toml:ro
- ./data:/data
- ./logs:/logs
command:
- --addr=0.0.0.0:20160
- --advertise-addr=tikv0:20160
- --data-dir=/data/tikv0
- --pd=pd0:2379
- --config=/tikv.toml
- --log-file=/logs/tikv0.log
depends_on:
- "pd0"
restart: on-failure
tikv1:
image: pingcap/tikv:latest
volumes:
- ./config/tikv.toml:/tikv.toml:ro
- ./data:/data
- ./logs:/logs
command:
- --addr=0.0.0.0:20160
- --advertise-addr=tikv1:20160
- --data-dir=/data/tikv1
- --pd=pd0:2379
- --config=/tikv.toml
- --log-file=/logs/tikv1.log
depends_on:
- "pd0"
restart: on-failure
tidb:
image: pingcap/tidb:latest
ports:
- "4000:4000"
- "10080:10080"
volumes:
- ./config/tidb.toml:/tidb.toml:ro
- ./logs:/logs
command:
- --store=tikv
- --path=pd0:2379
- --config=/tidb.toml
- --log-file=/logs/tidb.log
- --advertise-address=tidb
depends_on:
- "tikv0"
- "tikv1"
restart: on-failure

View File

@ -27,7 +27,7 @@ type siprng struct {
k0, k1, ctr uint64
}
// siphash implements SipHash-2-4, accepting a uint64 as a message.
// siphash implements SipHash-2-4, accepting an uint64 as a message.
func siphash(k0, k1, m uint64) uint64 {
// Initialization.
v0 := k0 ^ 0x736f6d6570736575

View File

@ -153,7 +153,7 @@ func (input *BeegoInput) IsHead() bool {
return input.Is("HEAD")
}
// IsOptions Is this a OPTIONS method request?
// IsOptions Is this an OPTIONS method request?
func (input *BeegoInput) IsOptions() bool {
return input.Is("OPTIONS")
}

View File

@ -15,8 +15,10 @@
package web
import (
"bytes"
"errors"
"fmt"
"io"
"net/http"
"path"
"reflect"
@ -211,6 +213,7 @@ func (p *ControllerRegister) Init() {
// Add controller handler and pattern rules to ControllerRegister.
// usage:
//
// default methods is the same name as method
// Add("/user",&UserController{})
// Add("/api/list",&RestController{},"*:ListFood")
@ -348,9 +351,10 @@ func (p *ControllerRegister) Include(cList ...ControllerInterface) {
// GetContext returns a context from pool, so usually you should remember to call Reset function to clean the context
// And don't forget to give back context to pool
// example:
// ctx := p.GetContext()
// ctx.Reset(w, q)
// defer p.GiveBackContext(ctx)
//
// ctx := p.GetContext()
// ctx.Reset(w, q)
// defer p.GiveBackContext(ctx)
func (p *ControllerRegister) GetContext() *beecontext.Context {
return p.pool.Get().(*beecontext.Context)
}
@ -362,14 +366,16 @@ func (p *ControllerRegister) GiveBackContext(ctx *beecontext.Context) {
// CtrlGet add get method
// usage:
// type MyController struct {
// web.Controller
// }
// func (m MyController) Ping() {
// m.Ctx.Output.Body([]byte("hello world"))
// }
//
// CtrlGet("/api/:id", MyController.Ping)
// type MyController struct {
// web.Controller
// }
// func (m MyController) Ping() {
// m.Ctx.Output.Body([]byte("hello world"))
// }
//
// CtrlGet("/api/:id", MyController.Ping)
//
// If the receiver of function Ping is pointer, you should use CtrlGet("/api/:id", (*MyController).Ping)
func (p *ControllerRegister) CtrlGet(pattern string, f interface{}) {
p.AddRouterMethod(http.MethodGet, pattern, f)
@ -377,14 +383,16 @@ func (p *ControllerRegister) CtrlGet(pattern string, f interface{}) {
// CtrlPost add post method
// usage:
// type MyController struct {
// web.Controller
// }
// func (m MyController) Ping() {
// m.Ctx.Output.Body([]byte("hello world"))
// }
//
// CtrlPost("/api/:id", MyController.Ping)
// type MyController struct {
// web.Controller
// }
// func (m MyController) Ping() {
// m.Ctx.Output.Body([]byte("hello world"))
// }
//
// CtrlPost("/api/:id", MyController.Ping)
//
// If the receiver of function Ping is pointer, you should use CtrlPost("/api/:id", (*MyController).Ping)
func (p *ControllerRegister) CtrlPost(pattern string, f interface{}) {
p.AddRouterMethod(http.MethodPost, pattern, f)
@ -392,14 +400,16 @@ func (p *ControllerRegister) CtrlPost(pattern string, f interface{}) {
// CtrlHead add head method
// usage:
// type MyController struct {
// web.Controller
// }
// func (m MyController) Ping() {
// m.Ctx.Output.Body([]byte("hello world"))
// }
//
// CtrlHead("/api/:id", MyController.Ping)
// type MyController struct {
// web.Controller
// }
// func (m MyController) Ping() {
// m.Ctx.Output.Body([]byte("hello world"))
// }
//
// CtrlHead("/api/:id", MyController.Ping)
//
// If the receiver of function Ping is pointer, you should use CtrlHead("/api/:id", (*MyController).Ping)
func (p *ControllerRegister) CtrlHead(pattern string, f interface{}) {
p.AddRouterMethod(http.MethodHead, pattern, f)
@ -422,70 +432,75 @@ func (p *ControllerRegister) CtrlPut(pattern string, f interface{}) {
// CtrlPatch add patch method
// usage:
// type MyController struct {
// web.Controller
// }
// func (m MyController) Ping() {
// m.Ctx.Output.Body([]byte("hello world"))
// }
//
// CtrlPatch("/api/:id", MyController.Ping)
// type MyController struct {
// web.Controller
// }
// func (m MyController) Ping() {
// m.Ctx.Output.Body([]byte("hello world"))
// }
//
// CtrlPatch("/api/:id", MyController.Ping)
func (p *ControllerRegister) CtrlPatch(pattern string, f interface{}) {
p.AddRouterMethod(http.MethodPatch, pattern, f)
}
// CtrlDelete add delete method
// usage:
// type MyController struct {
// web.Controller
// }
// func (m MyController) Ping() {
// m.Ctx.Output.Body([]byte("hello world"))
// }
//
// CtrlDelete("/api/:id", MyController.Ping)
// type MyController struct {
// web.Controller
// }
// func (m MyController) Ping() {
// m.Ctx.Output.Body([]byte("hello world"))
// }
//
// CtrlDelete("/api/:id", MyController.Ping)
func (p *ControllerRegister) CtrlDelete(pattern string, f interface{}) {
p.AddRouterMethod(http.MethodDelete, pattern, f)
}
// CtrlOptions add options method
// usage:
// type MyController struct {
// web.Controller
// }
// func (m MyController) Ping() {
// m.Ctx.Output.Body([]byte("hello world"))
// }
//
// CtrlOptions("/api/:id", MyController.Ping)
// type MyController struct {
// web.Controller
// }
// func (m MyController) Ping() {
// m.Ctx.Output.Body([]byte("hello world"))
// }
//
// CtrlOptions("/api/:id", MyController.Ping)
func (p *ControllerRegister) CtrlOptions(pattern string, f interface{}) {
p.AddRouterMethod(http.MethodOptions, pattern, f)
}
// CtrlAny add all method
// usage:
// type MyController struct {
// web.Controller
// }
// func (m MyController) Ping() {
// m.Ctx.Output.Body([]byte("hello world"))
// }
//
// CtrlAny("/api/:id", MyController.Ping)
// type MyController struct {
// web.Controller
// }
// func (m MyController) Ping() {
// m.Ctx.Output.Body([]byte("hello world"))
// }
//
// CtrlAny("/api/:id", MyController.Ping)
func (p *ControllerRegister) CtrlAny(pattern string, f interface{}) {
p.AddRouterMethod("*", pattern, f)
}
// AddRouterMethod add http method router
// usage:
// type MyController struct {
// web.Controller
// }
// func (m MyController) Ping() {
// m.Ctx.Output.Body([]byte("hello world"))
// }
//
// AddRouterMethod("get","/api/:id", MyController.Ping)
// type MyController struct {
// web.Controller
// }
// func (m MyController) Ping() {
// m.Ctx.Output.Body([]byte("hello world"))
// }
//
// AddRouterMethod("get","/api/:id", MyController.Ping)
func (p *ControllerRegister) AddRouterMethod(httpMethod, pattern string, f interface{}) {
httpMethod = p.getUpperMethodString(httpMethod)
ct, methodName := getReflectTypeAndMethod(f)
@ -624,81 +639,90 @@ type HandleFunc func(ctx *beecontext.Context)
// Get add get method
// usage:
// Get("/", func(ctx *context.Context){
// ctx.Output.Body("hello world")
// })
//
// Get("/", func(ctx *context.Context){
// ctx.Output.Body("hello world")
// })
func (p *ControllerRegister) Get(pattern string, f HandleFunc) {
p.AddMethod("get", pattern, f)
}
// Post add post method
// usage:
// Post("/api", func(ctx *context.Context){
// ctx.Output.Body("hello world")
// })
//
// Post("/api", func(ctx *context.Context){
// ctx.Output.Body("hello world")
// })
func (p *ControllerRegister) Post(pattern string, f HandleFunc) {
p.AddMethod("post", pattern, f)
}
// Put add put method
// usage:
// Put("/api/:id", func(ctx *context.Context){
// ctx.Output.Body("hello world")
// })
//
// Put("/api/:id", func(ctx *context.Context){
// ctx.Output.Body("hello world")
// })
func (p *ControllerRegister) Put(pattern string, f HandleFunc) {
p.AddMethod("put", pattern, f)
}
// Delete add delete method
// usage:
// Delete("/api/:id", func(ctx *context.Context){
// ctx.Output.Body("hello world")
// })
//
// Delete("/api/:id", func(ctx *context.Context){
// ctx.Output.Body("hello world")
// })
func (p *ControllerRegister) Delete(pattern string, f HandleFunc) {
p.AddMethod("delete", pattern, f)
}
// Head add head method
// usage:
// Head("/api/:id", func(ctx *context.Context){
// ctx.Output.Body("hello world")
// })
//
// Head("/api/:id", func(ctx *context.Context){
// ctx.Output.Body("hello world")
// })
func (p *ControllerRegister) Head(pattern string, f HandleFunc) {
p.AddMethod("head", pattern, f)
}
// Patch add patch method
// usage:
// Patch("/api/:id", func(ctx *context.Context){
// ctx.Output.Body("hello world")
// })
//
// Patch("/api/:id", func(ctx *context.Context){
// ctx.Output.Body("hello world")
// })
func (p *ControllerRegister) Patch(pattern string, f HandleFunc) {
p.AddMethod("patch", pattern, f)
}
// Options add options method
// usage:
// Options("/api/:id", func(ctx *context.Context){
// ctx.Output.Body("hello world")
// })
//
// Options("/api/:id", func(ctx *context.Context){
// ctx.Output.Body("hello world")
// })
func (p *ControllerRegister) Options(pattern string, f HandleFunc) {
p.AddMethod("options", pattern, f)
}
// Any add all method
// usage:
// Any("/api/:id", func(ctx *context.Context){
// ctx.Output.Body("hello world")
// })
//
// Any("/api/:id", func(ctx *context.Context){
// ctx.Output.Body("hello world")
// })
func (p *ControllerRegister) Any(pattern string, f HandleFunc) {
p.AddMethod("*", pattern, f)
}
// AddMethod add http method router
// usage:
// AddMethod("get","/api/:id", func(ctx *context.Context){
// ctx.Output.Body("hello world")
// })
//
// AddMethod("get","/api/:id", func(ctx *context.Context){
// ctx.Output.Body("hello world")
// })
func (p *ControllerRegister) AddMethod(method, pattern string, f HandleFunc) {
method = p.getUpperMethodString(method)
@ -772,8 +796,8 @@ func (p *ControllerRegister) addAutoPrefixMethod(prefix, controllerName, methodN
// InsertFilter Add a FilterFunc with pattern rule and action constant.
// params is for:
// 1. setting the returnOnOutput value (false allows multiple filters to execute)
// 2. determining whether or not params need to be reset.
// 1. setting the returnOnOutput value (false allows multiple filters to execute)
// 2. determining whether or not params need to be reset.
func (p *ControllerRegister) InsertFilter(pattern string, pos int, filter FilterFunc, opts ...FilterOpt) error {
opts = append(opts, WithCaseSensitive(p.cfg.RouterCaseSensitive))
mr := newFilterRouter(pattern, filter, opts...)
@ -784,13 +808,14 @@ func (p *ControllerRegister) InsertFilter(pattern string, pos int, filter Filter
// but it will using chainRoot.filterFunc as input to build a new filterFunc
// for example, assume that chainRoot is funcA
// and we add new FilterChain
// fc := func(next) {
// return func(ctx) {
// // do something
// next(ctx)
// // do something
// }
// }
//
// fc := func(next) {
// return func(ctx) {
// // do something
// next(ctx)
// // do something
// }
// }
func (p *ControllerRegister) InsertFilterChain(pattern string, chain FilterChain, opts ...FilterOpt) {
opts = append([]FilterOpt{WithCaseSensitive(p.cfg.RouterCaseSensitive)}, opts...)
p.filterChains = append(p.filterChains, filterChainConfig{
@ -1025,10 +1050,14 @@ func (p *ControllerRegister) serveHttp(ctx *beecontext.Context) {
}
if r.Method != http.MethodGet && r.Method != http.MethodHead {
body := ctx.Input.Context.Request.Body
if body == nil {
body = io.NopCloser(bytes.NewReader([]byte{}))
}
if ctx.Input.IsUpload() {
ctx.Input.Context.Request.Body = http.MaxBytesReader(ctx.Input.Context.ResponseWriter,
ctx.Input.Context.Request.Body,
body,
p.cfg.MaxUploadSize)
} else if p.cfg.CopyRequestBody {
// connection will close if the incoming data are larger (RFC 7231, 6.5.11)
@ -1040,7 +1069,7 @@ func (p *ControllerRegister) serveHttp(ctx *beecontext.Context) {
ctx.Input.CopyBody(p.cfg.MaxMemory)
} else {
ctx.Input.Context.Request.Body = http.MaxBytesReader(ctx.Input.Context.ResponseWriter,
ctx.Input.Context.Request.Body,
body,
p.cfg.MaxMemory)
}

View File

@ -98,7 +98,7 @@ func encrypt(block cipher.Block, value []byte) ([]byte, error) {
// decrypt decrypts a value using the given block in counter mode.
//
// The value to be decrypted must be prepended by a initialization vector
// The value to be decrypted must be prepended by an initialization vector
// (http://goo.gl/zF67k) with the length of the block size.
func decrypt(block cipher.Block, value []byte) ([]byte, error) {
size := block.BlockSize()

View File

@ -103,7 +103,7 @@ func init() {
beegoTplFuncMap["lt"] = lt // <
beegoTplFuncMap["ne"] = ne // !=
beegoTplFuncMap["urlfor"] = URLFor // build a URL to match a Controller and it's method
beegoTplFuncMap["urlfor"] = URLFor // build an URL to match a Controller and it's method
}
// AddFuncMap let user to register a func in the template.

View File

@ -221,7 +221,7 @@ func (f optionFunc) apply(t *Task) {
f(t)
}
// TimeoutOption return a option to set timeout duration for task
// TimeoutOption return an option to set timeout duration for task
func TimeoutOption(timeout time.Duration) Option {
return optionFunc(func(t *Task) {
t.Timeout = timeout