build(deps): bump deps specifically CVE-2024-45338
This commit is contained in:
parent
bdc755f71b
commit
f41c764ca7
308 changed files with 72185 additions and 132790 deletions
54
vendor/github.com/labstack/echo/v4/CHANGELOG.md
generated
vendored
54
vendor/github.com/labstack/echo/v4/CHANGELOG.md
generated
vendored
|
|
@ -1,5 +1,59 @@
|
|||
# Changelog
|
||||
|
||||
## v4.13.3 - 2024-12-19
|
||||
|
||||
**Security**
|
||||
|
||||
* Update golang.org/x/net dependency [GO-2024-3333](https://pkg.go.dev/vuln/GO-2024-3333) in https://github.com/labstack/echo/pull/2722
|
||||
|
||||
|
||||
## v4.13.2 - 2024-12-12
|
||||
|
||||
**Security**
|
||||
|
||||
* Update dependencies (dependabot reports [GO-2024-3321](https://pkg.go.dev/vuln/GO-2024-3321)) in https://github.com/labstack/echo/pull/2721
|
||||
|
||||
|
||||
## v4.13.1 - 2024-12-11
|
||||
|
||||
**Fixes**
|
||||
|
||||
* Fix BindBody ignoring `Transfer-Encoding: chunked` requests by @178inaba in https://github.com/labstack/echo/pull/2717
|
||||
|
||||
|
||||
|
||||
## v4.13.0 - 2024-12-04
|
||||
|
||||
**BREAKING CHANGE** JWT Middleware Removed from Core use [labstack/echo-jwt](https://github.com/labstack/echo-jwt) instead
|
||||
|
||||
The JWT middleware has been **removed from Echo core** due to another security vulnerability, [CVE-2024-51744](https://nvd.nist.gov/vuln/detail/CVE-2024-51744). For more details, refer to issue [#2699](https://github.com/labstack/echo/issues/2699). A drop-in replacement is available in the [labstack/echo-jwt](https://github.com/labstack/echo-jwt) repository.
|
||||
|
||||
**Important**: Direct assignments like `token := c.Get("user").(*jwt.Token)` will now cause a panic due to an invalid cast. Update your code accordingly. Replace the current imports from `"github.com/golang-jwt/jwt"` in your handlers to the new middleware version using `"github.com/golang-jwt/jwt/v5"`.
|
||||
|
||||
|
||||
Background:
|
||||
|
||||
The version of `golang-jwt/jwt` (v3.2.2) previously used in Echo core has been in an unmaintained state for some time. This is not the first vulnerability affecting this library; earlier issues were addressed in [PR #1946](https://github.com/labstack/echo/pull/1946).
|
||||
JWT middleware was marked as deprecated in Echo core as of [v4.10.0](https://github.com/labstack/echo/releases/tag/v4.10.0) on 2022-12-27. If you did not notice that, consider leveraging tools like [Staticcheck](https://staticcheck.dev/) to catch such deprecations earlier in you dev/CI flow. For bonus points - check out [gosec](https://github.com/securego/gosec).
|
||||
|
||||
We sincerely apologize for any inconvenience caused by this change. While we strive to maintain backward compatibility within Echo core, recurring security issues with third-party dependencies have forced this decision.
|
||||
|
||||
**Enhancements**
|
||||
|
||||
* remove jwt middleware by @stevenwhitehead in https://github.com/labstack/echo/pull/2701
|
||||
* optimization: struct alignment by @behnambm in https://github.com/labstack/echo/pull/2636
|
||||
* bind: Maintain backwards compatibility for map[string]interface{} binding by @thesaltree in https://github.com/labstack/echo/pull/2656
|
||||
* Add Go 1.23 to CI by @aldas in https://github.com/labstack/echo/pull/2675
|
||||
* improve `MultipartForm` test by @martinyonatann in https://github.com/labstack/echo/pull/2682
|
||||
* `bind` : add support of multipart multi files by @martinyonatann in https://github.com/labstack/echo/pull/2684
|
||||
* Add TemplateRenderer struct to ease creating renderers for `html/template` and `text/template` packages. by @aldas in https://github.com/labstack/echo/pull/2690
|
||||
* Refactor TestBasicAuth to utilize table-driven test format by @ErikOlson in https://github.com/labstack/echo/pull/2688
|
||||
* Remove broken header by @aldas in https://github.com/labstack/echo/pull/2705
|
||||
* fix(bind body): content-length can be -1 by @phamvinhdat in https://github.com/labstack/echo/pull/2710
|
||||
* CORS middleware should compile allowOrigin regexp at creation by @aldas in https://github.com/labstack/echo/pull/2709
|
||||
* Shorten Github issue template and add test example by @aldas in https://github.com/labstack/echo/pull/2711
|
||||
|
||||
|
||||
## v4.12.0 - 2024-04-15
|
||||
|
||||
**Security**
|
||||
|
|
|
|||
4
vendor/github.com/labstack/echo/v4/Makefile
generated
vendored
4
vendor/github.com/labstack/echo/v4/Makefile
generated
vendored
|
|
@ -31,6 +31,6 @@ benchmark: ## Run benchmarks
|
|||
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}'
|
||||
|
||||
goversion ?= "1.19"
|
||||
test_version: ## Run tests inside Docker with given version (defaults to 1.19 oldest supported). Example: make test_version goversion=1.19
|
||||
goversion ?= "1.20"
|
||||
test_version: ## Run tests inside Docker with given version (defaults to 1.20 oldest supported). Example: make test_version goversion=1.20
|
||||
@docker run --rm -it -v $(shell pwd):/project golang:$(goversion) /bin/sh -c "cd /project && make init check"
|
||||
|
|
|
|||
7
vendor/github.com/labstack/echo/v4/README.md
generated
vendored
7
vendor/github.com/labstack/echo/v4/README.md
generated
vendored
|
|
@ -1,5 +1,3 @@
|
|||
<a href="https://echo.labstack.com"><img height="80" src="https://cdn.labstack.com/images/echo-logo.svg"></a>
|
||||
|
||||
[](https://sourcegraph.com/github.com/labstack/echo?badge)
|
||||
[](https://pkg.go.dev/github.com/labstack/echo/v4)
|
||||
[](https://goreportcard.com/report/github.com/labstack/echo)
|
||||
|
|
@ -77,6 +75,7 @@ package main
|
|||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/labstack/echo/v4/middleware"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
|
|
@ -92,7 +91,9 @@ func main() {
|
|||
e.GET("/", hello)
|
||||
|
||||
// Start server
|
||||
e.Logger.Fatal(e.Start(":1323"))
|
||||
if err := e.Start(":8080"); err != nil && !errors.Is(err, http.ErrServerClosed) {
|
||||
slog.Error("failed to start server", "error", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Handler
|
||||
|
|
|
|||
106
vendor/github.com/labstack/echo/v4/bind.go
generated
vendored
106
vendor/github.com/labstack/echo/v4/bind.go
generated
vendored
|
|
@ -8,6 +8,7 @@ import (
|
|||
"encoding/xml"
|
||||
"errors"
|
||||
"fmt"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strconv"
|
||||
|
|
@ -45,7 +46,7 @@ func (b *DefaultBinder) BindPathParams(c Context, i interface{}) error {
|
|||
for i, name := range names {
|
||||
params[name] = []string{values[i]}
|
||||
}
|
||||
if err := b.bindData(i, params, "param"); err != nil {
|
||||
if err := b.bindData(i, params, "param", nil); err != nil {
|
||||
return NewHTTPError(http.StatusBadRequest, err.Error()).SetInternal(err)
|
||||
}
|
||||
return nil
|
||||
|
|
@ -53,7 +54,7 @@ func (b *DefaultBinder) BindPathParams(c Context, i interface{}) error {
|
|||
|
||||
// BindQueryParams binds query params to bindable object
|
||||
func (b *DefaultBinder) BindQueryParams(c Context, i interface{}) error {
|
||||
if err := b.bindData(i, c.QueryParams(), "query"); err != nil {
|
||||
if err := b.bindData(i, c.QueryParams(), "query", nil); err != nil {
|
||||
return NewHTTPError(http.StatusBadRequest, err.Error()).SetInternal(err)
|
||||
}
|
||||
return nil
|
||||
|
|
@ -70,9 +71,12 @@ func (b *DefaultBinder) BindBody(c Context, i interface{}) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
ctype := req.Header.Get(HeaderContentType)
|
||||
switch {
|
||||
case strings.HasPrefix(ctype, MIMEApplicationJSON):
|
||||
// mediatype is found like `mime.ParseMediaType()` does it
|
||||
base, _, _ := strings.Cut(req.Header.Get(HeaderContentType), ";")
|
||||
mediatype := strings.TrimSpace(base)
|
||||
|
||||
switch mediatype {
|
||||
case MIMEApplicationJSON:
|
||||
if err = c.Echo().JSONSerializer.Deserialize(c, i); err != nil {
|
||||
switch err.(type) {
|
||||
case *HTTPError:
|
||||
|
|
@ -81,7 +85,7 @@ func (b *DefaultBinder) BindBody(c Context, i interface{}) (err error) {
|
|||
return NewHTTPError(http.StatusBadRequest, err.Error()).SetInternal(err)
|
||||
}
|
||||
}
|
||||
case strings.HasPrefix(ctype, MIMEApplicationXML), strings.HasPrefix(ctype, MIMETextXML):
|
||||
case MIMEApplicationXML, MIMETextXML:
|
||||
if err = xml.NewDecoder(req.Body).Decode(i); err != nil {
|
||||
if ute, ok := err.(*xml.UnsupportedTypeError); ok {
|
||||
return NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Unsupported type error: type=%v, error=%v", ute.Type, ute.Error())).SetInternal(err)
|
||||
|
|
@ -90,12 +94,20 @@ func (b *DefaultBinder) BindBody(c Context, i interface{}) (err error) {
|
|||
}
|
||||
return NewHTTPError(http.StatusBadRequest, err.Error()).SetInternal(err)
|
||||
}
|
||||
case strings.HasPrefix(ctype, MIMEApplicationForm), strings.HasPrefix(ctype, MIMEMultipartForm):
|
||||
case MIMEApplicationForm:
|
||||
params, err := c.FormParams()
|
||||
if err != nil {
|
||||
return NewHTTPError(http.StatusBadRequest, err.Error()).SetInternal(err)
|
||||
}
|
||||
if err = b.bindData(i, params, "form"); err != nil {
|
||||
if err = b.bindData(i, params, "form", nil); err != nil {
|
||||
return NewHTTPError(http.StatusBadRequest, err.Error()).SetInternal(err)
|
||||
}
|
||||
case MIMEMultipartForm:
|
||||
params, err := c.MultipartForm()
|
||||
if err != nil {
|
||||
return NewHTTPError(http.StatusBadRequest, err.Error()).SetInternal(err)
|
||||
}
|
||||
if err = b.bindData(i, params.Value, "form", params.File); err != nil {
|
||||
return NewHTTPError(http.StatusBadRequest, err.Error()).SetInternal(err)
|
||||
}
|
||||
default:
|
||||
|
|
@ -106,7 +118,7 @@ func (b *DefaultBinder) BindBody(c Context, i interface{}) (err error) {
|
|||
|
||||
// BindHeaders binds HTTP headers to a bindable object
|
||||
func (b *DefaultBinder) BindHeaders(c Context, i interface{}) error {
|
||||
if err := b.bindData(i, c.Request().Header, "header"); err != nil {
|
||||
if err := b.bindData(i, c.Request().Header, "header", nil); err != nil {
|
||||
return NewHTTPError(http.StatusBadRequest, err.Error()).SetInternal(err)
|
||||
}
|
||||
return nil
|
||||
|
|
@ -132,10 +144,11 @@ func (b *DefaultBinder) Bind(i interface{}, c Context) (err error) {
|
|||
}
|
||||
|
||||
// bindData will bind data ONLY fields in destination struct that have EXPLICIT tag
|
||||
func (b *DefaultBinder) bindData(destination interface{}, data map[string][]string, tag string) error {
|
||||
if destination == nil || len(data) == 0 {
|
||||
func (b *DefaultBinder) bindData(destination interface{}, data map[string][]string, tag string, dataFiles map[string][]*multipart.FileHeader) error {
|
||||
if destination == nil || (len(data) == 0 && len(dataFiles) == 0) {
|
||||
return nil
|
||||
}
|
||||
hasFiles := len(dataFiles) > 0
|
||||
typ := reflect.TypeOf(destination).Elem()
|
||||
val := reflect.ValueOf(destination).Elem()
|
||||
|
||||
|
|
@ -159,6 +172,10 @@ func (b *DefaultBinder) bindData(destination interface{}, data map[string][]stri
|
|||
for k, v := range data {
|
||||
if isElemString {
|
||||
val.SetMapIndex(reflect.ValueOf(k), reflect.ValueOf(v[0]))
|
||||
} else if isElemInterface {
|
||||
// To maintain backward compatibility, we always bind to the first string value
|
||||
// and not the slice of strings when dealing with map[string]interface{}{}
|
||||
val.SetMapIndex(reflect.ValueOf(k), reflect.ValueOf(v[0]))
|
||||
} else {
|
||||
val.SetMapIndex(reflect.ValueOf(k), reflect.ValueOf(v))
|
||||
}
|
||||
|
|
@ -175,7 +192,7 @@ func (b *DefaultBinder) bindData(destination interface{}, data map[string][]stri
|
|||
return errors.New("binding element must be a struct")
|
||||
}
|
||||
|
||||
for i := 0; i < typ.NumField(); i++ {
|
||||
for i := 0; i < typ.NumField(); i++ { // iterate over all destination fields
|
||||
typeField := typ.Field(i)
|
||||
structField := val.Field(i)
|
||||
if typeField.Anonymous {
|
||||
|
|
@ -194,10 +211,10 @@ func (b *DefaultBinder) bindData(destination interface{}, data map[string][]stri
|
|||
}
|
||||
|
||||
if inputFieldName == "" {
|
||||
// If tag is nil, we inspect if the field is a not BindUnmarshaler struct and try to bind data into it (might contains fields with tags).
|
||||
// If tag is nil, we inspect if the field is a not BindUnmarshaler struct and try to bind data into it (might contain fields with tags).
|
||||
// structs that implement BindUnmarshaler are bound only when they have explicit tag
|
||||
if _, ok := structField.Addr().Interface().(BindUnmarshaler); !ok && structFieldKind == reflect.Struct {
|
||||
if err := b.bindData(structField.Addr().Interface(), data, tag); err != nil {
|
||||
if err := b.bindData(structField.Addr().Interface(), data, tag, dataFiles); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
@ -205,10 +222,20 @@ func (b *DefaultBinder) bindData(destination interface{}, data map[string][]stri
|
|||
continue
|
||||
}
|
||||
|
||||
if hasFiles {
|
||||
if ok, err := isFieldMultipartFile(structField.Type()); err != nil {
|
||||
return err
|
||||
} else if ok {
|
||||
if ok := setMultipartFileHeaderTypes(structField, inputFieldName, dataFiles); ok {
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inputValue, exists := data[inputFieldName]
|
||||
if !exists {
|
||||
// Go json.Unmarshal supports case insensitive binding. However the
|
||||
// url params are bound case sensitive which is inconsistent. To
|
||||
// Go json.Unmarshal supports case-insensitive binding. However the
|
||||
// url params are bound case-sensitive which is inconsistent. To
|
||||
// fix this we must check all of the map values in a
|
||||
// case-insensitive search.
|
||||
for k, v := range data {
|
||||
|
|
@ -390,3 +417,50 @@ func setFloatField(value string, bitSize int, field reflect.Value) error {
|
|||
}
|
||||
return err
|
||||
}
|
||||
|
||||
var (
|
||||
// NOT supported by bind as you can NOT check easily empty struct being actual file or not
|
||||
multipartFileHeaderType = reflect.TypeOf(multipart.FileHeader{})
|
||||
// supported by bind as you can check by nil value if file existed or not
|
||||
multipartFileHeaderPointerType = reflect.TypeOf(&multipart.FileHeader{})
|
||||
multipartFileHeaderSliceType = reflect.TypeOf([]multipart.FileHeader(nil))
|
||||
multipartFileHeaderPointerSliceType = reflect.TypeOf([]*multipart.FileHeader(nil))
|
||||
)
|
||||
|
||||
func isFieldMultipartFile(field reflect.Type) (bool, error) {
|
||||
switch field {
|
||||
case multipartFileHeaderPointerType,
|
||||
multipartFileHeaderSliceType,
|
||||
multipartFileHeaderPointerSliceType:
|
||||
return true, nil
|
||||
case multipartFileHeaderType:
|
||||
return true, errors.New("binding to multipart.FileHeader struct is not supported, use pointer to struct")
|
||||
default:
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
|
||||
func setMultipartFileHeaderTypes(structField reflect.Value, inputFieldName string, files map[string][]*multipart.FileHeader) bool {
|
||||
fileHeaders := files[inputFieldName]
|
||||
if len(fileHeaders) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
result := true
|
||||
switch structField.Type() {
|
||||
case multipartFileHeaderPointerSliceType:
|
||||
structField.Set(reflect.ValueOf(fileHeaders))
|
||||
case multipartFileHeaderSliceType:
|
||||
headers := make([]multipart.FileHeader, len(fileHeaders))
|
||||
for i, fileHeader := range fileHeaders {
|
||||
headers[i] = *fileHeader
|
||||
}
|
||||
structField.Set(reflect.ValueOf(headers))
|
||||
case multipartFileHeaderPointerType:
|
||||
structField.Set(reflect.ValueOf(fileHeaders[0]))
|
||||
default:
|
||||
result = false
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
|
|
|||
9
vendor/github.com/labstack/echo/v4/binder.go
generated
vendored
9
vendor/github.com/labstack/echo/v4/binder.go
generated
vendored
|
|
@ -69,9 +69,9 @@ import (
|
|||
type BindingError struct {
|
||||
// Field is the field name where value binding failed
|
||||
Field string `json:"field"`
|
||||
*HTTPError
|
||||
// Values of parameter that failed to bind.
|
||||
Values []string `json:"-"`
|
||||
*HTTPError
|
||||
}
|
||||
|
||||
// NewBindingError creates new instance of binding error
|
||||
|
|
@ -94,16 +94,15 @@ func (be *BindingError) Error() string {
|
|||
|
||||
// ValueBinder provides utility methods for binding query or path parameter to various Go built-in types
|
||||
type ValueBinder struct {
|
||||
// failFast is flag for binding methods to return without attempting to bind when previous binding already failed
|
||||
failFast bool
|
||||
errors []error
|
||||
|
||||
// ValueFunc is used to get single parameter (first) value from request
|
||||
ValueFunc func(sourceParam string) string
|
||||
// ValuesFunc is used to get all values for parameter from request. i.e. `/api/search?ids=1&ids=2`
|
||||
ValuesFunc func(sourceParam string) []string
|
||||
// ErrorFunc is used to create errors. Allows you to use your own error type, that for example marshals to your specific json response
|
||||
ErrorFunc func(sourceParam string, values []string, message interface{}, internalError error) error
|
||||
errors []error
|
||||
// failFast is flag for binding methods to return without attempting to bind when previous binding already failed
|
||||
failFast bool
|
||||
}
|
||||
|
||||
// QueryParamsBinder creates query parameter value binder
|
||||
|
|
|
|||
10
vendor/github.com/labstack/echo/v4/context.go
generated
vendored
10
vendor/github.com/labstack/echo/v4/context.go
generated
vendored
|
|
@ -200,31 +200,31 @@ type Context interface {
|
|||
}
|
||||
|
||||
type context struct {
|
||||
logger Logger
|
||||
request *http.Request
|
||||
response *Response
|
||||
query url.Values
|
||||
echo *Echo
|
||||
logger Logger
|
||||
|
||||
store Map
|
||||
lock sync.RWMutex
|
||||
|
||||
// following fields are set by Router
|
||||
handler HandlerFunc
|
||||
|
||||
// path is route path that Router matched. It is empty string where there is no route match.
|
||||
// Route registered with RouteNotFound is considered as a match and path therefore is not empty.
|
||||
path string
|
||||
|
||||
// pnames length is tied to param count for the matched route
|
||||
pnames []string
|
||||
|
||||
// Usually echo.Echo is sizing pvalues but there could be user created middlewares that decide to
|
||||
// overwrite parameter by calling SetParamNames + SetParamValues.
|
||||
// When echo.Echo allocated that slice it length/capacity is tied to echo.Echo.maxParam value.
|
||||
//
|
||||
// It is important that pvalues size is always equal or bigger to pnames length.
|
||||
pvalues []string
|
||||
handler HandlerFunc
|
||||
|
||||
// pnames length is tied to param count for the matched route
|
||||
pnames []string
|
||||
}
|
||||
|
||||
const (
|
||||
|
|
|
|||
20
vendor/github.com/labstack/echo/v4/echo.go
generated
vendored
20
vendor/github.com/labstack/echo/v4/echo.go
generated
vendored
|
|
@ -45,7 +45,6 @@ import (
|
|||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
stdLog "log"
|
||||
"net"
|
||||
"net/http"
|
||||
|
|
@ -91,10 +90,6 @@ type Echo struct {
|
|||
Listener net.Listener
|
||||
TLSListener net.Listener
|
||||
AutoTLSManager autocert.Manager
|
||||
DisableHTTP2 bool
|
||||
Debug bool
|
||||
HideBanner bool
|
||||
HidePort bool
|
||||
HTTPErrorHandler HTTPErrorHandler
|
||||
Binder Binder
|
||||
JSONSerializer JSONSerializer
|
||||
|
|
@ -106,6 +101,10 @@ type Echo struct {
|
|||
|
||||
// OnAddRouteHandler is called when Echo adds new route to specific host router.
|
||||
OnAddRouteHandler func(host string, route Route, handler HandlerFunc, middleware []MiddlewareFunc)
|
||||
DisableHTTP2 bool
|
||||
Debug bool
|
||||
HideBanner bool
|
||||
HidePort bool
|
||||
}
|
||||
|
||||
// Route contains a handler and information for matching against requests.
|
||||
|
|
@ -117,9 +116,9 @@ type Route struct {
|
|||
|
||||
// HTTPError represents an error that occurred while handling a request.
|
||||
type HTTPError struct {
|
||||
Code int `json:"-"`
|
||||
Message interface{} `json:"message"`
|
||||
Internal error `json:"-"` // Stores the error returned by an external dependency
|
||||
Message interface{} `json:"message"`
|
||||
Code int `json:"-"`
|
||||
}
|
||||
|
||||
// MiddlewareFunc defines a function to process middleware.
|
||||
|
|
@ -142,11 +141,6 @@ type JSONSerializer interface {
|
|||
Deserialize(c Context, i interface{}) error
|
||||
}
|
||||
|
||||
// Renderer is the interface that wraps the Render function.
|
||||
type Renderer interface {
|
||||
Render(io.Writer, string, interface{}, Context) error
|
||||
}
|
||||
|
||||
// Map defines a generic map of type `map[string]interface{}`.
|
||||
type Map map[string]interface{}
|
||||
|
||||
|
|
@ -265,7 +259,7 @@ const (
|
|||
|
||||
const (
|
||||
// Version of Echo
|
||||
Version = "4.12.0"
|
||||
Version = "4.13.3"
|
||||
website = "https://echo.labstack.com"
|
||||
// http://patorjk.com/software/taag/#p=display&f=Small%20Slant&t=Echo
|
||||
banner = `
|
||||
|
|
|
|||
2
vendor/github.com/labstack/echo/v4/echo_fs.go
generated
vendored
2
vendor/github.com/labstack/echo/v4/echo_fs.go
generated
vendored
|
|
@ -102,8 +102,8 @@ func StaticFileHandler(file string, filesystem fs.FS) HandlerFunc {
|
|||
// traverse up from current executable run path.
|
||||
// NB: private because you really should use fs.FS implementation instances
|
||||
type defaultFS struct {
|
||||
prefix string
|
||||
fs fs.FS
|
||||
prefix string
|
||||
}
|
||||
|
||||
func newDefaultFS() *defaultFS {
|
||||
|
|
|
|||
2
vendor/github.com/labstack/echo/v4/group.go
generated
vendored
2
vendor/github.com/labstack/echo/v4/group.go
generated
vendored
|
|
@ -14,8 +14,8 @@ type Group struct {
|
|||
common
|
||||
host string
|
||||
prefix string
|
||||
middleware []MiddlewareFunc
|
||||
echo *Echo
|
||||
middleware []MiddlewareFunc
|
||||
}
|
||||
|
||||
// Use implements `Echo#Use()` for sub-routes within the Group.
|
||||
|
|
|
|||
2
vendor/github.com/labstack/echo/v4/ip.go
generated
vendored
2
vendor/github.com/labstack/echo/v4/ip.go
generated
vendored
|
|
@ -134,10 +134,10 @@ Private IPv6 address ranges:
|
|||
*/
|
||||
|
||||
type ipChecker struct {
|
||||
trustExtraRanges []*net.IPNet
|
||||
trustLoopback bool
|
||||
trustLinkLocal bool
|
||||
trustPrivateNet bool
|
||||
trustExtraRanges []*net.IPNet
|
||||
}
|
||||
|
||||
// TrustOption is config for which IP address to trust
|
||||
|
|
|
|||
4
vendor/github.com/labstack/echo/v4/middleware/body_dump.go
generated
vendored
4
vendor/github.com/labstack/echo/v4/middleware/body_dump.go
generated
vendored
|
|
@ -98,14 +98,14 @@ func (w *bodyDumpResponseWriter) Write(b []byte) (int, error) {
|
|||
}
|
||||
|
||||
func (w *bodyDumpResponseWriter) Flush() {
|
||||
err := responseControllerFlush(w.ResponseWriter)
|
||||
err := http.NewResponseController(w.ResponseWriter).Flush()
|
||||
if err != nil && errors.Is(err, http.ErrNotSupported) {
|
||||
panic(errors.New("response writer flushing is not supported"))
|
||||
}
|
||||
}
|
||||
|
||||
func (w *bodyDumpResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
||||
return responseControllerHijack(w.ResponseWriter)
|
||||
return http.NewResponseController(w.ResponseWriter).Hijack()
|
||||
}
|
||||
|
||||
func (w *bodyDumpResponseWriter) Unwrap() http.ResponseWriter {
|
||||
|
|
|
|||
4
vendor/github.com/labstack/echo/v4/middleware/compress.go
generated
vendored
4
vendor/github.com/labstack/echo/v4/middleware/compress.go
generated
vendored
|
|
@ -190,7 +190,7 @@ func (w *gzipResponseWriter) Flush() {
|
|||
}
|
||||
|
||||
w.Writer.(*gzip.Writer).Flush()
|
||||
_ = responseControllerFlush(w.ResponseWriter)
|
||||
_ = http.NewResponseController(w.ResponseWriter).Flush()
|
||||
}
|
||||
|
||||
func (w *gzipResponseWriter) Unwrap() http.ResponseWriter {
|
||||
|
|
@ -198,7 +198,7 @@ func (w *gzipResponseWriter) Unwrap() http.ResponseWriter {
|
|||
}
|
||||
|
||||
func (w *gzipResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
||||
return responseControllerHijack(w.ResponseWriter)
|
||||
return http.NewResponseController(w.ResponseWriter).Hijack()
|
||||
}
|
||||
|
||||
func (w *gzipResponseWriter) Push(target string, opts *http.PushOptions) error {
|
||||
|
|
|
|||
18
vendor/github.com/labstack/echo/v4/middleware/cors.go
generated
vendored
18
vendor/github.com/labstack/echo/v4/middleware/cors.go
generated
vendored
|
|
@ -147,13 +147,25 @@ func CORSWithConfig(config CORSConfig) echo.MiddlewareFunc {
|
|||
config.AllowMethods = DefaultCORSConfig.AllowMethods
|
||||
}
|
||||
|
||||
allowOriginPatterns := []string{}
|
||||
allowOriginPatterns := make([]*regexp.Regexp, 0, len(config.AllowOrigins))
|
||||
for _, origin := range config.AllowOrigins {
|
||||
if origin == "*" {
|
||||
continue // "*" is handled differently and does not need regexp
|
||||
}
|
||||
pattern := regexp.QuoteMeta(origin)
|
||||
pattern = strings.ReplaceAll(pattern, "\\*", ".*")
|
||||
pattern = strings.ReplaceAll(pattern, "\\?", ".")
|
||||
pattern = "^" + pattern + "$"
|
||||
allowOriginPatterns = append(allowOriginPatterns, pattern)
|
||||
|
||||
re, err := regexp.Compile(pattern)
|
||||
if err != nil {
|
||||
// this is to preserve previous behaviour - invalid patterns were just ignored.
|
||||
// If we would turn this to panic, users with invalid patterns
|
||||
// would have applications crashing in production due unrecovered panic.
|
||||
// TODO: this should be turned to error/panic in `v5`
|
||||
continue
|
||||
}
|
||||
allowOriginPatterns = append(allowOriginPatterns, re)
|
||||
}
|
||||
|
||||
allowMethods := strings.Join(config.AllowMethods, ",")
|
||||
|
|
@ -239,7 +251,7 @@ func CORSWithConfig(config CORSConfig) echo.MiddlewareFunc {
|
|||
}
|
||||
if checkPatterns {
|
||||
for _, re := range allowOriginPatterns {
|
||||
if match, _ := regexp.MatchString(re, origin); match {
|
||||
if match := re.MatchString(origin); match {
|
||||
allowOrigin = origin
|
||||
break
|
||||
}
|
||||
|
|
|
|||
303
vendor/github.com/labstack/echo/v4/middleware/jwt.go
generated
vendored
303
vendor/github.com/labstack/echo/v4/middleware/jwt.go
generated
vendored
|
|
@ -1,303 +0,0 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
||||
|
||||
//go:build go1.15
|
||||
// +build go1.15
|
||||
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/golang-jwt/jwt"
|
||||
"github.com/labstack/echo/v4"
|
||||
"net/http"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// JWTConfig defines the config for JWT middleware.
|
||||
type JWTConfig struct {
|
||||
// Skipper defines a function to skip middleware.
|
||||
Skipper Skipper
|
||||
|
||||
// BeforeFunc defines a function which is executed just before the middleware.
|
||||
BeforeFunc BeforeFunc
|
||||
|
||||
// SuccessHandler defines a function which is executed for a valid token before middleware chain continues with next
|
||||
// middleware or handler.
|
||||
SuccessHandler JWTSuccessHandler
|
||||
|
||||
// ErrorHandler defines a function which is executed for an invalid token.
|
||||
// It may be used to define a custom JWT error.
|
||||
ErrorHandler JWTErrorHandler
|
||||
|
||||
// ErrorHandlerWithContext is almost identical to ErrorHandler, but it's passed the current context.
|
||||
ErrorHandlerWithContext JWTErrorHandlerWithContext
|
||||
|
||||
// ContinueOnIgnoredError allows the next middleware/handler to be called when ErrorHandlerWithContext decides to
|
||||
// ignore the error (by returning `nil`).
|
||||
// This is useful when parts of your site/api allow public access and some authorized routes provide extra functionality.
|
||||
// In that case you can use ErrorHandlerWithContext to set a default public JWT token value in the request context
|
||||
// and continue. Some logic down the remaining execution chain needs to check that (public) token value then.
|
||||
ContinueOnIgnoredError bool
|
||||
|
||||
// Signing key to validate token.
|
||||
// This is one of the three options to provide a token validation key.
|
||||
// The order of precedence is a user-defined KeyFunc, SigningKeys and SigningKey.
|
||||
// Required if neither user-defined KeyFunc nor SigningKeys is provided.
|
||||
SigningKey interface{}
|
||||
|
||||
// Map of signing keys to validate token with kid field usage.
|
||||
// This is one of the three options to provide a token validation key.
|
||||
// The order of precedence is a user-defined KeyFunc, SigningKeys and SigningKey.
|
||||
// Required if neither user-defined KeyFunc nor SigningKey is provided.
|
||||
SigningKeys map[string]interface{}
|
||||
|
||||
// Signing method used to check the token's signing algorithm.
|
||||
// Optional. Default value HS256.
|
||||
SigningMethod string
|
||||
|
||||
// Context key to store user information from the token into context.
|
||||
// Optional. Default value "user".
|
||||
ContextKey string
|
||||
|
||||
// Claims are extendable claims data defining token content. Used by default ParseTokenFunc implementation.
|
||||
// Not used if custom ParseTokenFunc is set.
|
||||
// Optional. Default value jwt.MapClaims
|
||||
Claims jwt.Claims
|
||||
|
||||
// TokenLookup is a string in the form of "<source>:<name>" or "<source>:<name>,<source>:<name>" that is used
|
||||
// to extract token from the request.
|
||||
// Optional. Default value "header:Authorization".
|
||||
// Possible values:
|
||||
// - "header:<name>" or "header:<name>:<cut-prefix>"
|
||||
// `<cut-prefix>` is argument value to cut/trim prefix of the extracted value. This is useful if header
|
||||
// value has static prefix like `Authorization: <auth-scheme> <authorisation-parameters>` where part that we
|
||||
// want to cut is `<auth-scheme> ` note the space at the end.
|
||||
// In case of JWT tokens `Authorization: Bearer <token>` prefix we cut is `Bearer `.
|
||||
// If prefix is left empty the whole value is returned.
|
||||
// - "query:<name>"
|
||||
// - "param:<name>"
|
||||
// - "cookie:<name>"
|
||||
// - "form:<name>"
|
||||
// Multiple sources example:
|
||||
// - "header:Authorization,cookie:myowncookie"
|
||||
TokenLookup string
|
||||
|
||||
// TokenLookupFuncs defines a list of user-defined functions that extract JWT token from the given context.
|
||||
// This is one of the two options to provide a token extractor.
|
||||
// The order of precedence is user-defined TokenLookupFuncs, and TokenLookup.
|
||||
// You can also provide both if you want.
|
||||
TokenLookupFuncs []ValuesExtractor
|
||||
|
||||
// AuthScheme to be used in the Authorization header.
|
||||
// Optional. Default value "Bearer".
|
||||
AuthScheme string
|
||||
|
||||
// KeyFunc defines a user-defined function that supplies the public key for a token validation.
|
||||
// The function shall take care of verifying the signing algorithm and selecting the proper key.
|
||||
// A user-defined KeyFunc can be useful if tokens are issued by an external party.
|
||||
// Used by default ParseTokenFunc implementation.
|
||||
//
|
||||
// When a user-defined KeyFunc is provided, SigningKey, SigningKeys, and SigningMethod are ignored.
|
||||
// This is one of the three options to provide a token validation key.
|
||||
// The order of precedence is a user-defined KeyFunc, SigningKeys and SigningKey.
|
||||
// Required if neither SigningKeys nor SigningKey is provided.
|
||||
// Not used if custom ParseTokenFunc is set.
|
||||
// Default to an internal implementation verifying the signing algorithm and selecting the proper key.
|
||||
KeyFunc jwt.Keyfunc
|
||||
|
||||
// ParseTokenFunc defines a user-defined function that parses token from given auth. Returns an error when token
|
||||
// parsing fails or parsed token is invalid.
|
||||
// Defaults to implementation using `github.com/golang-jwt/jwt` as JWT implementation library
|
||||
ParseTokenFunc func(auth string, c echo.Context) (interface{}, error)
|
||||
}
|
||||
|
||||
// JWTSuccessHandler defines a function which is executed for a valid token.
|
||||
type JWTSuccessHandler func(c echo.Context)
|
||||
|
||||
// JWTErrorHandler defines a function which is executed for an invalid token.
|
||||
type JWTErrorHandler func(err error) error
|
||||
|
||||
// JWTErrorHandlerWithContext is almost identical to JWTErrorHandler, but it's passed the current context.
|
||||
type JWTErrorHandlerWithContext func(err error, c echo.Context) error
|
||||
|
||||
// Algorithms
|
||||
const (
|
||||
AlgorithmHS256 = "HS256"
|
||||
)
|
||||
|
||||
// ErrJWTMissing is error that is returned when no JWToken was extracted from the request.
|
||||
var ErrJWTMissing = echo.NewHTTPError(http.StatusBadRequest, "missing or malformed jwt")
|
||||
|
||||
// ErrJWTInvalid is error that is returned when middleware could not parse JWT correctly.
|
||||
var ErrJWTInvalid = echo.NewHTTPError(http.StatusUnauthorized, "invalid or expired jwt")
|
||||
|
||||
// DefaultJWTConfig is the default JWT auth middleware config.
|
||||
var DefaultJWTConfig = JWTConfig{
|
||||
Skipper: DefaultSkipper,
|
||||
SigningMethod: AlgorithmHS256,
|
||||
ContextKey: "user",
|
||||
TokenLookup: "header:" + echo.HeaderAuthorization,
|
||||
TokenLookupFuncs: nil,
|
||||
AuthScheme: "Bearer",
|
||||
Claims: jwt.MapClaims{},
|
||||
KeyFunc: nil,
|
||||
}
|
||||
|
||||
// JWT returns a JSON Web Token (JWT) auth middleware.
|
||||
//
|
||||
// For valid token, it sets the user in context and calls next handler.
|
||||
// For invalid token, it returns "401 - Unauthorized" error.
|
||||
// For missing token, it returns "400 - Bad Request" error.
|
||||
//
|
||||
// See: https://jwt.io/introduction
|
||||
// See `JWTConfig.TokenLookup`
|
||||
//
|
||||
// Deprecated: Please use https://github.com/labstack/echo-jwt instead
|
||||
func JWT(key interface{}) echo.MiddlewareFunc {
|
||||
c := DefaultJWTConfig
|
||||
c.SigningKey = key
|
||||
return JWTWithConfig(c)
|
||||
}
|
||||
|
||||
// JWTWithConfig returns a JWT auth middleware with config.
|
||||
// See: `JWT()`.
|
||||
//
|
||||
// Deprecated: Please use https://github.com/labstack/echo-jwt instead
|
||||
func JWTWithConfig(config JWTConfig) echo.MiddlewareFunc {
|
||||
// Defaults
|
||||
if config.Skipper == nil {
|
||||
config.Skipper = DefaultJWTConfig.Skipper
|
||||
}
|
||||
if config.SigningKey == nil && len(config.SigningKeys) == 0 && config.KeyFunc == nil && config.ParseTokenFunc == nil {
|
||||
panic("echo: jwt middleware requires signing key")
|
||||
}
|
||||
if config.SigningMethod == "" {
|
||||
config.SigningMethod = DefaultJWTConfig.SigningMethod
|
||||
}
|
||||
if config.ContextKey == "" {
|
||||
config.ContextKey = DefaultJWTConfig.ContextKey
|
||||
}
|
||||
if config.Claims == nil {
|
||||
config.Claims = DefaultJWTConfig.Claims
|
||||
}
|
||||
if config.TokenLookup == "" && len(config.TokenLookupFuncs) == 0 {
|
||||
config.TokenLookup = DefaultJWTConfig.TokenLookup
|
||||
}
|
||||
if config.AuthScheme == "" {
|
||||
config.AuthScheme = DefaultJWTConfig.AuthScheme
|
||||
}
|
||||
if config.KeyFunc == nil {
|
||||
config.KeyFunc = config.defaultKeyFunc
|
||||
}
|
||||
if config.ParseTokenFunc == nil {
|
||||
config.ParseTokenFunc = config.defaultParseToken
|
||||
}
|
||||
|
||||
extractors, cErr := createExtractors(config.TokenLookup, config.AuthScheme)
|
||||
if cErr != nil {
|
||||
panic(cErr)
|
||||
}
|
||||
if len(config.TokenLookupFuncs) > 0 {
|
||||
extractors = append(config.TokenLookupFuncs, extractors...)
|
||||
}
|
||||
|
||||
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
if config.Skipper(c) {
|
||||
return next(c)
|
||||
}
|
||||
|
||||
if config.BeforeFunc != nil {
|
||||
config.BeforeFunc(c)
|
||||
}
|
||||
|
||||
var lastExtractorErr error
|
||||
var lastTokenErr error
|
||||
for _, extractor := range extractors {
|
||||
auths, err := extractor(c)
|
||||
if err != nil {
|
||||
lastExtractorErr = ErrJWTMissing // backwards compatibility: all extraction errors are same (unlike KeyAuth)
|
||||
continue
|
||||
}
|
||||
for _, auth := range auths {
|
||||
token, err := config.ParseTokenFunc(auth, c)
|
||||
if err != nil {
|
||||
lastTokenErr = err
|
||||
continue
|
||||
}
|
||||
// Store user information from token into context.
|
||||
c.Set(config.ContextKey, token)
|
||||
if config.SuccessHandler != nil {
|
||||
config.SuccessHandler(c)
|
||||
}
|
||||
return next(c)
|
||||
}
|
||||
}
|
||||
// we are here only when we did not successfully extract or parse any of the tokens
|
||||
err := lastTokenErr
|
||||
if err == nil { // prioritize token errors over extracting errors
|
||||
err = lastExtractorErr
|
||||
}
|
||||
if config.ErrorHandler != nil {
|
||||
return config.ErrorHandler(err)
|
||||
}
|
||||
if config.ErrorHandlerWithContext != nil {
|
||||
tmpErr := config.ErrorHandlerWithContext(err, c)
|
||||
if config.ContinueOnIgnoredError && tmpErr == nil {
|
||||
return next(c)
|
||||
}
|
||||
return tmpErr
|
||||
}
|
||||
|
||||
// backwards compatible errors codes
|
||||
if lastTokenErr != nil {
|
||||
return &echo.HTTPError{
|
||||
Code: ErrJWTInvalid.Code,
|
||||
Message: ErrJWTInvalid.Message,
|
||||
Internal: err,
|
||||
}
|
||||
}
|
||||
return err // this is lastExtractorErr value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (config *JWTConfig) defaultParseToken(auth string, c echo.Context) (interface{}, error) {
|
||||
var token *jwt.Token
|
||||
var err error
|
||||
// Issue #647, #656
|
||||
if _, ok := config.Claims.(jwt.MapClaims); ok {
|
||||
token, err = jwt.Parse(auth, config.KeyFunc)
|
||||
} else {
|
||||
t := reflect.ValueOf(config.Claims).Type().Elem()
|
||||
claims := reflect.New(t).Interface().(jwt.Claims)
|
||||
token, err = jwt.ParseWithClaims(auth, claims, config.KeyFunc)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !token.Valid {
|
||||
return nil, errors.New("invalid token")
|
||||
}
|
||||
return token, nil
|
||||
}
|
||||
|
||||
// defaultKeyFunc returns a signing key of the given token.
|
||||
func (config *JWTConfig) defaultKeyFunc(t *jwt.Token) (interface{}, error) {
|
||||
// Check the signing method
|
||||
if t.Method.Alg() != config.SigningMethod {
|
||||
return nil, fmt.Errorf("unexpected jwt signing method=%v", t.Header["alg"])
|
||||
}
|
||||
if len(config.SigningKeys) > 0 {
|
||||
if kid, ok := t.Header["kid"].(string); ok {
|
||||
if key, ok := config.SigningKeys[kid]; ok {
|
||||
return key, nil
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("unexpected jwt key id=%v", t.Header["kid"])
|
||||
}
|
||||
|
||||
return config.SigningKey, nil
|
||||
}
|
||||
44
vendor/github.com/labstack/echo/v4/middleware/responsecontroller_1.19.go
generated
vendored
44
vendor/github.com/labstack/echo/v4/middleware/responsecontroller_1.19.go
generated
vendored
|
|
@ -1,44 +0,0 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
||||
|
||||
//go:build !go1.20
|
||||
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// TODO: remove when Go 1.23 is released and we do not support 1.19 anymore
|
||||
func responseControllerFlush(rw http.ResponseWriter) error {
|
||||
for {
|
||||
switch t := rw.(type) {
|
||||
case interface{ FlushError() error }:
|
||||
return t.FlushError()
|
||||
case http.Flusher:
|
||||
t.Flush()
|
||||
return nil
|
||||
case interface{ Unwrap() http.ResponseWriter }:
|
||||
rw = t.Unwrap()
|
||||
default:
|
||||
return fmt.Errorf("%w", http.ErrNotSupported)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: remove when Go 1.23 is released and we do not support 1.19 anymore
|
||||
func responseControllerHijack(rw http.ResponseWriter) (net.Conn, *bufio.ReadWriter, error) {
|
||||
for {
|
||||
switch t := rw.(type) {
|
||||
case http.Hijacker:
|
||||
return t.Hijack()
|
||||
case interface{ Unwrap() http.ResponseWriter }:
|
||||
rw = t.Unwrap()
|
||||
default:
|
||||
return nil, nil, fmt.Errorf("%w", http.ErrNotSupported)
|
||||
}
|
||||
}
|
||||
}
|
||||
20
vendor/github.com/labstack/echo/v4/middleware/responsecontroller_1.20.go
generated
vendored
20
vendor/github.com/labstack/echo/v4/middleware/responsecontroller_1.20.go
generated
vendored
|
|
@ -1,20 +0,0 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
||||
|
||||
//go:build go1.20
|
||||
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"net"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func responseControllerFlush(rw http.ResponseWriter) error {
|
||||
return http.NewResponseController(rw).Flush()
|
||||
}
|
||||
|
||||
func responseControllerHijack(rw http.ResponseWriter) (net.Conn, *bufio.ReadWriter, error) {
|
||||
return http.NewResponseController(rw).Hijack()
|
||||
}
|
||||
29
vendor/github.com/labstack/echo/v4/renderer.go
generated
vendored
Normal file
29
vendor/github.com/labstack/echo/v4/renderer.go
generated
vendored
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
package echo
|
||||
|
||||
import "io"
|
||||
|
||||
// Renderer is the interface that wraps the Render function.
|
||||
type Renderer interface {
|
||||
Render(io.Writer, string, interface{}, Context) error
|
||||
}
|
||||
|
||||
// TemplateRenderer is helper to ease creating renderers for `html/template` and `text/template` packages.
|
||||
// Example usage:
|
||||
//
|
||||
// e.Renderer = &echo.TemplateRenderer{
|
||||
// Template: template.Must(template.ParseGlob("templates/*.html")),
|
||||
// }
|
||||
//
|
||||
// e.Renderer = &echo.TemplateRenderer{
|
||||
// Template: template.Must(template.New("hello").Parse("Hello, {{.}}!")),
|
||||
// }
|
||||
type TemplateRenderer struct {
|
||||
Template interface {
|
||||
ExecuteTemplate(wr io.Writer, name string, data any) error
|
||||
}
|
||||
}
|
||||
|
||||
// Render renders the template with given data.
|
||||
func (t *TemplateRenderer) Render(w io.Writer, name string, data interface{}, c Context) error {
|
||||
return t.Template.ExecuteTemplate(w, name, data)
|
||||
}
|
||||
6
vendor/github.com/labstack/echo/v4/response.go
generated
vendored
6
vendor/github.com/labstack/echo/v4/response.go
generated
vendored
|
|
@ -14,10 +14,10 @@ import (
|
|||
// by an HTTP handler to construct an HTTP response.
|
||||
// See: https://golang.org/pkg/net/http/#ResponseWriter
|
||||
type Response struct {
|
||||
Writer http.ResponseWriter
|
||||
echo *Echo
|
||||
beforeFuncs []func()
|
||||
afterFuncs []func()
|
||||
Writer http.ResponseWriter
|
||||
Status int
|
||||
Size int64
|
||||
Committed bool
|
||||
|
|
@ -86,7 +86,7 @@ func (r *Response) Write(b []byte) (n int, err error) {
|
|||
// buffered data to the client.
|
||||
// See [http.Flusher](https://golang.org/pkg/net/http/#Flusher)
|
||||
func (r *Response) Flush() {
|
||||
err := responseControllerFlush(r.Writer)
|
||||
err := http.NewResponseController(r.Writer).Flush()
|
||||
if err != nil && errors.Is(err, http.ErrNotSupported) {
|
||||
panic(errors.New("response writer flushing is not supported"))
|
||||
}
|
||||
|
|
@ -96,7 +96,7 @@ func (r *Response) Flush() {
|
|||
// take over the connection.
|
||||
// See [http.Hijacker](https://golang.org/pkg/net/http/#Hijacker)
|
||||
func (r *Response) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
||||
return responseControllerHijack(r.Writer)
|
||||
return http.NewResponseController(r.Writer).Hijack()
|
||||
}
|
||||
|
||||
// Unwrap returns the original http.ResponseWriter.
|
||||
|
|
|
|||
44
vendor/github.com/labstack/echo/v4/responsecontroller_1.19.go
generated
vendored
44
vendor/github.com/labstack/echo/v4/responsecontroller_1.19.go
generated
vendored
|
|
@ -1,44 +0,0 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
||||
|
||||
//go:build !go1.20
|
||||
|
||||
package echo
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// TODO: remove when Go 1.23 is released and we do not support 1.19 anymore
|
||||
func responseControllerFlush(rw http.ResponseWriter) error {
|
||||
for {
|
||||
switch t := rw.(type) {
|
||||
case interface{ FlushError() error }:
|
||||
return t.FlushError()
|
||||
case http.Flusher:
|
||||
t.Flush()
|
||||
return nil
|
||||
case interface{ Unwrap() http.ResponseWriter }:
|
||||
rw = t.Unwrap()
|
||||
default:
|
||||
return fmt.Errorf("%w", http.ErrNotSupported)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: remove when Go 1.23 is released and we do not support 1.19 anymore
|
||||
func responseControllerHijack(rw http.ResponseWriter) (net.Conn, *bufio.ReadWriter, error) {
|
||||
for {
|
||||
switch t := rw.(type) {
|
||||
case http.Hijacker:
|
||||
return t.Hijack()
|
||||
case interface{ Unwrap() http.ResponseWriter }:
|
||||
rw = t.Unwrap()
|
||||
default:
|
||||
return nil, nil, fmt.Errorf("%w", http.ErrNotSupported)
|
||||
}
|
||||
}
|
||||
}
|
||||
20
vendor/github.com/labstack/echo/v4/responsecontroller_1.20.go
generated
vendored
20
vendor/github.com/labstack/echo/v4/responsecontroller_1.20.go
generated
vendored
|
|
@ -1,20 +0,0 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
||||
|
||||
//go:build go1.20
|
||||
|
||||
package echo
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"net"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func responseControllerFlush(rw http.ResponseWriter) error {
|
||||
return http.NewResponseController(rw).Flush()
|
||||
}
|
||||
|
||||
func responseControllerHijack(rw http.ResponseWriter) (net.Conn, *bufio.ReadWriter, error) {
|
||||
return http.NewResponseController(rw).Hijack()
|
||||
}
|
||||
33
vendor/github.com/labstack/echo/v4/router.go
generated
vendored
33
vendor/github.com/labstack/echo/v4/router.go
generated
vendored
|
|
@ -18,32 +18,31 @@ type Router struct {
|
|||
}
|
||||
|
||||
type node struct {
|
||||
kind kind
|
||||
label byte
|
||||
prefix string
|
||||
parent *node
|
||||
staticChildren children
|
||||
originalPath string
|
||||
methods *routeMethods
|
||||
paramChild *node
|
||||
anyChild *node
|
||||
paramsCount int
|
||||
methods *routeMethods
|
||||
parent *node
|
||||
paramChild *node
|
||||
anyChild *node
|
||||
// notFoundHandler is handler registered with RouteNotFound method and is executed for 404 cases
|
||||
notFoundHandler *routeMethod
|
||||
prefix string
|
||||
originalPath string
|
||||
staticChildren children
|
||||
paramsCount int
|
||||
label byte
|
||||
kind kind
|
||||
// isLeaf indicates that node does not have child routes
|
||||
isLeaf bool
|
||||
// isHandler indicates that node has at least one handler registered to it
|
||||
isHandler bool
|
||||
|
||||
// notFoundHandler is handler registered with RouteNotFound method and is executed for 404 cases
|
||||
notFoundHandler *routeMethod
|
||||
}
|
||||
|
||||
type kind uint8
|
||||
type children []*node
|
||||
|
||||
type routeMethod struct {
|
||||
handler HandlerFunc
|
||||
ppath string
|
||||
pnames []string
|
||||
handler HandlerFunc
|
||||
}
|
||||
|
||||
type routeMethods struct {
|
||||
|
|
@ -242,18 +241,18 @@ func (r *Router) insert(method, path string, h HandlerFunc) {
|
|||
|
||||
if i == lcpIndex {
|
||||
// path node is last fragment of route path. ie. `/users/:id`
|
||||
r.insertNode(method, path[:i], paramKind, routeMethod{ppath, pnames, h})
|
||||
r.insertNode(method, path[:i], paramKind, routeMethod{ppath: ppath, pnames: pnames, handler: h})
|
||||
} else {
|
||||
r.insertNode(method, path[:i], paramKind, routeMethod{})
|
||||
}
|
||||
} else if path[i] == '*' {
|
||||
r.insertNode(method, path[:i], staticKind, routeMethod{})
|
||||
pnames = append(pnames, "*")
|
||||
r.insertNode(method, path[:i+1], anyKind, routeMethod{ppath, pnames, h})
|
||||
r.insertNode(method, path[:i+1], anyKind, routeMethod{ppath: ppath, pnames: pnames, handler: h})
|
||||
}
|
||||
}
|
||||
|
||||
r.insertNode(method, path, staticKind, routeMethod{ppath, pnames, h})
|
||||
r.insertNode(method, path, staticKind, routeMethod{ppath: ppath, pnames: pnames, handler: h})
|
||||
}
|
||||
|
||||
func (r *Router) insertNode(method, path string, t kind, rm routeMethod) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue