build(deps): bump github.com/labstack/echo/v4 from 4.7.2 to 4.8.0
Bumps [github.com/labstack/echo/v4](https://github.com/labstack/echo) from 4.7.2 to 4.8.0. - [Release notes](https://github.com/labstack/echo/releases) - [Changelog](https://github.com/labstack/echo/blob/master/CHANGELOG.md) - [Commits](https://github.com/labstack/echo/compare/v4.7.2...v4.8.0) --- updated-dependencies: - dependency-name: github.com/labstack/echo/v4 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
parent
98a7457e08
commit
d75e01aef0
14 changed files with 439 additions and 197 deletions
2
go.mod
2
go.mod
|
|
@ -32,7 +32,7 @@ require (
|
||||||
github.com/jackc/pgx/v4 v4.17.1
|
github.com/jackc/pgx/v4 v4.17.1
|
||||||
github.com/julienschmidt/httprouter v1.3.0
|
github.com/julienschmidt/httprouter v1.3.0
|
||||||
github.com/kolo/xmlrpc v0.0.0-20201022064351-38db28db192b
|
github.com/kolo/xmlrpc v0.0.0-20201022064351-38db28db192b
|
||||||
github.com/labstack/echo/v4 v4.7.2
|
github.com/labstack/echo/v4 v4.8.0
|
||||||
github.com/labstack/gommon v0.3.1
|
github.com/labstack/gommon v0.3.1
|
||||||
github.com/opencontainers/go-digest v1.0.0
|
github.com/opencontainers/go-digest v1.0.0
|
||||||
github.com/opencontainers/image-spec v1.0.3-0.20220114050600-8b9d41f48198
|
github.com/opencontainers/image-spec v1.0.3-0.20220114050600-8b9d41f48198
|
||||||
|
|
|
||||||
4
go.sum
4
go.sum
|
|
@ -1099,8 +1099,8 @@ github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+
|
||||||
github.com/kyoh86/exportloopref v0.1.8/go.mod h1:1tUcJeiioIs7VWe5gcOObrux3lb66+sBqGZrRkMwPgg=
|
github.com/kyoh86/exportloopref v0.1.8/go.mod h1:1tUcJeiioIs7VWe5gcOObrux3lb66+sBqGZrRkMwPgg=
|
||||||
github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg=
|
github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg=
|
||||||
github.com/labstack/echo/v4 v4.3.0/go.mod h1:PvmtTvhVqKDzDQy4d3bWzPjZLzom4iQbAZy2sgZ/qI8=
|
github.com/labstack/echo/v4 v4.3.0/go.mod h1:PvmtTvhVqKDzDQy4d3bWzPjZLzom4iQbAZy2sgZ/qI8=
|
||||||
github.com/labstack/echo/v4 v4.7.2 h1:Kv2/p8OaQ+M6Ex4eGimg9b9e6icoxA42JSlOR3msKtI=
|
github.com/labstack/echo/v4 v4.8.0 h1:wdc6yKVaHxkNOEdz4cRZs1pQkwSXPiRjq69yWP4QQS8=
|
||||||
github.com/labstack/echo/v4 v4.7.2/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks=
|
github.com/labstack/echo/v4 v4.8.0/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks=
|
||||||
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
|
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
|
||||||
github.com/labstack/gommon v0.3.1 h1:OomWaJXm7xR6L1HmEtGyQf26TEn7V6X88mktX9kee9o=
|
github.com/labstack/gommon v0.3.1 h1:OomWaJXm7xR6L1HmEtGyQf26TEn7V6X88mktX9kee9o=
|
||||||
github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
|
github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
|
||||||
|
|
|
||||||
31
vendor/github.com/labstack/echo/v4/CHANGELOG.md
generated
vendored
31
vendor/github.com/labstack/echo/v4/CHANGELOG.md
generated
vendored
|
|
@ -1,5 +1,36 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## v4.8.0 - 2022-08-10
|
||||||
|
|
||||||
|
**Most notable things**
|
||||||
|
|
||||||
|
You can now add any arbitrary HTTP method type as a route [#2237](https://github.com/labstack/echo/pull/2237)
|
||||||
|
```go
|
||||||
|
e.Add("COPY", "/*", func(c echo.Context) error
|
||||||
|
return c.String(http.StatusOK, "OK COPY")
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
You can add custom 404 handler for specific paths [#2217](https://github.com/labstack/echo/pull/2217)
|
||||||
|
```go
|
||||||
|
e.RouteNotFound("/*", func(c echo.Context) error { return c.NoContent(http.StatusNotFound) })
|
||||||
|
|
||||||
|
g := e.Group("/images")
|
||||||
|
g.RouteNotFound("/*", func(c echo.Context) error { return c.NoContent(http.StatusNotFound) })
|
||||||
|
```
|
||||||
|
|
||||||
|
**Enhancements**
|
||||||
|
|
||||||
|
* Add new value binding methods (UnixTimeMilli,TextUnmarshaler,JSONUnmarshaler) to Valuebinder [#2127](https://github.com/labstack/echo/pull/2127)
|
||||||
|
* Refactor: body_limit middleware unit test [#2145](https://github.com/labstack/echo/pull/2145)
|
||||||
|
* Refactor: Timeout mw: rework how test waits for timeout. [#2187](https://github.com/labstack/echo/pull/2187)
|
||||||
|
* BasicAuth middleware returns 500 InternalServerError on invalid base64 strings but should return 400 [#2191](https://github.com/labstack/echo/pull/2191)
|
||||||
|
* Refactor: duplicated findStaticChild process at findChildWithLabel [#2176](https://github.com/labstack/echo/pull/2176)
|
||||||
|
* Allow different param names in different methods with same path scheme [#2209](https://github.com/labstack/echo/pull/2209)
|
||||||
|
* Add support for registering handlers for different 404 routes [#2217](https://github.com/labstack/echo/pull/2217)
|
||||||
|
* Middlewares should use errors.As() instead of type assertion on HTTPError [#2227](https://github.com/labstack/echo/pull/2227)
|
||||||
|
* Allow arbitrary HTTP method types to be added as routes [#2237](https://github.com/labstack/echo/pull/2237)
|
||||||
|
|
||||||
## v4.7.2 - 2022-03-16
|
## v4.7.2 - 2022-03-16
|
||||||
|
|
||||||
**Fixes**
|
**Fixes**
|
||||||
|
|
|
||||||
6
vendor/github.com/labstack/echo/v4/Makefile
generated
vendored
6
vendor/github.com/labstack/echo/v4/Makefile
generated
vendored
|
|
@ -9,7 +9,7 @@ tag:
|
||||||
check: lint vet race ## Check project
|
check: lint vet race ## Check project
|
||||||
|
|
||||||
init:
|
init:
|
||||||
@go get -u golang.org/x/lint/golint
|
@go install golang.org/x/lint/golint@latest
|
||||||
|
|
||||||
lint: ## Lint the files
|
lint: ## Lint the files
|
||||||
@golint -set_exit_status ${PKG_LIST}
|
@golint -set_exit_status ${PKG_LIST}
|
||||||
|
|
@ -29,6 +29,6 @@ benchmark: ## Run benchmarks
|
||||||
help: ## Display this help screen
|
help: ## Display this help screen
|
||||||
@grep -h -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
|
@grep -h -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
|
||||||
|
|
||||||
goversion ?= "1.15"
|
goversion ?= "1.16"
|
||||||
test_version: ## Run tests inside Docker with given version (defaults to 1.15 oldest supported). Example: make test_version goversion=1.15
|
test_version: ## Run tests inside Docker with given version (defaults to 1.15 oldest supported). Example: make test_version goversion=1.16
|
||||||
@docker run --rm -it -v $(shell pwd):/project golang:$(goversion) /bin/sh -c "cd /project && make init check"
|
@docker run --rm -it -v $(shell pwd):/project golang:$(goversion) /bin/sh -c "cd /project && make init check"
|
||||||
|
|
|
||||||
19
vendor/github.com/labstack/echo/v4/README.md
generated
vendored
19
vendor/github.com/labstack/echo/v4/README.md
generated
vendored
|
|
@ -93,15 +93,16 @@ func hello(c echo.Context) error {
|
||||||
|
|
||||||
# Third-party middlewares
|
# Third-party middlewares
|
||||||
|
|
||||||
| Repository | Description |
|
| Repository | Description |
|
||||||
|------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| [github.com/labstack/echo-contrib](https://github.com/labstack/echo-contrib) | (by Echo team) [casbin](https://github.com/casbin/casbin), [gorilla/sessions](https://github.com/gorilla/sessions), [jaegertracing](github.com/uber/jaeger-client-go), [prometheus](https://github.com/prometheus/client_golang/), [pprof](https://pkg.go.dev/net/http/pprof), [zipkin](https://github.com/openzipkin/zipkin-go) middlewares |
|
| [github.com/labstack/echo-contrib](https://github.com/labstack/echo-contrib) | (by Echo team) [casbin](https://github.com/casbin/casbin), [gorilla/sessions](https://github.com/gorilla/sessions), [jaegertracing](github.com/uber/jaeger-client-go), [prometheus](https://github.com/prometheus/client_golang/), [pprof](https://pkg.go.dev/net/http/pprof), [zipkin](https://github.com/openzipkin/zipkin-go) middlewares |
|
||||||
| [deepmap/oapi-codegen](https://github.com/deepmap/oapi-codegen) | Automatically generate RESTful API documentation with [OpenAPI](https://swagger.io/specification/) Client and Server Code Generator |
|
| [deepmap/oapi-codegen](https://github.com/deepmap/oapi-codegen) | Automatically generate RESTful API documentation with [OpenAPI](https://swagger.io/specification/) Client and Server Code Generator |
|
||||||
| [github.com/swaggo/echo-swagger](https://github.com/swaggo/echo-swagger) | Automatically generate RESTful API documentation with [Swagger](https://swagger.io/) 2.0. |
|
| [github.com/swaggo/echo-swagger](https://github.com/swaggo/echo-swagger) | Automatically generate RESTful API documentation with [Swagger](https://swagger.io/) 2.0. |
|
||||||
| [github.com/ziflex/lecho](https://github.com/ziflex/lecho) | [Zerolog](https://github.com/rs/zerolog) logging library wrapper for Echo logger interface. |
|
| [github.com/ziflex/lecho](https://github.com/ziflex/lecho) | [Zerolog](https://github.com/rs/zerolog) logging library wrapper for Echo logger interface. |
|
||||||
| [github.com/brpaz/echozap](https://github.com/brpaz/echozap) | Uber´s [Zap](https://github.com/uber-go/zap) logging library wrapper for Echo logger interface. |
|
| [github.com/brpaz/echozap](https://github.com/brpaz/echozap) | Uber´s [Zap](https://github.com/uber-go/zap) logging library wrapper for Echo logger interface. |
|
||||||
| [github.com/darkweak/souin/plugins/echo](https://github.com/darkweak/souin/tree/master/plugins/echo) | HTTP cache system based on [Souin](https://github.com/darkweak/souin) to automatically get your endpoints cached. It supports some distributed and non-distributed storage systems depending your needs. |
|
| [github.com/darkweak/souin/plugins/echo](https://github.com/darkweak/souin/tree/master/plugins/echo) | HTTP cache system based on [Souin](https://github.com/darkweak/souin) to automatically get your endpoints cached. It supports some distributed and non-distributed storage systems depending your needs. |
|
||||||
| [github.com/mikestefanello/pagoda](https://github.com/mikestefanello/pagoda) | Rapid, easy full-stack web development starter kit built with Echo.
|
| [github.com/mikestefanello/pagoda](https://github.com/mikestefanello/pagoda) | Rapid, easy full-stack web development starter kit built with Echo. |
|
||||||
|
| [github.com/go-woo/protoc-gen-echo](https://github.com/go-woo/protoc-gen-echo) | ProtoBuf generate Echo server side code |
|
||||||
|
|
||||||
Please send a PR to add your own library here.
|
Please send a PR to add your own library here.
|
||||||
|
|
||||||
|
|
|
||||||
197
vendor/github.com/labstack/echo/v4/binder.go
generated
vendored
197
vendor/github.com/labstack/echo/v4/binder.go
generated
vendored
|
|
@ -1,6 +1,8 @@
|
||||||
package echo
|
package echo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
@ -52,8 +54,11 @@ import (
|
||||||
* time
|
* time
|
||||||
* duration
|
* duration
|
||||||
* BindUnmarshaler() interface
|
* BindUnmarshaler() interface
|
||||||
|
* TextUnmarshaler() interface
|
||||||
|
* JSONUnmarshaler() interface
|
||||||
* UnixTime() - converts unix time (integer) to time.Time
|
* UnixTime() - converts unix time (integer) to time.Time
|
||||||
* UnixTimeNano() - converts unix time with nano second precision (integer) to time.Time
|
* UnixTimeMilli() - converts unix time with millisecond precision (integer) to time.Time
|
||||||
|
* UnixTimeNano() - converts unix time with nanosecond precision (integer) to time.Time
|
||||||
* CustomFunc() - callback function for your custom conversion logic. Signature `func(values []string) []error`
|
* CustomFunc() - callback function for your custom conversion logic. Signature `func(values []string) []error`
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -204,7 +209,7 @@ func (b *ValueBinder) CustomFunc(sourceParam string, customFunc func(values []st
|
||||||
return b.customFunc(sourceParam, customFunc, false)
|
return b.customFunc(sourceParam, customFunc, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustCustomFunc requires parameter values to exist to be bind with Func. Returns error when value does not exist.
|
// MustCustomFunc requires parameter values to exist to bind with Func. Returns error when value does not exist.
|
||||||
func (b *ValueBinder) MustCustomFunc(sourceParam string, customFunc func(values []string) []error) *ValueBinder {
|
func (b *ValueBinder) MustCustomFunc(sourceParam string, customFunc func(values []string) []error) *ValueBinder {
|
||||||
return b.customFunc(sourceParam, customFunc, true)
|
return b.customFunc(sourceParam, customFunc, true)
|
||||||
}
|
}
|
||||||
|
|
@ -241,7 +246,7 @@ func (b *ValueBinder) String(sourceParam string, dest *string) *ValueBinder {
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustString requires parameter value to exist to be bind to string variable. Returns error when value does not exist
|
// MustString requires parameter value to exist to bind to string variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustString(sourceParam string, dest *string) *ValueBinder {
|
func (b *ValueBinder) MustString(sourceParam string, dest *string) *ValueBinder {
|
||||||
if b.failFast && b.errors != nil {
|
if b.failFast && b.errors != nil {
|
||||||
return b
|
return b
|
||||||
|
|
@ -270,7 +275,7 @@ func (b *ValueBinder) Strings(sourceParam string, dest *[]string) *ValueBinder {
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustStrings requires parameter values to exist to be bind to slice of string variables. Returns error when value does not exist
|
// MustStrings requires parameter values to exist to bind to slice of string variables. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustStrings(sourceParam string, dest *[]string) *ValueBinder {
|
func (b *ValueBinder) MustStrings(sourceParam string, dest *[]string) *ValueBinder {
|
||||||
if b.failFast && b.errors != nil {
|
if b.failFast && b.errors != nil {
|
||||||
return b
|
return b
|
||||||
|
|
@ -302,7 +307,7 @@ func (b *ValueBinder) BindUnmarshaler(sourceParam string, dest BindUnmarshaler)
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustBindUnmarshaler requires parameter value to exist to be bind to destination implementing BindUnmarshaler interface.
|
// MustBindUnmarshaler requires parameter value to exist to bind to destination implementing BindUnmarshaler interface.
|
||||||
// Returns error when value does not exist
|
// Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustBindUnmarshaler(sourceParam string, dest BindUnmarshaler) *ValueBinder {
|
func (b *ValueBinder) MustBindUnmarshaler(sourceParam string, dest BindUnmarshaler) *ValueBinder {
|
||||||
if b.failFast && b.errors != nil {
|
if b.failFast && b.errors != nil {
|
||||||
|
|
@ -321,13 +326,85 @@ func (b *ValueBinder) MustBindUnmarshaler(sourceParam string, dest BindUnmarshal
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// JSONUnmarshaler binds parameter to destination implementing json.Unmarshaler interface
|
||||||
|
func (b *ValueBinder) JSONUnmarshaler(sourceParam string, dest json.Unmarshaler) *ValueBinder {
|
||||||
|
if b.failFast && b.errors != nil {
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp := b.ValueFunc(sourceParam)
|
||||||
|
if tmp == "" {
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := dest.UnmarshalJSON([]byte(tmp)); err != nil {
|
||||||
|
b.setError(b.ErrorFunc(sourceParam, []string{tmp}, "failed to bind field value to json.Unmarshaler interface", err))
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// MustJSONUnmarshaler requires parameter value to exist to bind to destination implementing json.Unmarshaler interface.
|
||||||
|
// Returns error when value does not exist
|
||||||
|
func (b *ValueBinder) MustJSONUnmarshaler(sourceParam string, dest json.Unmarshaler) *ValueBinder {
|
||||||
|
if b.failFast && b.errors != nil {
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp := b.ValueFunc(sourceParam)
|
||||||
|
if tmp == "" {
|
||||||
|
b.setError(b.ErrorFunc(sourceParam, []string{tmp}, "required field value is empty", nil))
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := dest.UnmarshalJSON([]byte(tmp)); err != nil {
|
||||||
|
b.setError(b.ErrorFunc(sourceParam, []string{tmp}, "failed to bind field value to json.Unmarshaler interface", err))
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// TextUnmarshaler binds parameter to destination implementing encoding.TextUnmarshaler interface
|
||||||
|
func (b *ValueBinder) TextUnmarshaler(sourceParam string, dest encoding.TextUnmarshaler) *ValueBinder {
|
||||||
|
if b.failFast && b.errors != nil {
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp := b.ValueFunc(sourceParam)
|
||||||
|
if tmp == "" {
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := dest.UnmarshalText([]byte(tmp)); err != nil {
|
||||||
|
b.setError(b.ErrorFunc(sourceParam, []string{tmp}, "failed to bind field value to encoding.TextUnmarshaler interface", err))
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// MustTextUnmarshaler requires parameter value to exist to bind to destination implementing encoding.TextUnmarshaler interface.
|
||||||
|
// Returns error when value does not exist
|
||||||
|
func (b *ValueBinder) MustTextUnmarshaler(sourceParam string, dest encoding.TextUnmarshaler) *ValueBinder {
|
||||||
|
if b.failFast && b.errors != nil {
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp := b.ValueFunc(sourceParam)
|
||||||
|
if tmp == "" {
|
||||||
|
b.setError(b.ErrorFunc(sourceParam, []string{tmp}, "required field value is empty", nil))
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := dest.UnmarshalText([]byte(tmp)); err != nil {
|
||||||
|
b.setError(b.ErrorFunc(sourceParam, []string{tmp}, "failed to bind field value to encoding.TextUnmarshaler interface", err))
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
// BindWithDelimiter binds parameter to destination by suitable conversion function.
|
// BindWithDelimiter binds parameter to destination by suitable conversion function.
|
||||||
// Delimiter is used before conversion to split parameter value to separate values
|
// Delimiter is used before conversion to split parameter value to separate values
|
||||||
func (b *ValueBinder) BindWithDelimiter(sourceParam string, dest interface{}, delimiter string) *ValueBinder {
|
func (b *ValueBinder) BindWithDelimiter(sourceParam string, dest interface{}, delimiter string) *ValueBinder {
|
||||||
return b.bindWithDelimiter(sourceParam, dest, delimiter, false)
|
return b.bindWithDelimiter(sourceParam, dest, delimiter, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustBindWithDelimiter requires parameter value to exist to be bind destination by suitable conversion function.
|
// MustBindWithDelimiter requires parameter value to exist to bind destination by suitable conversion function.
|
||||||
// Delimiter is used before conversion to split parameter value to separate values
|
// Delimiter is used before conversion to split parameter value to separate values
|
||||||
func (b *ValueBinder) MustBindWithDelimiter(sourceParam string, dest interface{}, delimiter string) *ValueBinder {
|
func (b *ValueBinder) MustBindWithDelimiter(sourceParam string, dest interface{}, delimiter string) *ValueBinder {
|
||||||
return b.bindWithDelimiter(sourceParam, dest, delimiter, true)
|
return b.bindWithDelimiter(sourceParam, dest, delimiter, true)
|
||||||
|
|
@ -376,7 +453,7 @@ func (b *ValueBinder) Int64(sourceParam string, dest *int64) *ValueBinder {
|
||||||
return b.intValue(sourceParam, dest, 64, false)
|
return b.intValue(sourceParam, dest, 64, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustInt64 requires parameter value to exist to be bind to int64 variable. Returns error when value does not exist
|
// MustInt64 requires parameter value to exist to bind to int64 variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustInt64(sourceParam string, dest *int64) *ValueBinder {
|
func (b *ValueBinder) MustInt64(sourceParam string, dest *int64) *ValueBinder {
|
||||||
return b.intValue(sourceParam, dest, 64, true)
|
return b.intValue(sourceParam, dest, 64, true)
|
||||||
}
|
}
|
||||||
|
|
@ -386,7 +463,7 @@ func (b *ValueBinder) Int32(sourceParam string, dest *int32) *ValueBinder {
|
||||||
return b.intValue(sourceParam, dest, 32, false)
|
return b.intValue(sourceParam, dest, 32, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustInt32 requires parameter value to exist to be bind to int32 variable. Returns error when value does not exist
|
// MustInt32 requires parameter value to exist to bind to int32 variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustInt32(sourceParam string, dest *int32) *ValueBinder {
|
func (b *ValueBinder) MustInt32(sourceParam string, dest *int32) *ValueBinder {
|
||||||
return b.intValue(sourceParam, dest, 32, true)
|
return b.intValue(sourceParam, dest, 32, true)
|
||||||
}
|
}
|
||||||
|
|
@ -396,7 +473,7 @@ func (b *ValueBinder) Int16(sourceParam string, dest *int16) *ValueBinder {
|
||||||
return b.intValue(sourceParam, dest, 16, false)
|
return b.intValue(sourceParam, dest, 16, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustInt16 requires parameter value to exist to be bind to int16 variable. Returns error when value does not exist
|
// MustInt16 requires parameter value to exist to bind to int16 variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustInt16(sourceParam string, dest *int16) *ValueBinder {
|
func (b *ValueBinder) MustInt16(sourceParam string, dest *int16) *ValueBinder {
|
||||||
return b.intValue(sourceParam, dest, 16, true)
|
return b.intValue(sourceParam, dest, 16, true)
|
||||||
}
|
}
|
||||||
|
|
@ -406,7 +483,7 @@ func (b *ValueBinder) Int8(sourceParam string, dest *int8) *ValueBinder {
|
||||||
return b.intValue(sourceParam, dest, 8, false)
|
return b.intValue(sourceParam, dest, 8, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustInt8 requires parameter value to exist to be bind to int8 variable. Returns error when value does not exist
|
// MustInt8 requires parameter value to exist to bind to int8 variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustInt8(sourceParam string, dest *int8) *ValueBinder {
|
func (b *ValueBinder) MustInt8(sourceParam string, dest *int8) *ValueBinder {
|
||||||
return b.intValue(sourceParam, dest, 8, true)
|
return b.intValue(sourceParam, dest, 8, true)
|
||||||
}
|
}
|
||||||
|
|
@ -416,7 +493,7 @@ func (b *ValueBinder) Int(sourceParam string, dest *int) *ValueBinder {
|
||||||
return b.intValue(sourceParam, dest, 0, false)
|
return b.intValue(sourceParam, dest, 0, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustInt requires parameter value to exist to be bind to int variable. Returns error when value does not exist
|
// MustInt requires parameter value to exist to bind to int variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustInt(sourceParam string, dest *int) *ValueBinder {
|
func (b *ValueBinder) MustInt(sourceParam string, dest *int) *ValueBinder {
|
||||||
return b.intValue(sourceParam, dest, 0, true)
|
return b.intValue(sourceParam, dest, 0, true)
|
||||||
}
|
}
|
||||||
|
|
@ -544,7 +621,7 @@ func (b *ValueBinder) Int64s(sourceParam string, dest *[]int64) *ValueBinder {
|
||||||
return b.intsValue(sourceParam, dest, false)
|
return b.intsValue(sourceParam, dest, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustInt64s requires parameter value to exist to be bind to int64 slice variable. Returns error when value does not exist
|
// MustInt64s requires parameter value to exist to bind to int64 slice variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustInt64s(sourceParam string, dest *[]int64) *ValueBinder {
|
func (b *ValueBinder) MustInt64s(sourceParam string, dest *[]int64) *ValueBinder {
|
||||||
return b.intsValue(sourceParam, dest, true)
|
return b.intsValue(sourceParam, dest, true)
|
||||||
}
|
}
|
||||||
|
|
@ -554,7 +631,7 @@ func (b *ValueBinder) Int32s(sourceParam string, dest *[]int32) *ValueBinder {
|
||||||
return b.intsValue(sourceParam, dest, false)
|
return b.intsValue(sourceParam, dest, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustInt32s requires parameter value to exist to be bind to int32 slice variable. Returns error when value does not exist
|
// MustInt32s requires parameter value to exist to bind to int32 slice variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustInt32s(sourceParam string, dest *[]int32) *ValueBinder {
|
func (b *ValueBinder) MustInt32s(sourceParam string, dest *[]int32) *ValueBinder {
|
||||||
return b.intsValue(sourceParam, dest, true)
|
return b.intsValue(sourceParam, dest, true)
|
||||||
}
|
}
|
||||||
|
|
@ -564,7 +641,7 @@ func (b *ValueBinder) Int16s(sourceParam string, dest *[]int16) *ValueBinder {
|
||||||
return b.intsValue(sourceParam, dest, false)
|
return b.intsValue(sourceParam, dest, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustInt16s requires parameter value to exist to be bind to int16 slice variable. Returns error when value does not exist
|
// MustInt16s requires parameter value to exist to bind to int16 slice variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustInt16s(sourceParam string, dest *[]int16) *ValueBinder {
|
func (b *ValueBinder) MustInt16s(sourceParam string, dest *[]int16) *ValueBinder {
|
||||||
return b.intsValue(sourceParam, dest, true)
|
return b.intsValue(sourceParam, dest, true)
|
||||||
}
|
}
|
||||||
|
|
@ -574,7 +651,7 @@ func (b *ValueBinder) Int8s(sourceParam string, dest *[]int8) *ValueBinder {
|
||||||
return b.intsValue(sourceParam, dest, false)
|
return b.intsValue(sourceParam, dest, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustInt8s requires parameter value to exist to be bind to int8 slice variable. Returns error when value does not exist
|
// MustInt8s requires parameter value to exist to bind to int8 slice variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustInt8s(sourceParam string, dest *[]int8) *ValueBinder {
|
func (b *ValueBinder) MustInt8s(sourceParam string, dest *[]int8) *ValueBinder {
|
||||||
return b.intsValue(sourceParam, dest, true)
|
return b.intsValue(sourceParam, dest, true)
|
||||||
}
|
}
|
||||||
|
|
@ -584,7 +661,7 @@ func (b *ValueBinder) Ints(sourceParam string, dest *[]int) *ValueBinder {
|
||||||
return b.intsValue(sourceParam, dest, false)
|
return b.intsValue(sourceParam, dest, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustInts requires parameter value to exist to be bind to int slice variable. Returns error when value does not exist
|
// MustInts requires parameter value to exist to bind to int slice variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustInts(sourceParam string, dest *[]int) *ValueBinder {
|
func (b *ValueBinder) MustInts(sourceParam string, dest *[]int) *ValueBinder {
|
||||||
return b.intsValue(sourceParam, dest, true)
|
return b.intsValue(sourceParam, dest, true)
|
||||||
}
|
}
|
||||||
|
|
@ -594,7 +671,7 @@ func (b *ValueBinder) Uint64(sourceParam string, dest *uint64) *ValueBinder {
|
||||||
return b.uintValue(sourceParam, dest, 64, false)
|
return b.uintValue(sourceParam, dest, 64, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustUint64 requires parameter value to exist to be bind to uint64 variable. Returns error when value does not exist
|
// MustUint64 requires parameter value to exist to bind to uint64 variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustUint64(sourceParam string, dest *uint64) *ValueBinder {
|
func (b *ValueBinder) MustUint64(sourceParam string, dest *uint64) *ValueBinder {
|
||||||
return b.uintValue(sourceParam, dest, 64, true)
|
return b.uintValue(sourceParam, dest, 64, true)
|
||||||
}
|
}
|
||||||
|
|
@ -604,7 +681,7 @@ func (b *ValueBinder) Uint32(sourceParam string, dest *uint32) *ValueBinder {
|
||||||
return b.uintValue(sourceParam, dest, 32, false)
|
return b.uintValue(sourceParam, dest, 32, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustUint32 requires parameter value to exist to be bind to uint32 variable. Returns error when value does not exist
|
// MustUint32 requires parameter value to exist to bind to uint32 variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustUint32(sourceParam string, dest *uint32) *ValueBinder {
|
func (b *ValueBinder) MustUint32(sourceParam string, dest *uint32) *ValueBinder {
|
||||||
return b.uintValue(sourceParam, dest, 32, true)
|
return b.uintValue(sourceParam, dest, 32, true)
|
||||||
}
|
}
|
||||||
|
|
@ -614,7 +691,7 @@ func (b *ValueBinder) Uint16(sourceParam string, dest *uint16) *ValueBinder {
|
||||||
return b.uintValue(sourceParam, dest, 16, false)
|
return b.uintValue(sourceParam, dest, 16, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustUint16 requires parameter value to exist to be bind to uint16 variable. Returns error when value does not exist
|
// MustUint16 requires parameter value to exist to bind to uint16 variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustUint16(sourceParam string, dest *uint16) *ValueBinder {
|
func (b *ValueBinder) MustUint16(sourceParam string, dest *uint16) *ValueBinder {
|
||||||
return b.uintValue(sourceParam, dest, 16, true)
|
return b.uintValue(sourceParam, dest, 16, true)
|
||||||
}
|
}
|
||||||
|
|
@ -624,7 +701,7 @@ func (b *ValueBinder) Uint8(sourceParam string, dest *uint8) *ValueBinder {
|
||||||
return b.uintValue(sourceParam, dest, 8, false)
|
return b.uintValue(sourceParam, dest, 8, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustUint8 requires parameter value to exist to be bind to uint8 variable. Returns error when value does not exist
|
// MustUint8 requires parameter value to exist to bind to uint8 variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustUint8(sourceParam string, dest *uint8) *ValueBinder {
|
func (b *ValueBinder) MustUint8(sourceParam string, dest *uint8) *ValueBinder {
|
||||||
return b.uintValue(sourceParam, dest, 8, true)
|
return b.uintValue(sourceParam, dest, 8, true)
|
||||||
}
|
}
|
||||||
|
|
@ -634,7 +711,7 @@ func (b *ValueBinder) Byte(sourceParam string, dest *byte) *ValueBinder {
|
||||||
return b.uintValue(sourceParam, dest, 8, false)
|
return b.uintValue(sourceParam, dest, 8, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustByte requires parameter value to exist to be bind to byte variable. Returns error when value does not exist
|
// MustByte requires parameter value to exist to bind to byte variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustByte(sourceParam string, dest *byte) *ValueBinder {
|
func (b *ValueBinder) MustByte(sourceParam string, dest *byte) *ValueBinder {
|
||||||
return b.uintValue(sourceParam, dest, 8, true)
|
return b.uintValue(sourceParam, dest, 8, true)
|
||||||
}
|
}
|
||||||
|
|
@ -644,7 +721,7 @@ func (b *ValueBinder) Uint(sourceParam string, dest *uint) *ValueBinder {
|
||||||
return b.uintValue(sourceParam, dest, 0, false)
|
return b.uintValue(sourceParam, dest, 0, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustUint requires parameter value to exist to be bind to uint variable. Returns error when value does not exist
|
// MustUint requires parameter value to exist to bind to uint variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustUint(sourceParam string, dest *uint) *ValueBinder {
|
func (b *ValueBinder) MustUint(sourceParam string, dest *uint) *ValueBinder {
|
||||||
return b.uintValue(sourceParam, dest, 0, true)
|
return b.uintValue(sourceParam, dest, 0, true)
|
||||||
}
|
}
|
||||||
|
|
@ -772,7 +849,7 @@ func (b *ValueBinder) Uint64s(sourceParam string, dest *[]uint64) *ValueBinder {
|
||||||
return b.uintsValue(sourceParam, dest, false)
|
return b.uintsValue(sourceParam, dest, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustUint64s requires parameter value to exist to be bind to uint64 slice variable. Returns error when value does not exist
|
// MustUint64s requires parameter value to exist to bind to uint64 slice variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustUint64s(sourceParam string, dest *[]uint64) *ValueBinder {
|
func (b *ValueBinder) MustUint64s(sourceParam string, dest *[]uint64) *ValueBinder {
|
||||||
return b.uintsValue(sourceParam, dest, true)
|
return b.uintsValue(sourceParam, dest, true)
|
||||||
}
|
}
|
||||||
|
|
@ -782,7 +859,7 @@ func (b *ValueBinder) Uint32s(sourceParam string, dest *[]uint32) *ValueBinder {
|
||||||
return b.uintsValue(sourceParam, dest, false)
|
return b.uintsValue(sourceParam, dest, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustUint32s requires parameter value to exist to be bind to uint32 slice variable. Returns error when value does not exist
|
// MustUint32s requires parameter value to exist to bind to uint32 slice variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustUint32s(sourceParam string, dest *[]uint32) *ValueBinder {
|
func (b *ValueBinder) MustUint32s(sourceParam string, dest *[]uint32) *ValueBinder {
|
||||||
return b.uintsValue(sourceParam, dest, true)
|
return b.uintsValue(sourceParam, dest, true)
|
||||||
}
|
}
|
||||||
|
|
@ -792,7 +869,7 @@ func (b *ValueBinder) Uint16s(sourceParam string, dest *[]uint16) *ValueBinder {
|
||||||
return b.uintsValue(sourceParam, dest, false)
|
return b.uintsValue(sourceParam, dest, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustUint16s requires parameter value to exist to be bind to uint16 slice variable. Returns error when value does not exist
|
// MustUint16s requires parameter value to exist to bind to uint16 slice variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustUint16s(sourceParam string, dest *[]uint16) *ValueBinder {
|
func (b *ValueBinder) MustUint16s(sourceParam string, dest *[]uint16) *ValueBinder {
|
||||||
return b.uintsValue(sourceParam, dest, true)
|
return b.uintsValue(sourceParam, dest, true)
|
||||||
}
|
}
|
||||||
|
|
@ -802,7 +879,7 @@ func (b *ValueBinder) Uint8s(sourceParam string, dest *[]uint8) *ValueBinder {
|
||||||
return b.uintsValue(sourceParam, dest, false)
|
return b.uintsValue(sourceParam, dest, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustUint8s requires parameter value to exist to be bind to uint8 slice variable. Returns error when value does not exist
|
// MustUint8s requires parameter value to exist to bind to uint8 slice variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustUint8s(sourceParam string, dest *[]uint8) *ValueBinder {
|
func (b *ValueBinder) MustUint8s(sourceParam string, dest *[]uint8) *ValueBinder {
|
||||||
return b.uintsValue(sourceParam, dest, true)
|
return b.uintsValue(sourceParam, dest, true)
|
||||||
}
|
}
|
||||||
|
|
@ -812,7 +889,7 @@ func (b *ValueBinder) Uints(sourceParam string, dest *[]uint) *ValueBinder {
|
||||||
return b.uintsValue(sourceParam, dest, false)
|
return b.uintsValue(sourceParam, dest, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustUints requires parameter value to exist to be bind to uint slice variable. Returns error when value does not exist
|
// MustUints requires parameter value to exist to bind to uint slice variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustUints(sourceParam string, dest *[]uint) *ValueBinder {
|
func (b *ValueBinder) MustUints(sourceParam string, dest *[]uint) *ValueBinder {
|
||||||
return b.uintsValue(sourceParam, dest, true)
|
return b.uintsValue(sourceParam, dest, true)
|
||||||
}
|
}
|
||||||
|
|
@ -822,7 +899,7 @@ func (b *ValueBinder) Bool(sourceParam string, dest *bool) *ValueBinder {
|
||||||
return b.boolValue(sourceParam, dest, false)
|
return b.boolValue(sourceParam, dest, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustBool requires parameter value to exist to be bind to bool variable. Returns error when value does not exist
|
// MustBool requires parameter value to exist to bind to bool variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustBool(sourceParam string, dest *bool) *ValueBinder {
|
func (b *ValueBinder) MustBool(sourceParam string, dest *bool) *ValueBinder {
|
||||||
return b.boolValue(sourceParam, dest, true)
|
return b.boolValue(sourceParam, dest, true)
|
||||||
}
|
}
|
||||||
|
|
@ -887,7 +964,7 @@ func (b *ValueBinder) Bools(sourceParam string, dest *[]bool) *ValueBinder {
|
||||||
return b.boolsValue(sourceParam, dest, false)
|
return b.boolsValue(sourceParam, dest, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustBools requires parameter values to exist to be bind to slice of bool variables. Returns error when values does not exist
|
// MustBools requires parameter values to exist to bind to slice of bool variables. Returns error when values does not exist
|
||||||
func (b *ValueBinder) MustBools(sourceParam string, dest *[]bool) *ValueBinder {
|
func (b *ValueBinder) MustBools(sourceParam string, dest *[]bool) *ValueBinder {
|
||||||
return b.boolsValue(sourceParam, dest, true)
|
return b.boolsValue(sourceParam, dest, true)
|
||||||
}
|
}
|
||||||
|
|
@ -897,7 +974,7 @@ func (b *ValueBinder) Float64(sourceParam string, dest *float64) *ValueBinder {
|
||||||
return b.floatValue(sourceParam, dest, 64, false)
|
return b.floatValue(sourceParam, dest, 64, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustFloat64 requires parameter value to exist to be bind to float64 variable. Returns error when value does not exist
|
// MustFloat64 requires parameter value to exist to bind to float64 variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustFloat64(sourceParam string, dest *float64) *ValueBinder {
|
func (b *ValueBinder) MustFloat64(sourceParam string, dest *float64) *ValueBinder {
|
||||||
return b.floatValue(sourceParam, dest, 64, true)
|
return b.floatValue(sourceParam, dest, 64, true)
|
||||||
}
|
}
|
||||||
|
|
@ -907,7 +984,7 @@ func (b *ValueBinder) Float32(sourceParam string, dest *float32) *ValueBinder {
|
||||||
return b.floatValue(sourceParam, dest, 32, false)
|
return b.floatValue(sourceParam, dest, 32, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustFloat32 requires parameter value to exist to be bind to float32 variable. Returns error when value does not exist
|
// MustFloat32 requires parameter value to exist to bind to float32 variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustFloat32(sourceParam string, dest *float32) *ValueBinder {
|
func (b *ValueBinder) MustFloat32(sourceParam string, dest *float32) *ValueBinder {
|
||||||
return b.floatValue(sourceParam, dest, 32, true)
|
return b.floatValue(sourceParam, dest, 32, true)
|
||||||
}
|
}
|
||||||
|
|
@ -992,7 +1069,7 @@ func (b *ValueBinder) Float64s(sourceParam string, dest *[]float64) *ValueBinder
|
||||||
return b.floatsValue(sourceParam, dest, false)
|
return b.floatsValue(sourceParam, dest, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustFloat64s requires parameter values to exist to be bind to slice of float64 variables. Returns error when values does not exist
|
// MustFloat64s requires parameter values to exist to bind to slice of float64 variables. Returns error when values does not exist
|
||||||
func (b *ValueBinder) MustFloat64s(sourceParam string, dest *[]float64) *ValueBinder {
|
func (b *ValueBinder) MustFloat64s(sourceParam string, dest *[]float64) *ValueBinder {
|
||||||
return b.floatsValue(sourceParam, dest, true)
|
return b.floatsValue(sourceParam, dest, true)
|
||||||
}
|
}
|
||||||
|
|
@ -1002,7 +1079,7 @@ func (b *ValueBinder) Float32s(sourceParam string, dest *[]float32) *ValueBinder
|
||||||
return b.floatsValue(sourceParam, dest, false)
|
return b.floatsValue(sourceParam, dest, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustFloat32s requires parameter values to exist to be bind to slice of float32 variables. Returns error when values does not exist
|
// MustFloat32s requires parameter values to exist to bind to slice of float32 variables. Returns error when values does not exist
|
||||||
func (b *ValueBinder) MustFloat32s(sourceParam string, dest *[]float32) *ValueBinder {
|
func (b *ValueBinder) MustFloat32s(sourceParam string, dest *[]float32) *ValueBinder {
|
||||||
return b.floatsValue(sourceParam, dest, true)
|
return b.floatsValue(sourceParam, dest, true)
|
||||||
}
|
}
|
||||||
|
|
@ -1012,7 +1089,7 @@ func (b *ValueBinder) Time(sourceParam string, dest *time.Time, layout string) *
|
||||||
return b.time(sourceParam, dest, layout, false)
|
return b.time(sourceParam, dest, layout, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustTime requires parameter value to exist to be bind to time.Time variable. Returns error when value does not exist
|
// MustTime requires parameter value to exist to bind to time.Time variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustTime(sourceParam string, dest *time.Time, layout string) *ValueBinder {
|
func (b *ValueBinder) MustTime(sourceParam string, dest *time.Time, layout string) *ValueBinder {
|
||||||
return b.time(sourceParam, dest, layout, true)
|
return b.time(sourceParam, dest, layout, true)
|
||||||
}
|
}
|
||||||
|
|
@ -1043,7 +1120,7 @@ func (b *ValueBinder) Times(sourceParam string, dest *[]time.Time, layout string
|
||||||
return b.times(sourceParam, dest, layout, false)
|
return b.times(sourceParam, dest, layout, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustTimes requires parameter values to exist to be bind to slice of time.Time variables. Returns error when values does not exist
|
// MustTimes requires parameter values to exist to bind to slice of time.Time variables. Returns error when values does not exist
|
||||||
func (b *ValueBinder) MustTimes(sourceParam string, dest *[]time.Time, layout string) *ValueBinder {
|
func (b *ValueBinder) MustTimes(sourceParam string, dest *[]time.Time, layout string) *ValueBinder {
|
||||||
return b.times(sourceParam, dest, layout, true)
|
return b.times(sourceParam, dest, layout, true)
|
||||||
}
|
}
|
||||||
|
|
@ -1084,7 +1161,7 @@ func (b *ValueBinder) Duration(sourceParam string, dest *time.Duration) *ValueBi
|
||||||
return b.duration(sourceParam, dest, false)
|
return b.duration(sourceParam, dest, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustDuration requires parameter value to exist to be bind to time.Duration variable. Returns error when value does not exist
|
// MustDuration requires parameter value to exist to bind to time.Duration variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustDuration(sourceParam string, dest *time.Duration) *ValueBinder {
|
func (b *ValueBinder) MustDuration(sourceParam string, dest *time.Duration) *ValueBinder {
|
||||||
return b.duration(sourceParam, dest, true)
|
return b.duration(sourceParam, dest, true)
|
||||||
}
|
}
|
||||||
|
|
@ -1115,7 +1192,7 @@ func (b *ValueBinder) Durations(sourceParam string, dest *[]time.Duration) *Valu
|
||||||
return b.durationsValue(sourceParam, dest, false)
|
return b.durationsValue(sourceParam, dest, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustDurations requires parameter values to exist to be bind to slice of time.Duration variables. Returns error when values does not exist
|
// MustDurations requires parameter values to exist to bind to slice of time.Duration variables. Returns error when values does not exist
|
||||||
func (b *ValueBinder) MustDurations(sourceParam string, dest *[]time.Duration) *ValueBinder {
|
func (b *ValueBinder) MustDurations(sourceParam string, dest *[]time.Duration) *ValueBinder {
|
||||||
return b.durationsValue(sourceParam, dest, true)
|
return b.durationsValue(sourceParam, dest, true)
|
||||||
}
|
}
|
||||||
|
|
@ -1161,10 +1238,10 @@ func (b *ValueBinder) durations(sourceParam string, values []string, dest *[]tim
|
||||||
// Note:
|
// Note:
|
||||||
// * time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal
|
// * time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal
|
||||||
func (b *ValueBinder) UnixTime(sourceParam string, dest *time.Time) *ValueBinder {
|
func (b *ValueBinder) UnixTime(sourceParam string, dest *time.Time) *ValueBinder {
|
||||||
return b.unixTime(sourceParam, dest, false, false)
|
return b.unixTime(sourceParam, dest, false, time.Second)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustUnixTime requires parameter value to exist to be bind to time.Duration variable (in local Time corresponding
|
// MustUnixTime requires parameter value to exist to bind to time.Duration variable (in local time corresponding
|
||||||
// to the given Unix time). Returns error when value does not exist.
|
// to the given Unix time). Returns error when value does not exist.
|
||||||
//
|
//
|
||||||
// Example: 1609180603 bind to 2020-12-28T18:36:43.000000000+00:00
|
// Example: 1609180603 bind to 2020-12-28T18:36:43.000000000+00:00
|
||||||
|
|
@ -1172,10 +1249,31 @@ func (b *ValueBinder) UnixTime(sourceParam string, dest *time.Time) *ValueBinder
|
||||||
// Note:
|
// Note:
|
||||||
// * time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal
|
// * time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal
|
||||||
func (b *ValueBinder) MustUnixTime(sourceParam string, dest *time.Time) *ValueBinder {
|
func (b *ValueBinder) MustUnixTime(sourceParam string, dest *time.Time) *ValueBinder {
|
||||||
return b.unixTime(sourceParam, dest, true, false)
|
return b.unixTime(sourceParam, dest, true, time.Second)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnixTimeNano binds parameter to time.Time variable (in local Time corresponding to the given Unix time in nano second precision).
|
// UnixTimeMilli binds parameter to time.Time variable (in local time corresponding to the given Unix time in millisecond precision).
|
||||||
|
//
|
||||||
|
// Example: 1647184410140 bind to 2022-03-13T15:13:30.140000000+00:00
|
||||||
|
//
|
||||||
|
// Note:
|
||||||
|
// * time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal
|
||||||
|
func (b *ValueBinder) UnixTimeMilli(sourceParam string, dest *time.Time) *ValueBinder {
|
||||||
|
return b.unixTime(sourceParam, dest, false, time.Millisecond)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MustUnixTimeMilli requires parameter value to exist to bind to time.Duration variable (in local time corresponding
|
||||||
|
// to the given Unix time in millisecond precision). Returns error when value does not exist.
|
||||||
|
//
|
||||||
|
// Example: 1647184410140 bind to 2022-03-13T15:13:30.140000000+00:00
|
||||||
|
//
|
||||||
|
// Note:
|
||||||
|
// * time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal
|
||||||
|
func (b *ValueBinder) MustUnixTimeMilli(sourceParam string, dest *time.Time) *ValueBinder {
|
||||||
|
return b.unixTime(sourceParam, dest, true, time.Millisecond)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnixTimeNano binds parameter to time.Time variable (in local time corresponding to the given Unix time in nanosecond precision).
|
||||||
//
|
//
|
||||||
// Example: 1609180603123456789 binds to 2020-12-28T18:36:43.123456789+00:00
|
// Example: 1609180603123456789 binds to 2020-12-28T18:36:43.123456789+00:00
|
||||||
// Example: 1000000000 binds to 1970-01-01T00:00:01.000000000+00:00
|
// Example: 1000000000 binds to 1970-01-01T00:00:01.000000000+00:00
|
||||||
|
|
@ -1185,10 +1283,10 @@ func (b *ValueBinder) MustUnixTime(sourceParam string, dest *time.Time) *ValueBi
|
||||||
// * time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal
|
// * time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal
|
||||||
// * Javascript's Number type only has about 53 bits of precision (Number.MAX_SAFE_INTEGER = 9007199254740991). Compare it to 1609180603123456789 in example.
|
// * Javascript's Number type only has about 53 bits of precision (Number.MAX_SAFE_INTEGER = 9007199254740991). Compare it to 1609180603123456789 in example.
|
||||||
func (b *ValueBinder) UnixTimeNano(sourceParam string, dest *time.Time) *ValueBinder {
|
func (b *ValueBinder) UnixTimeNano(sourceParam string, dest *time.Time) *ValueBinder {
|
||||||
return b.unixTime(sourceParam, dest, false, true)
|
return b.unixTime(sourceParam, dest, false, time.Nanosecond)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustUnixTimeNano requires parameter value to exist to be bind to time.Duration variable (in local Time corresponding
|
// MustUnixTimeNano requires parameter value to exist to bind to time.Duration variable (in local Time corresponding
|
||||||
// to the given Unix time value in nano second precision). Returns error when value does not exist.
|
// to the given Unix time value in nano second precision). Returns error when value does not exist.
|
||||||
//
|
//
|
||||||
// Example: 1609180603123456789 binds to 2020-12-28T18:36:43.123456789+00:00
|
// Example: 1609180603123456789 binds to 2020-12-28T18:36:43.123456789+00:00
|
||||||
|
|
@ -1199,10 +1297,10 @@ func (b *ValueBinder) UnixTimeNano(sourceParam string, dest *time.Time) *ValueBi
|
||||||
// * time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal
|
// * time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal
|
||||||
// * Javascript's Number type only has about 53 bits of precision (Number.MAX_SAFE_INTEGER = 9007199254740991). Compare it to 1609180603123456789 in example.
|
// * Javascript's Number type only has about 53 bits of precision (Number.MAX_SAFE_INTEGER = 9007199254740991). Compare it to 1609180603123456789 in example.
|
||||||
func (b *ValueBinder) MustUnixTimeNano(sourceParam string, dest *time.Time) *ValueBinder {
|
func (b *ValueBinder) MustUnixTimeNano(sourceParam string, dest *time.Time) *ValueBinder {
|
||||||
return b.unixTime(sourceParam, dest, true, true)
|
return b.unixTime(sourceParam, dest, true, time.Nanosecond)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *ValueBinder) unixTime(sourceParam string, dest *time.Time, valueMustExist bool, isNano bool) *ValueBinder {
|
func (b *ValueBinder) unixTime(sourceParam string, dest *time.Time, valueMustExist bool, precision time.Duration) *ValueBinder {
|
||||||
if b.failFast && b.errors != nil {
|
if b.failFast && b.errors != nil {
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
@ -1221,10 +1319,13 @@ func (b *ValueBinder) unixTime(sourceParam string, dest *time.Time, valueMustExi
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
if isNano {
|
switch precision {
|
||||||
*dest = time.Unix(0, n)
|
case time.Second:
|
||||||
} else {
|
|
||||||
*dest = time.Unix(n, 0)
|
*dest = time.Unix(n, 0)
|
||||||
|
case time.Millisecond:
|
||||||
|
*dest = time.Unix(n/1e3, (n%1e3)*1e6) // TODO: time.UnixMilli(n) exists since Go1.17 switch to that when min version allows
|
||||||
|
case time.Nanosecond:
|
||||||
|
*dest = time.Unix(0, n)
|
||||||
}
|
}
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
|
||||||
20
vendor/github.com/labstack/echo/v4/echo.go
generated
vendored
20
vendor/github.com/labstack/echo/v4/echo.go
generated
vendored
|
|
@ -183,6 +183,8 @@ const (
|
||||||
PROPFIND = "PROPFIND"
|
PROPFIND = "PROPFIND"
|
||||||
// REPORT Method can be used to get information about a resource, see rfc 3253
|
// REPORT Method can be used to get information about a resource, see rfc 3253
|
||||||
REPORT = "REPORT"
|
REPORT = "REPORT"
|
||||||
|
// RouteNotFound is special method type for routes handling "route not found" (404) cases
|
||||||
|
RouteNotFound = "echo_route_not_found"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Headers
|
// Headers
|
||||||
|
|
@ -246,7 +248,7 @@ const (
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// Version of Echo
|
// Version of Echo
|
||||||
Version = "4.7.2"
|
Version = "4.8.0"
|
||||||
website = "https://echo.labstack.com"
|
website = "https://echo.labstack.com"
|
||||||
// http://patorjk.com/software/taag/#p=display&f=Small%20Slant&t=Echo
|
// http://patorjk.com/software/taag/#p=display&f=Small%20Slant&t=Echo
|
||||||
banner = `
|
banner = `
|
||||||
|
|
@ -480,8 +482,21 @@ func (e *Echo) TRACE(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
|
||||||
return e.Add(http.MethodTrace, path, h, m...)
|
return e.Add(http.MethodTrace, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Any registers a new route for all HTTP methods and path with matching handler
|
// RouteNotFound registers a special-case route which is executed when no other route is found (i.e. HTTP 404 cases)
|
||||||
|
// for current request URL.
|
||||||
|
// Path supports static and named/any parameters just like other http method is defined. Generally path is ended with
|
||||||
|
// wildcard/match-any character (`/*`, `/download/*` etc).
|
||||||
|
//
|
||||||
|
// Example: `e.RouteNotFound("/*", func(c echo.Context) error { return c.NoContent(http.StatusNotFound) })`
|
||||||
|
func (e *Echo) RouteNotFound(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
|
||||||
|
return e.Add(RouteNotFound, path, h, m...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Any registers a new route for all HTTP methods (supported by Echo) and path with matching handler
|
||||||
// in the router with optional route-level middleware.
|
// in the router with optional route-level middleware.
|
||||||
|
//
|
||||||
|
// Note: this method only adds specific set of supported HTTP methods as handler and is not true
|
||||||
|
// "catch-any-arbitrary-method" way of matching requests.
|
||||||
func (e *Echo) Any(path string, handler HandlerFunc, middleware ...MiddlewareFunc) []*Route {
|
func (e *Echo) Any(path string, handler HandlerFunc, middleware ...MiddlewareFunc) []*Route {
|
||||||
routes := make([]*Route, len(methods))
|
routes := make([]*Route, len(methods))
|
||||||
for i, m := range methods {
|
for i, m := range methods {
|
||||||
|
|
@ -515,6 +530,7 @@ func (e *Echo) File(path, file string, m ...MiddlewareFunc) *Route {
|
||||||
func (e *Echo) add(host, method, path string, handler HandlerFunc, middleware ...MiddlewareFunc) *Route {
|
func (e *Echo) add(host, method, path string, handler HandlerFunc, middleware ...MiddlewareFunc) *Route {
|
||||||
name := handlerName(handler)
|
name := handlerName(handler)
|
||||||
router := e.findRouter(host)
|
router := e.findRouter(host)
|
||||||
|
// FIXME: when handler+middleware are both nil ... make it behave like handler removal
|
||||||
router.Add(method, path, func(c Context) error {
|
router.Add(method, path, func(c Context) error {
|
||||||
h := applyMiddleware(handler, middleware...)
|
h := applyMiddleware(handler, middleware...)
|
||||||
return h(c)
|
return h(c)
|
||||||
|
|
|
||||||
7
vendor/github.com/labstack/echo/v4/group.go
generated
vendored
7
vendor/github.com/labstack/echo/v4/group.go
generated
vendored
|
|
@ -107,6 +107,13 @@ func (g *Group) File(path, file string) {
|
||||||
g.file(path, file, g.GET)
|
g.file(path, file, g.GET)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RouteNotFound implements `Echo#RouteNotFound()` for sub-routes within the Group.
|
||||||
|
//
|
||||||
|
// Example: `g.RouteNotFound("/*", func(c echo.Context) error { return c.NoContent(http.StatusNotFound) })`
|
||||||
|
func (g *Group) RouteNotFound(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
|
||||||
|
return g.Add(RouteNotFound, path, h, m...)
|
||||||
|
}
|
||||||
|
|
||||||
// Add implements `Echo#Add()` for sub-routes within the Group.
|
// Add implements `Echo#Add()` for sub-routes within the Group.
|
||||||
func (g *Group) Add(method, path string, handler HandlerFunc, middleware ...MiddlewareFunc) *Route {
|
func (g *Group) Add(method, path string, handler HandlerFunc, middleware ...MiddlewareFunc) *Route {
|
||||||
// Combine into a new slice to avoid accidentally passing the same slice for
|
// Combine into a new slice to avoid accidentally passing the same slice for
|
||||||
|
|
|
||||||
6
vendor/github.com/labstack/echo/v4/middleware/basic_auth.go
generated
vendored
6
vendor/github.com/labstack/echo/v4/middleware/basic_auth.go
generated
vendored
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
|
|
@ -74,10 +75,13 @@ func BasicAuthWithConfig(config BasicAuthConfig) echo.MiddlewareFunc {
|
||||||
l := len(basic)
|
l := len(basic)
|
||||||
|
|
||||||
if len(auth) > l+1 && strings.EqualFold(auth[:l], basic) {
|
if len(auth) > l+1 && strings.EqualFold(auth[:l], basic) {
|
||||||
|
// Invalid base64 shouldn't be treated as error
|
||||||
|
// instead should be treated as invalid client input
|
||||||
b, err := base64.StdEncoding.DecodeString(auth[l+1:])
|
b, err := base64.StdEncoding.DecodeString(auth[l+1:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return echo.NewHTTPError(http.StatusBadRequest).SetInternal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cred := string(b)
|
cred := string(b)
|
||||||
for i := 0; i < len(cred); i++ {
|
for i := 0; i < len(cred); i++ {
|
||||||
if cred[i] == ':' {
|
if cred[i] == ':' {
|
||||||
|
|
|
||||||
8
vendor/github.com/labstack/echo/v4/middleware/logger.go
generated
vendored
8
vendor/github.com/labstack/echo/v4/middleware/logger.go
generated
vendored
|
|
@ -23,6 +23,8 @@ type (
|
||||||
// Tags to construct the logger format.
|
// Tags to construct the logger format.
|
||||||
//
|
//
|
||||||
// - time_unix
|
// - time_unix
|
||||||
|
// - time_unix_milli
|
||||||
|
// - time_unix_micro
|
||||||
// - time_unix_nano
|
// - time_unix_nano
|
||||||
// - time_rfc3339
|
// - time_rfc3339
|
||||||
// - time_rfc3339_nano
|
// - time_rfc3339_nano
|
||||||
|
|
@ -126,6 +128,12 @@ func LoggerWithConfig(config LoggerConfig) echo.MiddlewareFunc {
|
||||||
switch tag {
|
switch tag {
|
||||||
case "time_unix":
|
case "time_unix":
|
||||||
return buf.WriteString(strconv.FormatInt(time.Now().Unix(), 10))
|
return buf.WriteString(strconv.FormatInt(time.Now().Unix(), 10))
|
||||||
|
case "time_unix_milli":
|
||||||
|
// go 1.17 or later, it supports time#UnixMilli()
|
||||||
|
return buf.WriteString(strconv.FormatInt(time.Now().UnixNano()/1000000, 10))
|
||||||
|
case "time_unix_micro":
|
||||||
|
// go 1.17 or later, it supports time#UnixMicro()
|
||||||
|
return buf.WriteString(strconv.FormatInt(time.Now().UnixNano()/1000, 10))
|
||||||
case "time_unix_nano":
|
case "time_unix_nano":
|
||||||
return buf.WriteString(strconv.FormatInt(time.Now().UnixNano(), 10))
|
return buf.WriteString(strconv.FormatInt(time.Now().UnixNano(), 10))
|
||||||
case "time_rfc3339":
|
case "time_rfc3339":
|
||||||
|
|
|
||||||
6
vendor/github.com/labstack/echo/v4/middleware/request_logger.go
generated
vendored
6
vendor/github.com/labstack/echo/v4/middleware/request_logger.go
generated
vendored
|
|
@ -2,9 +2,10 @@ package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/labstack/echo/v4"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Example for `fmt.Printf`
|
// Example for `fmt.Printf`
|
||||||
|
|
@ -264,7 +265,8 @@ func (config RequestLoggerConfig) ToMiddleware() (echo.MiddlewareFunc, error) {
|
||||||
if config.LogStatus {
|
if config.LogStatus {
|
||||||
v.Status = res.Status
|
v.Status = res.Status
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if httpErr, ok := err.(*echo.HTTPError); ok {
|
var httpErr *echo.HTTPError
|
||||||
|
if errors.As(err, &httpErr) {
|
||||||
v.Status = httpErr.Code
|
v.Status = httpErr.Code
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
5
vendor/github.com/labstack/echo/v4/middleware/static.go
generated
vendored
5
vendor/github.com/labstack/echo/v4/middleware/static.go
generated
vendored
|
|
@ -1,6 +1,7 @@
|
||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"html/template"
|
"html/template"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
@ -196,8 +197,8 @@ func StaticWithConfig(config StaticConfig) echo.MiddlewareFunc {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
he, ok := err.(*echo.HTTPError)
|
var he *echo.HTTPError
|
||||||
if !(ok && config.HTML5 && he.Code == http.StatusNotFound) {
|
if !(errors.As(err, &he) && config.HTML5 && he.Code == http.StatusNotFound) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
323
vendor/github.com/labstack/echo/v4/router.go
generated
vendored
323
vendor/github.com/labstack/echo/v4/router.go
generated
vendored
|
|
@ -19,30 +19,39 @@ type (
|
||||||
prefix string
|
prefix string
|
||||||
parent *node
|
parent *node
|
||||||
staticChildren children
|
staticChildren children
|
||||||
ppath string
|
originalPath string
|
||||||
pnames []string
|
methods *routeMethods
|
||||||
methodHandler *methodHandler
|
|
||||||
paramChild *node
|
paramChild *node
|
||||||
anyChild *node
|
anyChild *node
|
||||||
|
paramsCount int
|
||||||
// isLeaf indicates that node does not have child routes
|
// isLeaf indicates that node does not have child routes
|
||||||
isLeaf bool
|
isLeaf bool
|
||||||
// isHandler indicates that node has at least one handler registered to it
|
// isHandler indicates that node has at least one handler registered to it
|
||||||
isHandler bool
|
isHandler bool
|
||||||
|
|
||||||
|
// notFoundHandler is handler registered with RouteNotFound method and is executed for 404 cases
|
||||||
|
notFoundHandler *routeMethod
|
||||||
}
|
}
|
||||||
kind uint8
|
kind uint8
|
||||||
children []*node
|
children []*node
|
||||||
methodHandler struct {
|
routeMethod struct {
|
||||||
connect HandlerFunc
|
ppath string
|
||||||
delete HandlerFunc
|
pnames []string
|
||||||
get HandlerFunc
|
handler HandlerFunc
|
||||||
head HandlerFunc
|
}
|
||||||
options HandlerFunc
|
routeMethods struct {
|
||||||
patch HandlerFunc
|
connect *routeMethod
|
||||||
post HandlerFunc
|
delete *routeMethod
|
||||||
propfind HandlerFunc
|
get *routeMethod
|
||||||
put HandlerFunc
|
head *routeMethod
|
||||||
trace HandlerFunc
|
options *routeMethod
|
||||||
report HandlerFunc
|
patch *routeMethod
|
||||||
|
post *routeMethod
|
||||||
|
propfind *routeMethod
|
||||||
|
put *routeMethod
|
||||||
|
trace *routeMethod
|
||||||
|
report *routeMethod
|
||||||
|
anyOther map[string]*routeMethod
|
||||||
allowHeader string
|
allowHeader string
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
@ -56,7 +65,7 @@ const (
|
||||||
anyLabel = byte('*')
|
anyLabel = byte('*')
|
||||||
)
|
)
|
||||||
|
|
||||||
func (m *methodHandler) isHandler() bool {
|
func (m *routeMethods) isHandler() bool {
|
||||||
return m.connect != nil ||
|
return m.connect != nil ||
|
||||||
m.delete != nil ||
|
m.delete != nil ||
|
||||||
m.get != nil ||
|
m.get != nil ||
|
||||||
|
|
@ -67,10 +76,12 @@ func (m *methodHandler) isHandler() bool {
|
||||||
m.propfind != nil ||
|
m.propfind != nil ||
|
||||||
m.put != nil ||
|
m.put != nil ||
|
||||||
m.trace != nil ||
|
m.trace != nil ||
|
||||||
m.report != nil
|
m.report != nil ||
|
||||||
|
len(m.anyOther) != 0
|
||||||
|
// RouteNotFound/404 is not considered as a handler
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *methodHandler) updateAllowHeader() {
|
func (m *routeMethods) updateAllowHeader() {
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
buf.WriteString(http.MethodOptions)
|
buf.WriteString(http.MethodOptions)
|
||||||
|
|
||||||
|
|
@ -112,6 +123,10 @@ func (m *methodHandler) updateAllowHeader() {
|
||||||
if m.report != nil {
|
if m.report != nil {
|
||||||
buf.WriteString(", REPORT")
|
buf.WriteString(", REPORT")
|
||||||
}
|
}
|
||||||
|
for method := range m.anyOther { // for simplicity, we use map and therefore order is not deterministic here
|
||||||
|
buf.WriteString(", ")
|
||||||
|
buf.WriteString(method)
|
||||||
|
}
|
||||||
m.allowHeader = buf.String()
|
m.allowHeader = buf.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -119,7 +134,7 @@ func (m *methodHandler) updateAllowHeader() {
|
||||||
func NewRouter(e *Echo) *Router {
|
func NewRouter(e *Echo) *Router {
|
||||||
return &Router{
|
return &Router{
|
||||||
tree: &node{
|
tree: &node{
|
||||||
methodHandler: new(methodHandler),
|
methods: new(routeMethods),
|
||||||
},
|
},
|
||||||
routes: map[string]*Route{},
|
routes: map[string]*Route{},
|
||||||
echo: e,
|
echo: e,
|
||||||
|
|
@ -153,7 +168,7 @@ func (r *Router) Add(method, path string, h HandlerFunc) {
|
||||||
}
|
}
|
||||||
j := i + 1
|
j := i + 1
|
||||||
|
|
||||||
r.insert(method, path[:i], nil, staticKind, "", nil)
|
r.insert(method, path[:i], staticKind, routeMethod{})
|
||||||
for ; i < lcpIndex && path[i] != '/'; i++ {
|
for ; i < lcpIndex && path[i] != '/'; i++ {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -163,23 +178,23 @@ func (r *Router) Add(method, path string, h HandlerFunc) {
|
||||||
|
|
||||||
if i == lcpIndex {
|
if i == lcpIndex {
|
||||||
// path node is last fragment of route path. ie. `/users/:id`
|
// path node is last fragment of route path. ie. `/users/:id`
|
||||||
r.insert(method, path[:i], h, paramKind, ppath, pnames)
|
r.insert(method, path[:i], paramKind, routeMethod{ppath, pnames, h})
|
||||||
} else {
|
} else {
|
||||||
r.insert(method, path[:i], nil, paramKind, "", nil)
|
r.insert(method, path[:i], paramKind, routeMethod{})
|
||||||
}
|
}
|
||||||
} else if path[i] == '*' {
|
} else if path[i] == '*' {
|
||||||
r.insert(method, path[:i], nil, staticKind, "", nil)
|
r.insert(method, path[:i], staticKind, routeMethod{})
|
||||||
pnames = append(pnames, "*")
|
pnames = append(pnames, "*")
|
||||||
r.insert(method, path[:i+1], h, anyKind, ppath, pnames)
|
r.insert(method, path[:i+1], anyKind, routeMethod{ppath, pnames, h})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r.insert(method, path, h, staticKind, ppath, pnames)
|
r.insert(method, path, staticKind, routeMethod{ppath, pnames, h})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Router) insert(method, path string, h HandlerFunc, t kind, ppath string, pnames []string) {
|
func (r *Router) insert(method, path string, t kind, rm routeMethod) {
|
||||||
// Adjust max param
|
// Adjust max param
|
||||||
paramLen := len(pnames)
|
paramLen := len(rm.pnames)
|
||||||
if *r.echo.maxParam < paramLen {
|
if *r.echo.maxParam < paramLen {
|
||||||
*r.echo.maxParam = paramLen
|
*r.echo.maxParam = paramLen
|
||||||
}
|
}
|
||||||
|
|
@ -207,25 +222,31 @@ func (r *Router) insert(method, path string, h HandlerFunc, t kind, ppath string
|
||||||
// At root node
|
// At root node
|
||||||
currentNode.label = search[0]
|
currentNode.label = search[0]
|
||||||
currentNode.prefix = search
|
currentNode.prefix = search
|
||||||
if h != nil {
|
if rm.handler != nil {
|
||||||
currentNode.kind = t
|
currentNode.kind = t
|
||||||
currentNode.addHandler(method, h)
|
currentNode.addMethod(method, &rm)
|
||||||
currentNode.ppath = ppath
|
currentNode.paramsCount = len(rm.pnames)
|
||||||
currentNode.pnames = pnames
|
currentNode.originalPath = rm.ppath
|
||||||
}
|
}
|
||||||
currentNode.isLeaf = currentNode.staticChildren == nil && currentNode.paramChild == nil && currentNode.anyChild == nil
|
currentNode.isLeaf = currentNode.staticChildren == nil && currentNode.paramChild == nil && currentNode.anyChild == nil
|
||||||
} else if lcpLen < prefixLen {
|
} else if lcpLen < prefixLen {
|
||||||
// Split node
|
// Split node into two before we insert new node.
|
||||||
|
// This happens when we are inserting path that is submatch of any existing inserted paths.
|
||||||
|
// For example, we have node `/test` and now are about to insert `/te/*`. In that case
|
||||||
|
// 1. overlapping part is `/te` that is used as parent node
|
||||||
|
// 2. `st` is part from existing node that is not matching - it gets its own node (child to `/te`)
|
||||||
|
// 3. `/*` is the new part we are about to insert (child to `/te`)
|
||||||
n := newNode(
|
n := newNode(
|
||||||
currentNode.kind,
|
currentNode.kind,
|
||||||
currentNode.prefix[lcpLen:],
|
currentNode.prefix[lcpLen:],
|
||||||
currentNode,
|
currentNode,
|
||||||
currentNode.staticChildren,
|
currentNode.staticChildren,
|
||||||
currentNode.methodHandler,
|
currentNode.originalPath,
|
||||||
currentNode.ppath,
|
currentNode.methods,
|
||||||
currentNode.pnames,
|
currentNode.paramsCount,
|
||||||
currentNode.paramChild,
|
currentNode.paramChild,
|
||||||
currentNode.anyChild,
|
currentNode.anyChild,
|
||||||
|
currentNode.notFoundHandler,
|
||||||
)
|
)
|
||||||
// Update parent path for all children to new node
|
// Update parent path for all children to new node
|
||||||
for _, child := range currentNode.staticChildren {
|
for _, child := range currentNode.staticChildren {
|
||||||
|
|
@ -243,13 +264,14 @@ func (r *Router) insert(method, path string, h HandlerFunc, t kind, ppath string
|
||||||
currentNode.label = currentNode.prefix[0]
|
currentNode.label = currentNode.prefix[0]
|
||||||
currentNode.prefix = currentNode.prefix[:lcpLen]
|
currentNode.prefix = currentNode.prefix[:lcpLen]
|
||||||
currentNode.staticChildren = nil
|
currentNode.staticChildren = nil
|
||||||
currentNode.methodHandler = new(methodHandler)
|
currentNode.originalPath = ""
|
||||||
currentNode.ppath = ""
|
currentNode.methods = new(routeMethods)
|
||||||
currentNode.pnames = nil
|
currentNode.paramsCount = 0
|
||||||
currentNode.paramChild = nil
|
currentNode.paramChild = nil
|
||||||
currentNode.anyChild = nil
|
currentNode.anyChild = nil
|
||||||
currentNode.isLeaf = false
|
currentNode.isLeaf = false
|
||||||
currentNode.isHandler = false
|
currentNode.isHandler = false
|
||||||
|
currentNode.notFoundHandler = nil
|
||||||
|
|
||||||
// Only Static children could reach here
|
// Only Static children could reach here
|
||||||
currentNode.addStaticChild(n)
|
currentNode.addStaticChild(n)
|
||||||
|
|
@ -257,13 +279,19 @@ func (r *Router) insert(method, path string, h HandlerFunc, t kind, ppath string
|
||||||
if lcpLen == searchLen {
|
if lcpLen == searchLen {
|
||||||
// At parent node
|
// At parent node
|
||||||
currentNode.kind = t
|
currentNode.kind = t
|
||||||
currentNode.addHandler(method, h)
|
if rm.handler != nil {
|
||||||
currentNode.ppath = ppath
|
currentNode.addMethod(method, &rm)
|
||||||
currentNode.pnames = pnames
|
currentNode.paramsCount = len(rm.pnames)
|
||||||
|
currentNode.originalPath = rm.ppath
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Create child node
|
// Create child node
|
||||||
n = newNode(t, search[lcpLen:], currentNode, nil, new(methodHandler), ppath, pnames, nil, nil)
|
n = newNode(t, search[lcpLen:], currentNode, nil, "", new(routeMethods), 0, nil, nil, nil)
|
||||||
n.addHandler(method, h)
|
if rm.handler != nil {
|
||||||
|
n.addMethod(method, &rm)
|
||||||
|
n.paramsCount = len(rm.pnames)
|
||||||
|
n.originalPath = rm.ppath
|
||||||
|
}
|
||||||
// Only Static children could reach here
|
// Only Static children could reach here
|
||||||
currentNode.addStaticChild(n)
|
currentNode.addStaticChild(n)
|
||||||
}
|
}
|
||||||
|
|
@ -277,8 +305,12 @@ func (r *Router) insert(method, path string, h HandlerFunc, t kind, ppath string
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// Create child node
|
// Create child node
|
||||||
n := newNode(t, search, currentNode, nil, new(methodHandler), ppath, pnames, nil, nil)
|
n := newNode(t, search, currentNode, nil, rm.ppath, new(routeMethods), 0, nil, nil, nil)
|
||||||
n.addHandler(method, h)
|
if rm.handler != nil {
|
||||||
|
n.addMethod(method, &rm)
|
||||||
|
n.paramsCount = len(rm.pnames)
|
||||||
|
}
|
||||||
|
|
||||||
switch t {
|
switch t {
|
||||||
case staticKind:
|
case staticKind:
|
||||||
currentNode.addStaticChild(n)
|
currentNode.addStaticChild(n)
|
||||||
|
|
@ -290,32 +322,42 @@ func (r *Router) insert(method, path string, h HandlerFunc, t kind, ppath string
|
||||||
currentNode.isLeaf = currentNode.staticChildren == nil && currentNode.paramChild == nil && currentNode.anyChild == nil
|
currentNode.isLeaf = currentNode.staticChildren == nil && currentNode.paramChild == nil && currentNode.anyChild == nil
|
||||||
} else {
|
} else {
|
||||||
// Node already exists
|
// Node already exists
|
||||||
if h != nil {
|
if rm.handler != nil {
|
||||||
currentNode.addHandler(method, h)
|
currentNode.addMethod(method, &rm)
|
||||||
currentNode.ppath = ppath
|
currentNode.paramsCount = len(rm.pnames)
|
||||||
if len(currentNode.pnames) == 0 { // Issue #729
|
currentNode.originalPath = rm.ppath
|
||||||
currentNode.pnames = pnames
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newNode(t kind, pre string, p *node, sc children, mh *methodHandler, ppath string, pnames []string, paramChildren, anyChildren *node) *node {
|
func newNode(
|
||||||
|
t kind,
|
||||||
|
pre string,
|
||||||
|
p *node,
|
||||||
|
sc children,
|
||||||
|
originalPath string,
|
||||||
|
methods *routeMethods,
|
||||||
|
paramsCount int,
|
||||||
|
paramChildren,
|
||||||
|
anyChildren *node,
|
||||||
|
notFoundHandler *routeMethod,
|
||||||
|
) *node {
|
||||||
return &node{
|
return &node{
|
||||||
kind: t,
|
kind: t,
|
||||||
label: pre[0],
|
label: pre[0],
|
||||||
prefix: pre,
|
prefix: pre,
|
||||||
parent: p,
|
parent: p,
|
||||||
staticChildren: sc,
|
staticChildren: sc,
|
||||||
ppath: ppath,
|
originalPath: originalPath,
|
||||||
pnames: pnames,
|
methods: methods,
|
||||||
methodHandler: mh,
|
paramsCount: paramsCount,
|
||||||
paramChild: paramChildren,
|
paramChild: paramChildren,
|
||||||
anyChild: anyChildren,
|
anyChild: anyChildren,
|
||||||
isLeaf: sc == nil && paramChildren == nil && anyChildren == nil,
|
isLeaf: sc == nil && paramChildren == nil && anyChildren == nil,
|
||||||
isHandler: mh.isHandler(),
|
isHandler: methods.isHandler(),
|
||||||
|
notFoundHandler: notFoundHandler,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -333,10 +375,8 @@ func (n *node) findStaticChild(l byte) *node {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *node) findChildWithLabel(l byte) *node {
|
func (n *node) findChildWithLabel(l byte) *node {
|
||||||
for _, c := range n.staticChildren {
|
if c := n.findStaticChild(l); c != nil {
|
||||||
if c.label == l {
|
return c
|
||||||
return c
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if l == paramLabel {
|
if l == paramLabel {
|
||||||
return n.paramChild
|
return n.paramChild
|
||||||
|
|
@ -347,66 +387,74 @@ func (n *node) findChildWithLabel(l byte) *node {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *node) addHandler(method string, h HandlerFunc) {
|
func (n *node) addMethod(method string, h *routeMethod) {
|
||||||
switch method {
|
switch method {
|
||||||
case http.MethodConnect:
|
case http.MethodConnect:
|
||||||
n.methodHandler.connect = h
|
n.methods.connect = h
|
||||||
case http.MethodDelete:
|
case http.MethodDelete:
|
||||||
n.methodHandler.delete = h
|
n.methods.delete = h
|
||||||
case http.MethodGet:
|
case http.MethodGet:
|
||||||
n.methodHandler.get = h
|
n.methods.get = h
|
||||||
case http.MethodHead:
|
case http.MethodHead:
|
||||||
n.methodHandler.head = h
|
n.methods.head = h
|
||||||
case http.MethodOptions:
|
case http.MethodOptions:
|
||||||
n.methodHandler.options = h
|
n.methods.options = h
|
||||||
case http.MethodPatch:
|
case http.MethodPatch:
|
||||||
n.methodHandler.patch = h
|
n.methods.patch = h
|
||||||
case http.MethodPost:
|
case http.MethodPost:
|
||||||
n.methodHandler.post = h
|
n.methods.post = h
|
||||||
case PROPFIND:
|
case PROPFIND:
|
||||||
n.methodHandler.propfind = h
|
n.methods.propfind = h
|
||||||
case http.MethodPut:
|
case http.MethodPut:
|
||||||
n.methodHandler.put = h
|
n.methods.put = h
|
||||||
case http.MethodTrace:
|
case http.MethodTrace:
|
||||||
n.methodHandler.trace = h
|
n.methods.trace = h
|
||||||
case REPORT:
|
case REPORT:
|
||||||
n.methodHandler.report = h
|
n.methods.report = h
|
||||||
|
case RouteNotFound:
|
||||||
|
n.notFoundHandler = h
|
||||||
|
return // RouteNotFound/404 is not considered as a handler so no further logic needs to be executed
|
||||||
|
default:
|
||||||
|
if n.methods.anyOther == nil {
|
||||||
|
n.methods.anyOther = make(map[string]*routeMethod)
|
||||||
|
}
|
||||||
|
if h.handler == nil {
|
||||||
|
delete(n.methods.anyOther, method)
|
||||||
|
} else {
|
||||||
|
n.methods.anyOther[method] = h
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
n.methodHandler.updateAllowHeader()
|
n.methods.updateAllowHeader()
|
||||||
if h != nil {
|
n.isHandler = true
|
||||||
n.isHandler = true
|
|
||||||
} else {
|
|
||||||
n.isHandler = n.methodHandler.isHandler()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *node) findHandler(method string) HandlerFunc {
|
func (n *node) findMethod(method string) *routeMethod {
|
||||||
switch method {
|
switch method {
|
||||||
case http.MethodConnect:
|
case http.MethodConnect:
|
||||||
return n.methodHandler.connect
|
return n.methods.connect
|
||||||
case http.MethodDelete:
|
case http.MethodDelete:
|
||||||
return n.methodHandler.delete
|
return n.methods.delete
|
||||||
case http.MethodGet:
|
case http.MethodGet:
|
||||||
return n.methodHandler.get
|
return n.methods.get
|
||||||
case http.MethodHead:
|
case http.MethodHead:
|
||||||
return n.methodHandler.head
|
return n.methods.head
|
||||||
case http.MethodOptions:
|
case http.MethodOptions:
|
||||||
return n.methodHandler.options
|
return n.methods.options
|
||||||
case http.MethodPatch:
|
case http.MethodPatch:
|
||||||
return n.methodHandler.patch
|
return n.methods.patch
|
||||||
case http.MethodPost:
|
case http.MethodPost:
|
||||||
return n.methodHandler.post
|
return n.methods.post
|
||||||
case PROPFIND:
|
case PROPFIND:
|
||||||
return n.methodHandler.propfind
|
return n.methods.propfind
|
||||||
case http.MethodPut:
|
case http.MethodPut:
|
||||||
return n.methodHandler.put
|
return n.methods.put
|
||||||
case http.MethodTrace:
|
case http.MethodTrace:
|
||||||
return n.methodHandler.trace
|
return n.methods.trace
|
||||||
case REPORT:
|
case REPORT:
|
||||||
return n.methodHandler.report
|
return n.methods.report
|
||||||
default:
|
default: // RouteNotFound/404 is not considered as a handler
|
||||||
return nil
|
return n.methods.anyOther[method]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -435,7 +483,7 @@ func (r *Router) Find(method, path string, c Context) {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
previousBestMatchNode *node
|
previousBestMatchNode *node
|
||||||
matchedHandler HandlerFunc
|
matchedRouteMethod *routeMethod
|
||||||
// search stores the remaining path to check for match. By each iteration we move from start of path to end of the path
|
// search stores the remaining path to check for match. By each iteration we move from start of path to end of the path
|
||||||
// and search value gets shorter and shorter.
|
// and search value gets shorter and shorter.
|
||||||
search = path
|
search = path
|
||||||
|
|
@ -508,7 +556,7 @@ func (r *Router) Find(method, path string, c Context) {
|
||||||
// No matching prefix, let's backtrack to the first possible alternative node of the decision path
|
// No matching prefix, let's backtrack to the first possible alternative node of the decision path
|
||||||
nk, ok := backtrackToNextNodeKind(staticKind)
|
nk, ok := backtrackToNextNodeKind(staticKind)
|
||||||
if !ok {
|
if !ok {
|
||||||
return // No other possibilities on the decision path
|
return // No other possibilities on the decision path, handler will be whatever context is reset to.
|
||||||
} else if nk == paramKind {
|
} else if nk == paramKind {
|
||||||
goto Param
|
goto Param
|
||||||
// NOTE: this case (backtracking from static node to previous any node) can not happen by current any matching logic. Any node is end of search currently
|
// NOTE: this case (backtracking from static node to previous any node) can not happen by current any matching logic. Any node is end of search currently
|
||||||
|
|
@ -524,15 +572,21 @@ func (r *Router) Find(method, path string, c Context) {
|
||||||
search = search[lcpLen:]
|
search = search[lcpLen:]
|
||||||
searchIndex = searchIndex + lcpLen
|
searchIndex = searchIndex + lcpLen
|
||||||
|
|
||||||
// Finish routing if no remaining search and we are on a node with handler and matching method type
|
// Finish routing if is no request path remaining to search
|
||||||
if search == "" && currentNode.isHandler {
|
if search == "" {
|
||||||
// check if current node has handler registered for http method we are looking for. we store currentNode as
|
// in case of node that is handler we have exact method type match or something for 405 to use
|
||||||
// best matching in case we do no find no more routes matching this path+method
|
if currentNode.isHandler {
|
||||||
if previousBestMatchNode == nil {
|
// check if current node has handler registered for http method we are looking for. we store currentNode as
|
||||||
previousBestMatchNode = currentNode
|
// best matching in case we do no find no more routes matching this path+method
|
||||||
}
|
if previousBestMatchNode == nil {
|
||||||
if h := currentNode.findHandler(method); h != nil {
|
previousBestMatchNode = currentNode
|
||||||
matchedHandler = h
|
}
|
||||||
|
if h := currentNode.findMethod(method); h != nil {
|
||||||
|
matchedRouteMethod = h
|
||||||
|
break
|
||||||
|
}
|
||||||
|
} else if currentNode.notFoundHandler != nil {
|
||||||
|
matchedRouteMethod = currentNode.notFoundHandler
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -552,7 +606,8 @@ func (r *Router) Find(method, path string, c Context) {
|
||||||
i := 0
|
i := 0
|
||||||
l := len(search)
|
l := len(search)
|
||||||
if currentNode.isLeaf {
|
if currentNode.isLeaf {
|
||||||
// when param node does not have any children then param node should act similarly to any node - consider all remaining search as match
|
// when param node does not have any children (path param is last piece of route path) then param node should
|
||||||
|
// act similarly to any node - consider all remaining search as match
|
||||||
i = l
|
i = l
|
||||||
} else {
|
} else {
|
||||||
for ; i < l && search[i] != '/'; i++ {
|
for ; i < l && search[i] != '/'; i++ {
|
||||||
|
|
@ -571,19 +626,23 @@ func (r *Router) Find(method, path string, c Context) {
|
||||||
if child := currentNode.anyChild; child != nil {
|
if child := currentNode.anyChild; child != nil {
|
||||||
// If any node is found, use remaining path for paramValues
|
// If any node is found, use remaining path for paramValues
|
||||||
currentNode = child
|
currentNode = child
|
||||||
paramValues[len(currentNode.pnames)-1] = search
|
paramValues[currentNode.paramsCount-1] = search
|
||||||
|
|
||||||
// update indexes/search in case we need to backtrack when no handler match is found
|
// update indexes/search in case we need to backtrack when no handler match is found
|
||||||
paramIndex++
|
paramIndex++
|
||||||
searchIndex += +len(search)
|
searchIndex += +len(search)
|
||||||
search = ""
|
search = ""
|
||||||
|
|
||||||
// check if current node has handler registered for http method we are looking for. we store currentNode as
|
if h := currentNode.findMethod(method); h != nil {
|
||||||
// best matching in case we do no find no more routes matching this path+method
|
matchedRouteMethod = h
|
||||||
|
break
|
||||||
|
}
|
||||||
|
// we store currentNode as best matching in case we do not find more routes matching this path+method. Needed for 405
|
||||||
if previousBestMatchNode == nil {
|
if previousBestMatchNode == nil {
|
||||||
previousBestMatchNode = currentNode
|
previousBestMatchNode = currentNode
|
||||||
}
|
}
|
||||||
if h := currentNode.findHandler(method); h != nil {
|
if currentNode.notFoundHandler != nil {
|
||||||
matchedHandler = h
|
matchedRouteMethod = currentNode.notFoundHandler
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -606,22 +665,34 @@ func (r *Router) Find(method, path string, c Context) {
|
||||||
return // nothing matched at all
|
return // nothing matched at all
|
||||||
}
|
}
|
||||||
|
|
||||||
if matchedHandler != nil {
|
// matchedHandler could be method+path handler that we matched or notFoundHandler from node with matching path
|
||||||
ctx.handler = matchedHandler
|
// user provided not found (404) handler has priority over generic method not found (405) handler or global 404 handler
|
||||||
|
var rPath string
|
||||||
|
var rPNames []string
|
||||||
|
if matchedRouteMethod != nil {
|
||||||
|
rPath = matchedRouteMethod.ppath
|
||||||
|
rPNames = matchedRouteMethod.pnames
|
||||||
|
ctx.handler = matchedRouteMethod.handler
|
||||||
} else {
|
} else {
|
||||||
// use previous match as basis. although we have no matching handler we have path match.
|
// use previous match as basis. although we have no matching handler we have path match.
|
||||||
// so we can send http.StatusMethodNotAllowed (405) instead of http.StatusNotFound (404)
|
// so we can send http.StatusMethodNotAllowed (405) instead of http.StatusNotFound (404)
|
||||||
currentNode = previousBestMatchNode
|
currentNode = previousBestMatchNode
|
||||||
|
|
||||||
|
rPath = currentNode.originalPath
|
||||||
|
rPNames = nil // no params here
|
||||||
ctx.handler = NotFoundHandler
|
ctx.handler = NotFoundHandler
|
||||||
if currentNode.isHandler {
|
if currentNode.notFoundHandler != nil {
|
||||||
ctx.Set(ContextKeyHeaderAllow, currentNode.methodHandler.allowHeader)
|
rPath = currentNode.notFoundHandler.ppath
|
||||||
|
rPNames = currentNode.notFoundHandler.pnames
|
||||||
|
ctx.handler = currentNode.notFoundHandler.handler
|
||||||
|
} else if currentNode.isHandler {
|
||||||
|
ctx.Set(ContextKeyHeaderAllow, currentNode.methods.allowHeader)
|
||||||
ctx.handler = MethodNotAllowedHandler
|
ctx.handler = MethodNotAllowedHandler
|
||||||
if method == http.MethodOptions {
|
if method == http.MethodOptions {
|
||||||
ctx.handler = optionsMethodHandler(currentNode.methodHandler.allowHeader)
|
ctx.handler = optionsMethodHandler(currentNode.methods.allowHeader)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctx.path = currentNode.ppath
|
ctx.path = rPath
|
||||||
ctx.pnames = currentNode.pnames
|
ctx.pnames = rPNames
|
||||||
}
|
}
|
||||||
|
|
|
||||||
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
|
|
@ -408,7 +408,7 @@ github.com/klauspost/pgzip
|
||||||
github.com/kolo/xmlrpc
|
github.com/kolo/xmlrpc
|
||||||
# github.com/kr/text v0.2.0
|
# github.com/kr/text v0.2.0
|
||||||
github.com/kr/text
|
github.com/kr/text
|
||||||
# github.com/labstack/echo/v4 v4.7.2
|
# github.com/labstack/echo/v4 v4.8.0
|
||||||
## explicit
|
## explicit
|
||||||
github.com/labstack/echo/v4
|
github.com/labstack/echo/v4
|
||||||
github.com/labstack/echo/v4/middleware
|
github.com/labstack/echo/v4/middleware
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue