mirror of
https://github.com/documize/community.git
synced 2025-07-25 16:19:46 +02:00
Bump version to 5.11.0
This commit is contained in:
parent
a32510b8e6
commit
510e1bd0bd
370 changed files with 18825 additions and 5454 deletions
47
vendor/github.com/gorilla/css/LICENSE
generated
vendored
47
vendor/github.com/gorilla/css/LICENSE
generated
vendored
|
@ -1,27 +1,28 @@
|
|||
Copyright (c) 2013, Gorilla web toolkit
|
||||
All rights reserved.
|
||||
Copyright (c) 2023 The Gorilla Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Neither the name of the {organization} nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
|
6
vendor/github.com/gorilla/css/scanner/scanner.go
generated
vendored
6
vendor/github.com/gorilla/css/scanner/scanner.go
generated
vendored
|
@ -191,7 +191,11 @@ func init() {
|
|||
// New returns a new CSS scanner for the given input.
|
||||
func New(input string) *Scanner {
|
||||
// Normalize newlines.
|
||||
// https://www.w3.org/TR/css-syntax-3/#input-preprocessing
|
||||
input = strings.Replace(input, "\r\n", "\n", -1)
|
||||
input = strings.Replace(input, "\r", "\n", -1)
|
||||
input = strings.Replace(input, "\f", "\n", -1)
|
||||
input = strings.Replace(input, "\u0000", "\ufffd", -1)
|
||||
return &Scanner{
|
||||
input: input,
|
||||
row: 1,
|
||||
|
@ -232,7 +236,7 @@ func (s *Scanner) Next() *Token {
|
|||
// shortcut before testing multiple regexps.
|
||||
input := s.input[s.pos:]
|
||||
switch input[0] {
|
||||
case '\t', '\n', '\f', '\r', ' ':
|
||||
case '\t', '\n', ' ':
|
||||
// Whitespace.
|
||||
return s.emitToken(TokenS, matchers[TokenS].FindString(input))
|
||||
case '.':
|
||||
|
|
20
vendor/github.com/gorilla/handlers/.editorconfig
generated
vendored
Normal file
20
vendor/github.com/gorilla/handlers/.editorconfig
generated
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
; https://editorconfig.org/
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
insert_final_newline = true
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[{Makefile,go.mod,go.sum,*.go,.gitmodules}]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
|
||||
[*.md]
|
||||
indent_size = 4
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
eclint_indent_style = unset
|
2
vendor/github.com/gorilla/handlers/.gitignore
generated
vendored
Normal file
2
vendor/github.com/gorilla/handlers/.gitignore
generated
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
# Output of the go test coverage tool
|
||||
coverage.coverprofile
|
39
vendor/github.com/gorilla/handlers/LICENSE
generated
vendored
39
vendor/github.com/gorilla/handlers/LICENSE
generated
vendored
|
@ -1,22 +1,27 @@
|
|||
Copyright (c) 2013 The Gorilla Handlers Authors. All rights reserved.
|
||||
Copyright (c) 2023 The Gorilla Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
|
34
vendor/github.com/gorilla/handlers/Makefile
generated
vendored
Normal file
34
vendor/github.com/gorilla/handlers/Makefile
generated
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
GO_LINT=$(shell which golangci-lint 2> /dev/null || echo '')
|
||||
GO_LINT_URI=github.com/golangci/golangci-lint/cmd/golangci-lint@latest
|
||||
|
||||
GO_SEC=$(shell which gosec 2> /dev/null || echo '')
|
||||
GO_SEC_URI=github.com/securego/gosec/v2/cmd/gosec@latest
|
||||
|
||||
GO_VULNCHECK=$(shell which govulncheck 2> /dev/null || echo '')
|
||||
GO_VULNCHECK_URI=golang.org/x/vuln/cmd/govulncheck@latest
|
||||
|
||||
.PHONY: verify
|
||||
verify: sec govulncheck lint test
|
||||
|
||||
.PHONY: lint
|
||||
lint:
|
||||
$(if $(GO_LINT), ,go install $(GO_LINT_URI))
|
||||
@echo "##### Running golangci-lint #####"
|
||||
golangci-lint run -v
|
||||
|
||||
.PHONY: sec
|
||||
sec:
|
||||
$(if $(GO_SEC), ,go install $(GO_SEC_URI))
|
||||
@echo "##### Running gosec #####"
|
||||
gosec ./...
|
||||
|
||||
.PHONY: govulncheck
|
||||
govulncheck:
|
||||
$(if $(GO_VULNCHECK), ,go install $(GO_VULNCHECK_URI))
|
||||
@echo "##### Running govulncheck #####"
|
||||
govulncheck ./...
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
@echo "##### Running tests #####"
|
||||
go test -race -cover -coverprofile=coverage.coverprofile -covermode=atomic -v ./...
|
10
vendor/github.com/gorilla/handlers/README.md
generated
vendored
10
vendor/github.com/gorilla/handlers/README.md
generated
vendored
|
@ -1,9 +1,9 @@
|
|||
gorilla/handlers
|
||||
================
|
||||
[](https://godoc.org/github.com/gorilla/handlers)
|
||||
[](https://circleci.com/gh/gorilla/handlers)
|
||||
[](https://sourcegraph.com/github.com/gorilla/handlers?badge)
|
||||
# gorilla/handlers
|
||||
|
||||

|
||||
[](https://codecov.io/github/gorilla/handlers)
|
||||
[](https://godoc.org/github.com/gorilla/handlers)
|
||||
[](https://sourcegraph.com/github.com/gorilla/handlers?badge)
|
||||
|
||||
Package handlers is a collection of handlers (aka "HTTP middleware") for use
|
||||
with Go's `net/http` package (or any framework supporting `http.Handler`), including:
|
||||
|
|
9
vendor/github.com/gorilla/handlers/canonical.go
generated
vendored
9
vendor/github.com/gorilla/handlers/canonical.go
generated
vendored
|
@ -21,12 +21,11 @@ type canonical struct {
|
|||
//
|
||||
// Example:
|
||||
//
|
||||
// r := mux.NewRouter()
|
||||
// canonical := handlers.CanonicalHost("http://www.gorillatoolkit.org", 302)
|
||||
// r.HandleFunc("/route", YourHandler)
|
||||
//
|
||||
// log.Fatal(http.ListenAndServe(":7000", canonical(r)))
|
||||
// r := mux.NewRouter()
|
||||
// canonical := handlers.CanonicalHost("http://www.gorillatoolkit.org", 302)
|
||||
// r.HandleFunc("/route", YourHandler)
|
||||
//
|
||||
// log.Fatal(http.ListenAndServe(":7000", canonical(r)))
|
||||
func CanonicalHost(domain string, code int) func(h http.Handler) http.Handler {
|
||||
fn := func(h http.Handler) http.Handler {
|
||||
return canonical{h, domain, code}
|
||||
|
|
167
vendor/github.com/gorilla/handlers/compress.go
generated
vendored
167
vendor/github.com/gorilla/handlers/compress.go
generated
vendored
|
@ -10,47 +10,48 @@ import (
|
|||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/felixge/httpsnoop"
|
||||
)
|
||||
|
||||
const acceptEncoding string = "Accept-Encoding"
|
||||
|
||||
type compressResponseWriter struct {
|
||||
io.Writer
|
||||
http.ResponseWriter
|
||||
http.Hijacker
|
||||
http.Flusher
|
||||
http.CloseNotifier
|
||||
compressor io.Writer
|
||||
w http.ResponseWriter
|
||||
}
|
||||
|
||||
func (w *compressResponseWriter) WriteHeader(c int) {
|
||||
w.ResponseWriter.Header().Del("Content-Length")
|
||||
w.ResponseWriter.WriteHeader(c)
|
||||
func (cw *compressResponseWriter) WriteHeader(c int) {
|
||||
cw.w.Header().Del("Content-Length")
|
||||
cw.w.WriteHeader(c)
|
||||
}
|
||||
|
||||
func (w *compressResponseWriter) Header() http.Header {
|
||||
return w.ResponseWriter.Header()
|
||||
}
|
||||
|
||||
func (w *compressResponseWriter) Write(b []byte) (int, error) {
|
||||
h := w.ResponseWriter.Header()
|
||||
func (cw *compressResponseWriter) Write(b []byte) (int, error) {
|
||||
h := cw.w.Header()
|
||||
if h.Get("Content-Type") == "" {
|
||||
h.Set("Content-Type", http.DetectContentType(b))
|
||||
}
|
||||
h.Del("Content-Length")
|
||||
|
||||
return w.Writer.Write(b)
|
||||
return cw.compressor.Write(b)
|
||||
}
|
||||
|
||||
func (cw *compressResponseWriter) ReadFrom(r io.Reader) (int64, error) {
|
||||
return io.Copy(cw.compressor, r)
|
||||
}
|
||||
|
||||
type flusher interface {
|
||||
Flush() error
|
||||
}
|
||||
|
||||
func (w *compressResponseWriter) Flush() {
|
||||
func (cw *compressResponseWriter) Flush() {
|
||||
// Flush compressed data if compressor supports it.
|
||||
if f, ok := w.Writer.(flusher); ok {
|
||||
f.Flush()
|
||||
if f, ok := cw.compressor.(flusher); ok {
|
||||
_ = f.Flush()
|
||||
}
|
||||
// Flush HTTP response.
|
||||
if w.Flusher != nil {
|
||||
w.Flusher.Flush()
|
||||
if f, ok := cw.w.(http.Flusher); ok {
|
||||
f.Flush()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,77 +75,69 @@ func CompressHandlerLevel(h http.Handler, level int) http.Handler {
|
|||
level = gzip.DefaultCompression
|
||||
}
|
||||
|
||||
const (
|
||||
gzipEncoding = "gzip"
|
||||
flateEncoding = "deflate"
|
||||
)
|
||||
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
L:
|
||||
for _, enc := range strings.Split(r.Header.Get("Accept-Encoding"), ",") {
|
||||
switch strings.TrimSpace(enc) {
|
||||
case "gzip":
|
||||
w.Header().Set("Content-Encoding", "gzip")
|
||||
r.Header.Del("Accept-Encoding")
|
||||
w.Header().Add("Vary", "Accept-Encoding")
|
||||
|
||||
gw, _ := gzip.NewWriterLevel(w, level)
|
||||
defer gw.Close()
|
||||
|
||||
h, hok := w.(http.Hijacker)
|
||||
if !hok { /* w is not Hijacker... oh well... */
|
||||
h = nil
|
||||
}
|
||||
|
||||
f, fok := w.(http.Flusher)
|
||||
if !fok {
|
||||
f = nil
|
||||
}
|
||||
|
||||
cn, cnok := w.(http.CloseNotifier)
|
||||
if !cnok {
|
||||
cn = nil
|
||||
}
|
||||
|
||||
w = &compressResponseWriter{
|
||||
Writer: gw,
|
||||
ResponseWriter: w,
|
||||
Hijacker: h,
|
||||
Flusher: f,
|
||||
CloseNotifier: cn,
|
||||
}
|
||||
|
||||
break L
|
||||
case "deflate":
|
||||
w.Header().Set("Content-Encoding", "deflate")
|
||||
r.Header.Del("Accept-Encoding")
|
||||
w.Header().Add("Vary", "Accept-Encoding")
|
||||
|
||||
fw, _ := flate.NewWriter(w, level)
|
||||
defer fw.Close()
|
||||
|
||||
h, hok := w.(http.Hijacker)
|
||||
if !hok { /* w is not Hijacker... oh well... */
|
||||
h = nil
|
||||
}
|
||||
|
||||
f, fok := w.(http.Flusher)
|
||||
if !fok {
|
||||
f = nil
|
||||
}
|
||||
|
||||
cn, cnok := w.(http.CloseNotifier)
|
||||
if !cnok {
|
||||
cn = nil
|
||||
}
|
||||
|
||||
w = &compressResponseWriter{
|
||||
Writer: fw,
|
||||
ResponseWriter: w,
|
||||
Hijacker: h,
|
||||
Flusher: f,
|
||||
CloseNotifier: cn,
|
||||
}
|
||||
|
||||
break L
|
||||
// detect what encoding to use
|
||||
var encoding string
|
||||
for _, curEnc := range strings.Split(r.Header.Get(acceptEncoding), ",") {
|
||||
curEnc = strings.TrimSpace(curEnc)
|
||||
if curEnc == gzipEncoding || curEnc == flateEncoding {
|
||||
encoding = curEnc
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// always add Accept-Encoding to Vary to prevent intermediate caches corruption
|
||||
w.Header().Add("Vary", acceptEncoding)
|
||||
|
||||
// if we weren't able to identify an encoding we're familiar with, pass on the
|
||||
// request to the handler and return
|
||||
if encoding == "" {
|
||||
h.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
if r.Header.Get("Upgrade") != "" {
|
||||
h.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
// wrap the ResponseWriter with the writer for the chosen encoding
|
||||
var encWriter io.WriteCloser
|
||||
if encoding == gzipEncoding {
|
||||
encWriter, _ = gzip.NewWriterLevel(w, level)
|
||||
} else if encoding == flateEncoding {
|
||||
encWriter, _ = flate.NewWriter(w, level)
|
||||
}
|
||||
defer encWriter.Close()
|
||||
|
||||
w.Header().Set("Content-Encoding", encoding)
|
||||
r.Header.Del(acceptEncoding)
|
||||
|
||||
cw := &compressResponseWriter{
|
||||
w: w,
|
||||
compressor: encWriter,
|
||||
}
|
||||
|
||||
w = httpsnoop.Wrap(w, httpsnoop.Hooks{
|
||||
Write: func(httpsnoop.WriteFunc) httpsnoop.WriteFunc {
|
||||
return cw.Write
|
||||
},
|
||||
WriteHeader: func(httpsnoop.WriteHeaderFunc) httpsnoop.WriteHeaderFunc {
|
||||
return cw.WriteHeader
|
||||
},
|
||||
Flush: func(httpsnoop.FlushFunc) httpsnoop.FlushFunc {
|
||||
return cw.Flush
|
||||
},
|
||||
ReadFrom: func(rff httpsnoop.ReadFromFunc) httpsnoop.ReadFromFunc {
|
||||
return cw.ReadFrom
|
||||
},
|
||||
})
|
||||
|
||||
h.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
|
41
vendor/github.com/gorilla/handlers/cors.go
generated
vendored
41
vendor/github.com/gorilla/handlers/cors.go
generated
vendored
|
@ -26,14 +26,14 @@ type cors struct {
|
|||
type OriginValidator func(string) bool
|
||||
|
||||
var (
|
||||
defaultCorsOptionStatusCode = 200
|
||||
defaultCorsMethods = []string{"GET", "HEAD", "POST"}
|
||||
defaultCorsOptionStatusCode = http.StatusOK
|
||||
defaultCorsMethods = []string{http.MethodGet, http.MethodHead, http.MethodPost}
|
||||
defaultCorsHeaders = []string{"Accept", "Accept-Language", "Content-Language", "Origin"}
|
||||
// (WebKit/Safari v9 sends the Origin header by default in AJAX requests)
|
||||
// (WebKit/Safari v9 sends the Origin header by default in AJAX requests).
|
||||
)
|
||||
|
||||
const (
|
||||
corsOptionMethod string = "OPTIONS"
|
||||
corsOptionMethod string = http.MethodOptions
|
||||
corsAllowOriginHeader string = "Access-Control-Allow-Origin"
|
||||
corsExposeHeadersHeader string = "Access-Control-Expose-Headers"
|
||||
corsMaxAgeHeader string = "Access-Control-Max-Age"
|
||||
|
@ -101,10 +101,8 @@ func (ch *cors) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||
if !ch.isMatch(method, defaultCorsMethods) {
|
||||
w.Header().Set(corsAllowMethodsHeader, method)
|
||||
}
|
||||
} else {
|
||||
if len(ch.exposedHeaders) > 0 {
|
||||
w.Header().Set(corsExposeHeadersHeader, strings.Join(ch.exposedHeaders, ","))
|
||||
}
|
||||
} else if len(ch.exposedHeaders) > 0 {
|
||||
w.Header().Set(corsExposeHeadersHeader, strings.Join(ch.exposedHeaders, ","))
|
||||
}
|
||||
|
||||
if ch.allowCredentials {
|
||||
|
@ -141,22 +139,21 @@ func (ch *cors) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||
// CORS provides Cross-Origin Resource Sharing middleware.
|
||||
// Example:
|
||||
//
|
||||
// import (
|
||||
// "net/http"
|
||||
// import (
|
||||
// "net/http"
|
||||
//
|
||||
// "github.com/gorilla/handlers"
|
||||
// "github.com/gorilla/mux"
|
||||
// )
|
||||
// "github.com/gorilla/handlers"
|
||||
// "github.com/gorilla/mux"
|
||||
// )
|
||||
//
|
||||
// func main() {
|
||||
// r := mux.NewRouter()
|
||||
// r.HandleFunc("/users", UserEndpoint)
|
||||
// r.HandleFunc("/projects", ProjectEndpoint)
|
||||
//
|
||||
// // Apply the CORS middleware to our top-level router, with the defaults.
|
||||
// http.ListenAndServe(":8000", handlers.CORS()(r))
|
||||
// }
|
||||
// func main() {
|
||||
// r := mux.NewRouter()
|
||||
// r.HandleFunc("/users", UserEndpoint)
|
||||
// r.HandleFunc("/projects", ProjectEndpoint)
|
||||
//
|
||||
// // Apply the CORS middleware to our top-level router, with the defaults.
|
||||
// http.ListenAndServe(":8000", handlers.CORS()(r))
|
||||
// }
|
||||
func CORS(opts ...CORSOption) func(http.Handler) http.Handler {
|
||||
return func(h http.Handler) http.Handler {
|
||||
ch := parseCORSOptions(opts...)
|
||||
|
@ -174,7 +171,7 @@ func parseCORSOptions(opts ...CORSOption) *cors {
|
|||
}
|
||||
|
||||
for _, option := range opts {
|
||||
option(ch)
|
||||
_ = option(ch) //TODO: @bharat-rajani, return error to caller if not nil?
|
||||
}
|
||||
|
||||
return ch
|
||||
|
|
50
vendor/github.com/gorilla/handlers/handlers.go
generated
vendored
50
vendor/github.com/gorilla/handlers/handlers.go
generated
vendored
|
@ -35,7 +35,7 @@ func (h MethodHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
}
|
||||
sort.Strings(allow)
|
||||
w.Header().Set("Allow", strings.Join(allow, ", "))
|
||||
if req.Method == "OPTIONS" {
|
||||
if req.Method == http.MethodOptions {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
} else {
|
||||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||
|
@ -44,17 +44,13 @@ func (h MethodHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
}
|
||||
|
||||
// responseLogger is wrapper of http.ResponseWriter that keeps track of its HTTP
|
||||
// status code and body size
|
||||
// status code and body size.
|
||||
type responseLogger struct {
|
||||
w http.ResponseWriter
|
||||
status int
|
||||
size int
|
||||
}
|
||||
|
||||
func (l *responseLogger) Header() http.Header {
|
||||
return l.w.Header()
|
||||
}
|
||||
|
||||
func (l *responseLogger) Write(b []byte) (int, error) {
|
||||
size, err := l.w.Write(b)
|
||||
l.size += size
|
||||
|
@ -74,39 +70,16 @@ func (l *responseLogger) Size() int {
|
|||
return l.size
|
||||
}
|
||||
|
||||
func (l *responseLogger) Flush() {
|
||||
f, ok := l.w.(http.Flusher)
|
||||
if ok {
|
||||
f.Flush()
|
||||
}
|
||||
}
|
||||
|
||||
type hijackLogger struct {
|
||||
responseLogger
|
||||
}
|
||||
|
||||
func (l *hijackLogger) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
||||
h := l.responseLogger.w.(http.Hijacker)
|
||||
conn, rw, err := h.Hijack()
|
||||
if err == nil && l.responseLogger.status == 0 {
|
||||
func (l *responseLogger) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
||||
conn, rw, err := l.w.(http.Hijacker).Hijack()
|
||||
if err == nil && l.status == 0 {
|
||||
// The status will be StatusSwitchingProtocols if there was no error and
|
||||
// WriteHeader has not been called yet
|
||||
l.responseLogger.status = http.StatusSwitchingProtocols
|
||||
l.status = http.StatusSwitchingProtocols
|
||||
}
|
||||
return conn, rw, err
|
||||
}
|
||||
|
||||
type closeNotifyWriter struct {
|
||||
loggingResponseWriter
|
||||
http.CloseNotifier
|
||||
}
|
||||
|
||||
type hijackCloseNotifier struct {
|
||||
loggingResponseWriter
|
||||
http.Hijacker
|
||||
http.CloseNotifier
|
||||
}
|
||||
|
||||
// isContentType validates the Content-Type header matches the supplied
|
||||
// contentType. That is, its type and subtype match.
|
||||
func isContentType(h http.Header, contentType string) bool {
|
||||
|
@ -124,7 +97,7 @@ func isContentType(h http.Header, contentType string) bool {
|
|||
// Only PUT, POST, and PATCH requests are considered.
|
||||
func ContentTypeHandler(h http.Handler, contentTypes ...string) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if !(r.Method == "PUT" || r.Method == "POST" || r.Method == "PATCH") {
|
||||
if !(r.Method == http.MethodPut || r.Method == http.MethodPost || r.Method == http.MethodPatch) {
|
||||
h.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
@ -135,7 +108,10 @@ func ContentTypeHandler(h http.Handler, contentTypes ...string) http.Handler {
|
|||
return
|
||||
}
|
||||
}
|
||||
http.Error(w, fmt.Sprintf("Unsupported content type %q; expected one of %q", r.Header.Get("Content-Type"), contentTypes), http.StatusUnsupportedMediaType)
|
||||
http.Error(w, fmt.Sprintf("Unsupported content type %q; expected one of %q",
|
||||
r.Header.Get("Content-Type"),
|
||||
contentTypes),
|
||||
http.StatusUnsupportedMediaType)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -160,12 +136,12 @@ const (
|
|||
// Form method takes precedence over header method.
|
||||
func HTTPMethodOverrideHandler(h http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method == "POST" {
|
||||
if r.Method == http.MethodPost {
|
||||
om := r.FormValue(HTTPMethodOverrideFormKey)
|
||||
if om == "" {
|
||||
om = r.Header.Get(HTTPMethodOverrideHeader)
|
||||
}
|
||||
if om == "PUT" || om == "PATCH" || om == "DELETE" {
|
||||
if om == http.MethodPut || om == http.MethodPatch || om == http.MethodDelete {
|
||||
r.Method = om
|
||||
}
|
||||
}
|
||||
|
|
29
vendor/github.com/gorilla/handlers/handlers_go18.go
generated
vendored
29
vendor/github.com/gorilla/handlers/handlers_go18.go
generated
vendored
|
@ -1,29 +0,0 @@
|
|||
// +build go1.8
|
||||
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type loggingResponseWriter interface {
|
||||
commonLoggingResponseWriter
|
||||
http.Pusher
|
||||
}
|
||||
|
||||
func (l *responseLogger) Push(target string, opts *http.PushOptions) error {
|
||||
p, ok := l.w.(http.Pusher)
|
||||
if !ok {
|
||||
return fmt.Errorf("responseLogger does not implement http.Pusher")
|
||||
}
|
||||
return p.Push(target, opts)
|
||||
}
|
||||
|
||||
func (c *compressResponseWriter) Push(target string, opts *http.PushOptions) error {
|
||||
p, ok := c.ResponseWriter.(http.Pusher)
|
||||
if !ok {
|
||||
return fmt.Errorf("compressResponseWriter does not implement http.Pusher")
|
||||
}
|
||||
return p.Push(target, opts)
|
||||
}
|
7
vendor/github.com/gorilla/handlers/handlers_pre18.go
generated
vendored
7
vendor/github.com/gorilla/handlers/handlers_pre18.go
generated
vendored
|
@ -1,7 +0,0 @@
|
|||
// +build !go1.8
|
||||
|
||||
package handlers
|
||||
|
||||
type loggingResponseWriter interface {
|
||||
commonLoggingResponseWriter
|
||||
}
|
71
vendor/github.com/gorilla/handlers/logging.go
generated
vendored
71
vendor/github.com/gorilla/handlers/logging.go
generated
vendored
|
@ -12,11 +12,13 @@ import (
|
|||
"strconv"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/felixge/httpsnoop"
|
||||
)
|
||||
|
||||
// Logging
|
||||
|
||||
// LogFormatterParams is the structure any formatter will be handed when time to log comes
|
||||
// LogFormatterParams is the structure any formatter will be handed when time to log comes.
|
||||
type LogFormatterParams struct {
|
||||
Request *http.Request
|
||||
URL url.URL
|
||||
|
@ -25,7 +27,7 @@ type LogFormatterParams struct {
|
|||
Size int
|
||||
}
|
||||
|
||||
// LogFormatter gives the signature of the formatter function passed to CustomLoggingHandler
|
||||
// LogFormatter gives the signature of the formatter function passed to CustomLoggingHandler.
|
||||
type LogFormatter func(writer io.Writer, params LogFormatterParams)
|
||||
|
||||
// loggingHandler is the http.Handler implementation for LoggingHandlerTo and its
|
||||
|
@ -39,12 +41,15 @@ type loggingHandler struct {
|
|||
|
||||
func (h loggingHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
t := time.Now()
|
||||
logger := makeLogger(w)
|
||||
logger, w := makeLogger(w)
|
||||
url := *req.URL
|
||||
|
||||
h.handler.ServeHTTP(logger, req)
|
||||
h.handler.ServeHTTP(w, req)
|
||||
if req.MultipartForm != nil {
|
||||
req.MultipartForm.RemoveAll()
|
||||
err := req.MultipartForm.RemoveAll()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
params := LogFormatterParams{
|
||||
|
@ -58,34 +63,23 @@ func (h loggingHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
h.formatter(h.writer, params)
|
||||
}
|
||||
|
||||
func makeLogger(w http.ResponseWriter) loggingResponseWriter {
|
||||
var logger loggingResponseWriter = &responseLogger{w: w, status: http.StatusOK}
|
||||
if _, ok := w.(http.Hijacker); ok {
|
||||
logger = &hijackLogger{responseLogger{w: w, status: http.StatusOK}}
|
||||
}
|
||||
h, ok1 := logger.(http.Hijacker)
|
||||
c, ok2 := w.(http.CloseNotifier)
|
||||
if ok1 && ok2 {
|
||||
return hijackCloseNotifier{logger, h, c}
|
||||
}
|
||||
if ok2 {
|
||||
return &closeNotifyWriter{logger, c}
|
||||
}
|
||||
return logger
|
||||
}
|
||||
|
||||
type commonLoggingResponseWriter interface {
|
||||
http.ResponseWriter
|
||||
http.Flusher
|
||||
Status() int
|
||||
Size() int
|
||||
func makeLogger(w http.ResponseWriter) (*responseLogger, http.ResponseWriter) {
|
||||
logger := &responseLogger{w: w, status: http.StatusOK}
|
||||
return logger, httpsnoop.Wrap(w, httpsnoop.Hooks{
|
||||
Write: func(httpsnoop.WriteFunc) httpsnoop.WriteFunc {
|
||||
return logger.Write
|
||||
},
|
||||
WriteHeader: func(httpsnoop.WriteHeaderFunc) httpsnoop.WriteHeaderFunc {
|
||||
return logger.WriteHeader
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const lowerhex = "0123456789abcdef"
|
||||
|
||||
func appendQuoted(buf []byte, s string) []byte {
|
||||
var runeTmp [utf8.UTFMax]byte
|
||||
for width := 0; len(s) > 0; s = s[width:] {
|
||||
for width := 0; len(s) > 0; s = s[width:] { //nolint: wastedassign //TODO: why width starts from 0and reassigned as 1
|
||||
r := rune(s[0])
|
||||
width = 1
|
||||
if r >= utf8.RuneSelf {
|
||||
|
@ -145,7 +139,6 @@ func appendQuoted(buf []byte, s string) []byte {
|
|||
}
|
||||
}
|
||||
return buf
|
||||
|
||||
}
|
||||
|
||||
// buildCommonLogLine builds a log entry for req in Apache Common Log Format.
|
||||
|
@ -160,7 +153,6 @@ func buildCommonLogLine(req *http.Request, url url.URL, ts time.Time, status int
|
|||
}
|
||||
|
||||
host, _, err := net.SplitHostPort(req.RemoteAddr)
|
||||
|
||||
if err != nil {
|
||||
host = req.RemoteAddr
|
||||
}
|
||||
|
@ -202,7 +194,7 @@ func buildCommonLogLine(req *http.Request, url url.URL, ts time.Time, status int
|
|||
func writeLog(writer io.Writer, params LogFormatterParams) {
|
||||
buf := buildCommonLogLine(params.Request, params.URL, params.TimeStamp, params.StatusCode, params.Size)
|
||||
buf = append(buf, '\n')
|
||||
writer.Write(buf)
|
||||
_, _ = writer.Write(buf)
|
||||
}
|
||||
|
||||
// writeCombinedLog writes a log entry for req to w in Apache Combined Log Format.
|
||||
|
@ -215,7 +207,7 @@ func writeCombinedLog(writer io.Writer, params LogFormatterParams) {
|
|||
buf = append(buf, `" "`...)
|
||||
buf = appendQuoted(buf, params.Request.UserAgent())
|
||||
buf = append(buf, '"', '\n')
|
||||
writer.Write(buf)
|
||||
_, _ = writer.Write(buf)
|
||||
}
|
||||
|
||||
// CombinedLoggingHandler return a http.Handler that wraps h and logs requests to out in
|
||||
|
@ -223,7 +215,7 @@ func writeCombinedLog(writer io.Writer, params LogFormatterParams) {
|
|||
//
|
||||
// See http://httpd.apache.org/docs/2.2/logs.html#combined for a description of this format.
|
||||
//
|
||||
// LoggingHandler always sets the ident field of the log to -
|
||||
// LoggingHandler always sets the ident field of the log to -.
|
||||
func CombinedLoggingHandler(out io.Writer, h http.Handler) http.Handler {
|
||||
return loggingHandler{out, h, writeCombinedLog}
|
||||
}
|
||||
|
@ -237,19 +229,18 @@ func CombinedLoggingHandler(out io.Writer, h http.Handler) http.Handler {
|
|||
//
|
||||
// Example:
|
||||
//
|
||||
// r := mux.NewRouter()
|
||||
// r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
// w.Write([]byte("This is a catch-all route"))
|
||||
// })
|
||||
// loggedRouter := handlers.LoggingHandler(os.Stdout, r)
|
||||
// http.ListenAndServe(":1123", loggedRouter)
|
||||
//
|
||||
// r := mux.NewRouter()
|
||||
// r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
// w.Write([]byte("This is a catch-all route"))
|
||||
// })
|
||||
// loggedRouter := handlers.LoggingHandler(os.Stdout, r)
|
||||
// http.ListenAndServe(":1123", loggedRouter)
|
||||
func LoggingHandler(out io.Writer, h http.Handler) http.Handler {
|
||||
return loggingHandler{out, h, writeLog}
|
||||
}
|
||||
|
||||
// CustomLoggingHandler provides a way to supply a custom log formatter
|
||||
// while taking advantage of the mechanisms in this package
|
||||
// while taking advantage of the mechanisms in this package.
|
||||
func CustomLoggingHandler(out io.Writer, h http.Handler, f LogFormatter) http.Handler {
|
||||
return loggingHandler{out, h, f}
|
||||
}
|
||||
|
|
16
vendor/github.com/gorilla/handlers/proxy_headers.go
generated
vendored
16
vendor/github.com/gorilla/handlers/proxy_headers.go
generated
vendored
|
@ -18,7 +18,7 @@ var (
|
|||
var (
|
||||
// RFC7239 defines a new "Forwarded: " header designed to replace the
|
||||
// existing use of X-Forwarded-* headers.
|
||||
// e.g. Forwarded: for=192.0.2.60;proto=https;by=203.0.113.43
|
||||
// e.g. Forwarded: for=192.0.2.60;proto=https;by=203.0.113.43.
|
||||
forwarded = http.CanonicalHeaderKey("Forwarded")
|
||||
// Allows for a sub-match of the first value after 'for=' to the next
|
||||
// comma, semi-colon or space. The match is case-insensitive.
|
||||
|
@ -67,7 +67,9 @@ func ProxyHeaders(h http.Handler) http.Handler {
|
|||
func getIP(r *http.Request) string {
|
||||
var addr string
|
||||
|
||||
if fwd := r.Header.Get(xForwardedFor); fwd != "" {
|
||||
switch {
|
||||
case r.Header.Get(xForwardedFor) != "":
|
||||
fwd := r.Header.Get(xForwardedFor)
|
||||
// Only grab the first (client) address. Note that '192.168.0.1,
|
||||
// 10.1.1.1' is a valid key for X-Forwarded-For where addresses after
|
||||
// the first may represent forwarding proxies earlier in the chain.
|
||||
|
@ -76,17 +78,15 @@ func getIP(r *http.Request) string {
|
|||
s = len(fwd)
|
||||
}
|
||||
addr = fwd[:s]
|
||||
} else if fwd := r.Header.Get(xRealIP); fwd != "" {
|
||||
// X-Real-IP should only contain one IP address (the client making the
|
||||
// request).
|
||||
addr = fwd
|
||||
} else if fwd := r.Header.Get(forwarded); fwd != "" {
|
||||
case r.Header.Get(xRealIP) != "":
|
||||
addr = r.Header.Get(xRealIP)
|
||||
case r.Header.Get(forwarded) != "":
|
||||
// match should contain at least two elements if the protocol was
|
||||
// specified in the Forwarded header. The first element will always be
|
||||
// the 'for=' capture, which we ignore. In the case of multiple IP
|
||||
// addresses (for=8.8.8.8, 8.8.4.4,172.16.1.20 is valid) we only
|
||||
// extract the first, which should be the client IP.
|
||||
if match := forRegex.FindStringSubmatch(fwd); len(match) > 1 {
|
||||
if match := forRegex.FindStringSubmatch(r.Header.Get(forwarded)); len(match) > 1 {
|
||||
// IPv6 addresses in Forwarded headers are quoted-strings. We strip
|
||||
// these quotes.
|
||||
addr = strings.Trim(match[1], `"`)
|
||||
|
|
31
vendor/github.com/gorilla/handlers/recovery.go
generated
vendored
31
vendor/github.com/gorilla/handlers/recovery.go
generated
vendored
|
@ -19,7 +19,7 @@ type recoveryHandler struct {
|
|||
|
||||
// RecoveryOption provides a functional approach to define
|
||||
// configuration for a handler; such as setting the logging
|
||||
// whether or not to print strack traces on panic.
|
||||
// whether or not to print stack traces on panic.
|
||||
type RecoveryOption func(http.Handler)
|
||||
|
||||
func parseRecoveryOptions(h http.Handler, opts ...RecoveryOption) http.Handler {
|
||||
|
@ -36,12 +36,12 @@ func parseRecoveryOptions(h http.Handler, opts ...RecoveryOption) http.Handler {
|
|||
//
|
||||
// Example:
|
||||
//
|
||||
// r := mux.NewRouter()
|
||||
// r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
// panic("Unexpected error!")
|
||||
// })
|
||||
// r := mux.NewRouter()
|
||||
// r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
// panic("Unexpected error!")
|
||||
// })
|
||||
//
|
||||
// http.ListenAndServe(":1123", handlers.RecoveryHandler()(r))
|
||||
// http.ListenAndServe(":1123", handlers.RecoveryHandler()(r))
|
||||
func RecoveryHandler(opts ...RecoveryOption) func(h http.Handler) http.Handler {
|
||||
return func(h http.Handler) http.Handler {
|
||||
r := &recoveryHandler{handler: h}
|
||||
|
@ -50,20 +50,22 @@ func RecoveryHandler(opts ...RecoveryOption) func(h http.Handler) http.Handler {
|
|||
}
|
||||
|
||||
// RecoveryLogger is a functional option to override
|
||||
// the default logger
|
||||
// the default logger.
|
||||
func RecoveryLogger(logger RecoveryHandlerLogger) RecoveryOption {
|
||||
return func(h http.Handler) {
|
||||
r := h.(*recoveryHandler)
|
||||
r := h.(*recoveryHandler) //nolint:errcheck //TODO:
|
||||
// @bharat-rajani should return type-assertion error but would break the API?
|
||||
r.logger = logger
|
||||
}
|
||||
}
|
||||
|
||||
// PrintRecoveryStack is a functional option to enable
|
||||
// or disable printing stack traces on panic.
|
||||
func PrintRecoveryStack(print bool) RecoveryOption {
|
||||
func PrintRecoveryStack(shouldPrint bool) RecoveryOption {
|
||||
return func(h http.Handler) {
|
||||
r := h.(*recoveryHandler)
|
||||
r.printStack = print
|
||||
r := h.(*recoveryHandler) //nolint:errcheck //TODO:
|
||||
// @bharat-rajani should return type-assertion error but would break the API?
|
||||
r.printStack = shouldPrint
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,6 +88,11 @@ func (h recoveryHandler) log(v ...interface{}) {
|
|||
}
|
||||
|
||||
if h.printStack {
|
||||
debug.PrintStack()
|
||||
stack := string(debug.Stack())
|
||||
if h.logger != nil {
|
||||
h.logger.Println(stack)
|
||||
} else {
|
||||
log.Println(stack)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
20
vendor/github.com/gorilla/mux/.editorconfig
generated
vendored
Normal file
20
vendor/github.com/gorilla/mux/.editorconfig
generated
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
; https://editorconfig.org/
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
insert_final_newline = true
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[{Makefile,go.mod,go.sum,*.go,.gitmodules}]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
|
||||
[*.md]
|
||||
indent_size = 4
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
eclint_indent_style = unset
|
1
vendor/github.com/gorilla/mux/.gitignore
generated
vendored
Normal file
1
vendor/github.com/gorilla/mux/.gitignore
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
coverage.coverprofile
|
8
vendor/github.com/gorilla/mux/AUTHORS
generated
vendored
8
vendor/github.com/gorilla/mux/AUTHORS
generated
vendored
|
@ -1,8 +0,0 @@
|
|||
# This is the official list of gorilla/mux authors for copyright purposes.
|
||||
#
|
||||
# Please keep the list sorted.
|
||||
|
||||
Google LLC (https://opensource.google.com/)
|
||||
Kamil Kisielk <kamil@kamilkisiel.net>
|
||||
Matt Silverlock <matt@eatsleeprepeat.net>
|
||||
Rodrigo Moraes (https://github.com/moraes)
|
2
vendor/github.com/gorilla/mux/LICENSE
generated
vendored
2
vendor/github.com/gorilla/mux/LICENSE
generated
vendored
|
@ -1,4 +1,4 @@
|
|||
Copyright (c) 2012-2018 The Gorilla Authors. All rights reserved.
|
||||
Copyright (c) 2023 The Gorilla Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
|
|
34
vendor/github.com/gorilla/mux/Makefile
generated
vendored
Normal file
34
vendor/github.com/gorilla/mux/Makefile
generated
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
GO_LINT=$(shell which golangci-lint 2> /dev/null || echo '')
|
||||
GO_LINT_URI=github.com/golangci/golangci-lint/cmd/golangci-lint@latest
|
||||
|
||||
GO_SEC=$(shell which gosec 2> /dev/null || echo '')
|
||||
GO_SEC_URI=github.com/securego/gosec/v2/cmd/gosec@latest
|
||||
|
||||
GO_VULNCHECK=$(shell which govulncheck 2> /dev/null || echo '')
|
||||
GO_VULNCHECK_URI=golang.org/x/vuln/cmd/govulncheck@latest
|
||||
|
||||
.PHONY: golangci-lint
|
||||
golangci-lint:
|
||||
$(if $(GO_LINT), ,go install $(GO_LINT_URI))
|
||||
@echo "##### Running golangci-lint"
|
||||
golangci-lint run -v
|
||||
|
||||
.PHONY: gosec
|
||||
gosec:
|
||||
$(if $(GO_SEC), ,go install $(GO_SEC_URI))
|
||||
@echo "##### Running gosec"
|
||||
gosec ./...
|
||||
|
||||
.PHONY: govulncheck
|
||||
govulncheck:
|
||||
$(if $(GO_VULNCHECK), ,go install $(GO_VULNCHECK_URI))
|
||||
@echo "##### Running govulncheck"
|
||||
govulncheck ./...
|
||||
|
||||
.PHONY: verify
|
||||
verify: golangci-lint gosec govulncheck
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
@echo "##### Running tests"
|
||||
go test -race -cover -coverprofile=coverage.coverprofile -covermode=atomic -v ./...
|
63
vendor/github.com/gorilla/mux/README.md
generated
vendored
63
vendor/github.com/gorilla/mux/README.md
generated
vendored
|
@ -1,12 +1,12 @@
|
|||
# gorilla/mux
|
||||
|
||||
[](https://godoc.org/github.com/gorilla/mux)
|
||||
[](https://circleci.com/gh/gorilla/mux)
|
||||
[](https://sourcegraph.com/github.com/gorilla/mux?badge)
|
||||

|
||||
[](https://codecov.io/github/gorilla/mux)
|
||||
[](https://godoc.org/github.com/gorilla/mux)
|
||||
[](https://sourcegraph.com/github.com/gorilla/mux?badge)
|
||||
|
||||

|
||||
|
||||
https://www.gorillatoolkit.org/pkg/mux
|
||||

|
||||
|
||||
Package `gorilla/mux` implements a request router and dispatcher for matching incoming requests to
|
||||
their respective handler.
|
||||
|
@ -247,32 +247,25 @@ type spaHandler struct {
|
|||
// file located at the index path on the SPA handler will be served. This
|
||||
// is suitable behavior for serving an SPA (single page application).
|
||||
func (h spaHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
// get the absolute path to prevent directory traversal
|
||||
path, err := filepath.Abs(r.URL.Path)
|
||||
if err != nil {
|
||||
// if we failed to get the absolute path respond with a 400 bad request
|
||||
// and stop
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
// Join internally call path.Clean to prevent directory traversal
|
||||
path := filepath.Join(h.staticPath, r.URL.Path)
|
||||
|
||||
// prepend the path with the path to the static directory
|
||||
path = filepath.Join(h.staticPath, path)
|
||||
|
||||
// check whether a file exists at the given path
|
||||
_, err = os.Stat(path)
|
||||
if os.IsNotExist(err) {
|
||||
// file does not exist, serve index.html
|
||||
// check whether a file exists or is a directory at the given path
|
||||
fi, err := os.Stat(path)
|
||||
if os.IsNotExist(err) || fi.IsDir() {
|
||||
// file does not exist or path is a directory, serve index.html
|
||||
http.ServeFile(w, r, filepath.Join(h.staticPath, h.indexPath))
|
||||
return
|
||||
} else if err != nil {
|
||||
// if we got an error (that wasn't that the file doesn't exist) stating the
|
||||
// file, return a 500 internal server error and stop
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// otherwise, use http.FileServer to serve the static dir
|
||||
if err != nil {
|
||||
// if we got an error (that wasn't that the file doesn't exist) stating the
|
||||
// file, return a 500 internal server error and stop
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// otherwise, use http.FileServer to serve the static file
|
||||
http.FileServer(http.Dir(h.staticPath)).ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
|
@ -375,6 +368,19 @@ url, err := r.Get("article").URL("subdomain", "news",
|
|||
"id", "42")
|
||||
```
|
||||
|
||||
To find all the required variables for a given route when calling `URL()`, the method `GetVarNames()` is available:
|
||||
```go
|
||||
r := mux.NewRouter()
|
||||
r.Host("{domain}").
|
||||
Path("/{group}/{item_id}").
|
||||
Queries("some_data1", "{some_data1}").
|
||||
Queries("some_data2", "{some_data2}").
|
||||
Name("article")
|
||||
|
||||
// Will print [domain group item_id some_data1 some_data2] <nil>
|
||||
fmt.Println(r.Get("article").GetVarNames())
|
||||
|
||||
```
|
||||
### Walking Routes
|
||||
|
||||
The `Walk` function on `mux.Router` can be used to visit all of the routes that are registered on a router. For example,
|
||||
|
@ -572,7 +578,7 @@ func (amw *authenticationMiddleware) Middleware(next http.Handler) http.Handler
|
|||
r := mux.NewRouter()
|
||||
r.HandleFunc("/", handler)
|
||||
|
||||
amw := authenticationMiddleware{}
|
||||
amw := authenticationMiddleware{tokenUsers: make(map[string]string)}
|
||||
amw.Populate()
|
||||
|
||||
r.Use(amw.Middleware)
|
||||
|
@ -758,7 +764,8 @@ func TestMetricsHandler(t *testing.T) {
|
|||
|
||||
rr := httptest.NewRecorder()
|
||||
|
||||
// Need to create a router that we can pass the request through so that the vars will be added to the context
|
||||
// To add the vars to the context,
|
||||
// we need to create a router through which we can pass the request.
|
||||
router := mux.NewRouter()
|
||||
router.HandleFunc("/metrics/{type}", MetricsHandler)
|
||||
router.ServeHTTP(rr, req)
|
||||
|
|
25
vendor/github.com/gorilla/mux/doc.go
generated
vendored
25
vendor/github.com/gorilla/mux/doc.go
generated
vendored
|
@ -10,18 +10,18 @@ http.ServeMux, mux.Router matches incoming requests against a list of
|
|||
registered routes and calls a handler for the route that matches the URL
|
||||
or other conditions. The main features are:
|
||||
|
||||
* Requests can be matched based on URL host, path, path prefix, schemes,
|
||||
header and query values, HTTP methods or using custom matchers.
|
||||
* URL hosts, paths and query values can have variables with an optional
|
||||
regular expression.
|
||||
* Registered URLs can be built, or "reversed", which helps maintaining
|
||||
references to resources.
|
||||
* Routes can be used as subrouters: nested routes are only tested if the
|
||||
parent route matches. This is useful to define groups of routes that
|
||||
share common conditions like a host, a path prefix or other repeated
|
||||
attributes. As a bonus, this optimizes request matching.
|
||||
* It implements the http.Handler interface so it is compatible with the
|
||||
standard http.ServeMux.
|
||||
- Requests can be matched based on URL host, path, path prefix, schemes,
|
||||
header and query values, HTTP methods or using custom matchers.
|
||||
- URL hosts, paths and query values can have variables with an optional
|
||||
regular expression.
|
||||
- Registered URLs can be built, or "reversed", which helps maintaining
|
||||
references to resources.
|
||||
- Routes can be used as subrouters: nested routes are only tested if the
|
||||
parent route matches. This is useful to define groups of routes that
|
||||
share common conditions like a host, a path prefix or other repeated
|
||||
attributes. As a bonus, this optimizes request matching.
|
||||
- It implements the http.Handler interface so it is compatible with the
|
||||
standard http.ServeMux.
|
||||
|
||||
Let's start registering a couple of URL paths and handlers:
|
||||
|
||||
|
@ -301,6 +301,5 @@ A more complex authentication middleware, which maps session token to users, cou
|
|||
r.Use(amw.Middleware)
|
||||
|
||||
Note: The handler chain will be stopped if your middleware doesn't call `next.ServeHTTP()` with the corresponding parameters. This can be used to abort a request if the middleware writer wants to.
|
||||
|
||||
*/
|
||||
package mux
|
||||
|
|
19
vendor/github.com/gorilla/mux/mux.go
generated
vendored
19
vendor/github.com/gorilla/mux/mux.go
generated
vendored
|
@ -31,24 +31,26 @@ func NewRouter() *Router {
|
|||
// It implements the http.Handler interface, so it can be registered to serve
|
||||
// requests:
|
||||
//
|
||||
// var router = mux.NewRouter()
|
||||
// var router = mux.NewRouter()
|
||||
//
|
||||
// func main() {
|
||||
// http.Handle("/", router)
|
||||
// }
|
||||
// func main() {
|
||||
// http.Handle("/", router)
|
||||
// }
|
||||
//
|
||||
// Or, for Google App Engine, register it in a init() function:
|
||||
//
|
||||
// func init() {
|
||||
// http.Handle("/", router)
|
||||
// }
|
||||
// func init() {
|
||||
// http.Handle("/", router)
|
||||
// }
|
||||
//
|
||||
// This will send all incoming requests to the router.
|
||||
type Router struct {
|
||||
// Configurable Handler to be used when no route matches.
|
||||
// This can be used to render your own 404 Not Found errors.
|
||||
NotFoundHandler http.Handler
|
||||
|
||||
// Configurable Handler to be used when the request method does not match the route.
|
||||
// This can be used to render your own 405 Method Not Allowed errors.
|
||||
MethodNotAllowedHandler http.Handler
|
||||
|
||||
// Routes to be matched, in order.
|
||||
|
@ -435,8 +437,7 @@ func Vars(r *http.Request) map[string]string {
|
|||
// CurrentRoute returns the matched route for the current request, if any.
|
||||
// This only works when called inside the handler of the matched route
|
||||
// because the matched route is stored in the request context which is cleared
|
||||
// after the handler returns, unless the KeepContext option is set on the
|
||||
// Router.
|
||||
// after the handler returns.
|
||||
func CurrentRoute(r *http.Request) *Route {
|
||||
if rv := r.Context().Value(routeKey); rv != nil {
|
||||
return rv.(*Route)
|
||||
|
|
16
vendor/github.com/gorilla/mux/regexp.go
generated
vendored
16
vendor/github.com/gorilla/mux/regexp.go
generated
vendored
|
@ -22,10 +22,10 @@ type routeRegexpOptions struct {
|
|||
type regexpType int
|
||||
|
||||
const (
|
||||
regexpTypePath regexpType = 0
|
||||
regexpTypeHost regexpType = 1
|
||||
regexpTypePrefix regexpType = 2
|
||||
regexpTypeQuery regexpType = 3
|
||||
regexpTypePath regexpType = iota
|
||||
regexpTypeHost
|
||||
regexpTypePrefix
|
||||
regexpTypeQuery
|
||||
)
|
||||
|
||||
// newRouteRegexp parses a route template and returns a routeRegexp,
|
||||
|
@ -195,7 +195,7 @@ func (r *routeRegexp) Match(req *http.Request, match *RouteMatch) bool {
|
|||
|
||||
// url builds a URL part using the given values.
|
||||
func (r *routeRegexp) url(values map[string]string) (string, error) {
|
||||
urlValues := make([]interface{}, len(r.varsN), len(r.varsN))
|
||||
urlValues := make([]interface{}, len(r.varsN))
|
||||
for k, v := range r.varsN {
|
||||
value, ok := values[v]
|
||||
if !ok {
|
||||
|
@ -325,6 +325,12 @@ func (v routeRegexpGroup) setMatch(req *http.Request, m *RouteMatch, r *Route) {
|
|||
// Store host variables.
|
||||
if v.host != nil {
|
||||
host := getHost(req)
|
||||
if v.host.wildcardHostPort {
|
||||
// Don't be strict on the port match
|
||||
if i := strings.Index(host, ":"); i != -1 {
|
||||
host = host[:i]
|
||||
}
|
||||
}
|
||||
matches := v.host.regexp.FindStringSubmatchIndex(host)
|
||||
if len(matches) > 0 {
|
||||
extractVars(host, matches, v.host.varsN, m.Vars)
|
||||
|
|
109
vendor/github.com/gorilla/mux/route.go
generated
vendored
109
vendor/github.com/gorilla/mux/route.go
generated
vendored
|
@ -64,8 +64,18 @@ func (r *Route) Match(req *http.Request, match *RouteMatch) bool {
|
|||
match.MatchErr = nil
|
||||
}
|
||||
|
||||
matchErr = nil
|
||||
matchErr = nil // nolint:ineffassign
|
||||
return false
|
||||
} else {
|
||||
// Multiple routes may share the same path but use different HTTP methods. For instance:
|
||||
// Route 1: POST "/users/{id}".
|
||||
// Route 2: GET "/users/{id}", parameters: "id": "[0-9]+".
|
||||
//
|
||||
// The router must handle these cases correctly. For a GET request to "/users/abc" with "id" as "-2",
|
||||
// The router should return a "Not Found" error as no route fully matches this request.
|
||||
if match.MatchErr == ErrMethodMismatch {
|
||||
match.MatchErr = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -230,9 +240,9 @@ func (m headerMatcher) Match(r *http.Request, match *RouteMatch) bool {
|
|||
// Headers adds a matcher for request header values.
|
||||
// It accepts a sequence of key/value pairs to be matched. For example:
|
||||
//
|
||||
// r := mux.NewRouter()
|
||||
// r.Headers("Content-Type", "application/json",
|
||||
// "X-Requested-With", "XMLHttpRequest")
|
||||
// r := mux.NewRouter().NewRoute()
|
||||
// r.Headers("Content-Type", "application/json",
|
||||
// "X-Requested-With", "XMLHttpRequest")
|
||||
//
|
||||
// The above route will only match if both request header values match.
|
||||
// If the value is an empty string, it will match any value if the key is set.
|
||||
|
@ -255,9 +265,9 @@ func (m headerRegexMatcher) Match(r *http.Request, match *RouteMatch) bool {
|
|||
// HeadersRegexp accepts a sequence of key/value pairs, where the value has regex
|
||||
// support. For example:
|
||||
//
|
||||
// r := mux.NewRouter()
|
||||
// r.HeadersRegexp("Content-Type", "application/(text|json)",
|
||||
// "X-Requested-With", "XMLHttpRequest")
|
||||
// r := mux.NewRouter().NewRoute()
|
||||
// r.HeadersRegexp("Content-Type", "application/(text|json)",
|
||||
// "X-Requested-With", "XMLHttpRequest")
|
||||
//
|
||||
// The above route will only match if both the request header matches both regular expressions.
|
||||
// If the value is an empty string, it will match any value if the key is set.
|
||||
|
@ -283,10 +293,10 @@ func (r *Route) HeadersRegexp(pairs ...string) *Route {
|
|||
//
|
||||
// For example:
|
||||
//
|
||||
// r := mux.NewRouter()
|
||||
// r.Host("www.example.com")
|
||||
// r.Host("{subdomain}.domain.com")
|
||||
// r.Host("{subdomain:[a-z]+}.domain.com")
|
||||
// r := mux.NewRouter().NewRoute()
|
||||
// r.Host("www.example.com")
|
||||
// r.Host("{subdomain}.domain.com")
|
||||
// r.Host("{subdomain:[a-z]+}.domain.com")
|
||||
//
|
||||
// Variable names must be unique in a given route. They can be retrieved
|
||||
// calling mux.Vars(request).
|
||||
|
@ -342,11 +352,11 @@ func (r *Route) Methods(methods ...string) *Route {
|
|||
//
|
||||
// For example:
|
||||
//
|
||||
// r := mux.NewRouter()
|
||||
// r.Path("/products/").Handler(ProductsHandler)
|
||||
// r.Path("/products/{key}").Handler(ProductsHandler)
|
||||
// r.Path("/articles/{category}/{id:[0-9]+}").
|
||||
// Handler(ArticleHandler)
|
||||
// r := mux.NewRouter().NewRoute()
|
||||
// r.Path("/products/").Handler(ProductsHandler)
|
||||
// r.Path("/products/{key}").Handler(ProductsHandler)
|
||||
// r.Path("/articles/{category}/{id:[0-9]+}").
|
||||
// Handler(ArticleHandler)
|
||||
//
|
||||
// Variable names must be unique in a given route. They can be retrieved
|
||||
// calling mux.Vars(request).
|
||||
|
@ -377,8 +387,8 @@ func (r *Route) PathPrefix(tpl string) *Route {
|
|||
// It accepts a sequence of key/value pairs. Values may define variables.
|
||||
// For example:
|
||||
//
|
||||
// r := mux.NewRouter()
|
||||
// r.Queries("foo", "bar", "id", "{id:[0-9]+}")
|
||||
// r := mux.NewRouter().NewRoute()
|
||||
// r.Queries("foo", "bar", "id", "{id:[0-9]+}")
|
||||
//
|
||||
// The above route will only match if the URL contains the defined queries
|
||||
// values, e.g.: ?foo=bar&id=42.
|
||||
|
@ -473,11 +483,11 @@ func (r *Route) BuildVarsFunc(f BuildVarsFunc) *Route {
|
|||
//
|
||||
// It will test the inner routes only if the parent route matched. For example:
|
||||
//
|
||||
// r := mux.NewRouter()
|
||||
// s := r.Host("www.example.com").Subrouter()
|
||||
// s.HandleFunc("/products/", ProductsHandler)
|
||||
// s.HandleFunc("/products/{key}", ProductHandler)
|
||||
// s.HandleFunc("/articles/{category}/{id:[0-9]+}"), ArticleHandler)
|
||||
// r := mux.NewRouter().NewRoute()
|
||||
// s := r.Host("www.example.com").Subrouter()
|
||||
// s.HandleFunc("/products/", ProductsHandler)
|
||||
// s.HandleFunc("/products/{key}", ProductHandler)
|
||||
// s.HandleFunc("/articles/{category}/{id:[0-9]+}"), ArticleHandler)
|
||||
//
|
||||
// Here, the routes registered in the subrouter won't be tested if the host
|
||||
// doesn't match.
|
||||
|
@ -497,36 +507,36 @@ func (r *Route) Subrouter() *Router {
|
|||
// It accepts a sequence of key/value pairs for the route variables. For
|
||||
// example, given this route:
|
||||
//
|
||||
// r := mux.NewRouter()
|
||||
// r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler).
|
||||
// Name("article")
|
||||
// r := mux.NewRouter()
|
||||
// r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler).
|
||||
// Name("article")
|
||||
//
|
||||
// ...a URL for it can be built using:
|
||||
//
|
||||
// url, err := r.Get("article").URL("category", "technology", "id", "42")
|
||||
// url, err := r.Get("article").URL("category", "technology", "id", "42")
|
||||
//
|
||||
// ...which will return an url.URL with the following path:
|
||||
//
|
||||
// "/articles/technology/42"
|
||||
// "/articles/technology/42"
|
||||
//
|
||||
// This also works for host variables:
|
||||
//
|
||||
// r := mux.NewRouter()
|
||||
// r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler).
|
||||
// Host("{subdomain}.domain.com").
|
||||
// Name("article")
|
||||
// r := mux.NewRouter()
|
||||
// r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler).
|
||||
// Host("{subdomain}.domain.com").
|
||||
// Name("article")
|
||||
//
|
||||
// // url.String() will be "http://news.domain.com/articles/technology/42"
|
||||
// url, err := r.Get("article").URL("subdomain", "news",
|
||||
// "category", "technology",
|
||||
// "id", "42")
|
||||
// // url.String() will be "http://news.domain.com/articles/technology/42"
|
||||
// url, err := r.Get("article").URL("subdomain", "news",
|
||||
// "category", "technology",
|
||||
// "id", "42")
|
||||
//
|
||||
// The scheme of the resulting url will be the first argument that was passed to Schemes:
|
||||
//
|
||||
// // url.String() will be "https://example.com"
|
||||
// r := mux.NewRouter()
|
||||
// url, err := r.Host("example.com")
|
||||
// .Schemes("https", "http").URL()
|
||||
// // url.String() will be "https://example.com"
|
||||
// r := mux.NewRouter().NewRoute()
|
||||
// url, err := r.Host("example.com")
|
||||
// .Schemes("https", "http").URL()
|
||||
//
|
||||
// All variables defined in the route are required, and their values must
|
||||
// conform to the corresponding patterns.
|
||||
|
@ -718,6 +728,25 @@ func (r *Route) GetHostTemplate() (string, error) {
|
|||
return r.regexp.host.template, nil
|
||||
}
|
||||
|
||||
// GetVarNames returns the names of all variables added by regexp matchers
|
||||
// These can be used to know which route variables should be passed into r.URL()
|
||||
func (r *Route) GetVarNames() ([]string, error) {
|
||||
if r.err != nil {
|
||||
return nil, r.err
|
||||
}
|
||||
var varNames []string
|
||||
if r.regexp.host != nil {
|
||||
varNames = append(varNames, r.regexp.host.varsN...)
|
||||
}
|
||||
if r.regexp.path != nil {
|
||||
varNames = append(varNames, r.regexp.path.varsN...)
|
||||
}
|
||||
for _, regx := range r.regexp.queries {
|
||||
varNames = append(varNames, regx.varsN...)
|
||||
}
|
||||
return varNames, nil
|
||||
}
|
||||
|
||||
// prepareVars converts the route variable pairs into a map. If the route has a
|
||||
// BuildVarsFunc, it is invoked.
|
||||
func (r *Route) prepareVars(pairs ...string) (map[string]string, error) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue