summaryrefslogtreecommitdiff
path: root/vendor/github.com/gorilla/handlers
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/gorilla/handlers')
-rw-r--r--vendor/github.com/gorilla/handlers/.editorconfig20
-rw-r--r--vendor/github.com/gorilla/handlers/.gitignore2
-rw-r--r--vendor/github.com/gorilla/handlers/LICENSE27
-rw-r--r--vendor/github.com/gorilla/handlers/Makefile34
-rw-r--r--vendor/github.com/gorilla/handlers/README.md56
-rw-r--r--vendor/github.com/gorilla/handlers/canonical.go73
-rw-r--r--vendor/github.com/gorilla/handlers/compress.go143
-rw-r--r--vendor/github.com/gorilla/handlers/cors.go352
-rw-r--r--vendor/github.com/gorilla/handlers/doc.go9
-rw-r--r--vendor/github.com/gorilla/handlers/handlers.go150
-rw-r--r--vendor/github.com/gorilla/handlers/logging.go246
-rw-r--r--vendor/github.com/gorilla/handlers/proxy_headers.go120
-rw-r--r--vendor/github.com/gorilla/handlers/recovery.go98
13 files changed, 0 insertions, 1330 deletions
diff --git a/vendor/github.com/gorilla/handlers/.editorconfig b/vendor/github.com/gorilla/handlers/.editorconfig
deleted file mode 100644
index c6b74c3e0..000000000
--- a/vendor/github.com/gorilla/handlers/.editorconfig
+++ /dev/null
@@ -1,20 +0,0 @@
-; 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 \ No newline at end of file
diff --git a/vendor/github.com/gorilla/handlers/.gitignore b/vendor/github.com/gorilla/handlers/.gitignore
deleted file mode 100644
index 577a89e81..000000000
--- a/vendor/github.com/gorilla/handlers/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-# Output of the go test coverage tool
-coverage.coverprofile
diff --git a/vendor/github.com/gorilla/handlers/LICENSE b/vendor/github.com/gorilla/handlers/LICENSE
deleted file mode 100644
index bb9d80bc9..000000000
--- a/vendor/github.com/gorilla/handlers/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-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:
-
- * 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.
-
-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.
diff --git a/vendor/github.com/gorilla/handlers/Makefile b/vendor/github.com/gorilla/handlers/Makefile
deleted file mode 100644
index 003b784f7..000000000
--- a/vendor/github.com/gorilla/handlers/Makefile
+++ /dev/null
@@ -1,34 +0,0 @@
-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 ./...
diff --git a/vendor/github.com/gorilla/handlers/README.md b/vendor/github.com/gorilla/handlers/README.md
deleted file mode 100644
index 02555b264..000000000
--- a/vendor/github.com/gorilla/handlers/README.md
+++ /dev/null
@@ -1,56 +0,0 @@
-# gorilla/handlers
-
-![Testing](https://github.com/gorilla/handlers/actions/workflows/test.yml/badge.svg)
-[![Codecov](https://codecov.io/github/gorilla/handlers/branch/main/graph/badge.svg)](https://codecov.io/github/gorilla/handlers)
-[![GoDoc](https://godoc.org/github.com/gorilla/handlers?status.svg)](https://godoc.org/github.com/gorilla/handlers)
-[![Sourcegraph](https://sourcegraph.com/github.com/gorilla/handlers/-/badge.svg)](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:
-
-* [**LoggingHandler**](https://godoc.org/github.com/gorilla/handlers#LoggingHandler) for logging HTTP requests in the Apache [Common Log
- Format](http://httpd.apache.org/docs/2.2/logs.html#common).
-* [**CombinedLoggingHandler**](https://godoc.org/github.com/gorilla/handlers#CombinedLoggingHandler) for logging HTTP requests in the Apache [Combined Log
- Format](http://httpd.apache.org/docs/2.2/logs.html#combined) commonly used by
- both Apache and nginx.
-* [**CompressHandler**](https://godoc.org/github.com/gorilla/handlers#CompressHandler) for gzipping responses.
-* [**ContentTypeHandler**](https://godoc.org/github.com/gorilla/handlers#ContentTypeHandler) for validating requests against a list of accepted
- content types.
-* [**MethodHandler**](https://godoc.org/github.com/gorilla/handlers#MethodHandler) for matching HTTP methods against handlers in a
- `map[string]http.Handler`
-* [**ProxyHeaders**](https://godoc.org/github.com/gorilla/handlers#ProxyHeaders) for populating `r.RemoteAddr` and `r.URL.Scheme` based on the
- `X-Forwarded-For`, `X-Real-IP`, `X-Forwarded-Proto` and RFC7239 `Forwarded`
- headers when running a Go server behind a HTTP reverse proxy.
-* [**CanonicalHost**](https://godoc.org/github.com/gorilla/handlers#CanonicalHost) for re-directing to the preferred host when handling multiple
- domains (i.e. multiple CNAME aliases).
-* [**RecoveryHandler**](https://godoc.org/github.com/gorilla/handlers#RecoveryHandler) for recovering from unexpected panics.
-
-Other handlers are documented [on the Gorilla
-website](https://www.gorillatoolkit.org/pkg/handlers).
-
-## Example
-
-A simple example using `handlers.LoggingHandler` and `handlers.CompressHandler`:
-
-```go
-import (
- "net/http"
- "github.com/gorilla/handlers"
-)
-
-func main() {
- r := http.NewServeMux()
-
- // Only log requests to our admin dashboard to stdout
- r.Handle("/admin", handlers.LoggingHandler(os.Stdout, http.HandlerFunc(ShowAdminDashboard)))
- r.HandleFunc("/", ShowIndex)
-
- // Wrap our server with our gzip handler to gzip compress all responses.
- http.ListenAndServe(":8000", handlers.CompressHandler(r))
-}
-```
-
-## License
-
-BSD licensed. See the included LICENSE file for details.
-
diff --git a/vendor/github.com/gorilla/handlers/canonical.go b/vendor/github.com/gorilla/handlers/canonical.go
deleted file mode 100644
index 7121f5307..000000000
--- a/vendor/github.com/gorilla/handlers/canonical.go
+++ /dev/null
@@ -1,73 +0,0 @@
-package handlers
-
-import (
- "net/http"
- "net/url"
- "strings"
-)
-
-type canonical struct {
- h http.Handler
- domain string
- code int
-}
-
-// CanonicalHost is HTTP middleware that re-directs requests to the canonical
-// domain. It accepts a domain and a status code (e.g. 301 or 302) and
-// re-directs clients to this domain. The existing request path is maintained.
-//
-// Note: If the provided domain is considered invalid by url.Parse or otherwise
-// returns an empty scheme or host, clients are not re-directed.
-//
-// Example:
-//
-// 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}
- }
-
- return fn
-}
-
-func (c canonical) ServeHTTP(w http.ResponseWriter, r *http.Request) {
- dest, err := url.Parse(c.domain)
- if err != nil {
- // Call the next handler if the provided domain fails to parse.
- c.h.ServeHTTP(w, r)
- return
- }
-
- if dest.Scheme == "" || dest.Host == "" {
- // Call the next handler if the scheme or host are empty.
- // Note that url.Parse won't fail on in this case.
- c.h.ServeHTTP(w, r)
- return
- }
-
- if !strings.EqualFold(cleanHost(r.Host), dest.Host) {
- // Re-build the destination URL
- dest := dest.Scheme + "://" + dest.Host + r.URL.Path
- if r.URL.RawQuery != "" {
- dest += "?" + r.URL.RawQuery
- }
- http.Redirect(w, r, dest, c.code)
- return
- }
-
- c.h.ServeHTTP(w, r)
-}
-
-// cleanHost cleans invalid Host headers by stripping anything after '/' or ' '.
-// This is backported from Go 1.5 (in response to issue #11206) and attempts to
-// mitigate malformed Host headers that do not match the format in RFC7230.
-func cleanHost(in string) string {
- if i := strings.IndexAny(in, " /"); i != -1 {
- return in[:i]
- }
- return in
-}
diff --git a/vendor/github.com/gorilla/handlers/compress.go b/vendor/github.com/gorilla/handlers/compress.go
deleted file mode 100644
index d6f589503..000000000
--- a/vendor/github.com/gorilla/handlers/compress.go
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright 2013 The Gorilla Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package handlers
-
-import (
- "compress/flate"
- "compress/gzip"
- "io"
- "net/http"
- "strings"
-
- "github.com/felixge/httpsnoop"
-)
-
-const acceptEncoding string = "Accept-Encoding"
-
-type compressResponseWriter struct {
- compressor io.Writer
- w http.ResponseWriter
-}
-
-func (cw *compressResponseWriter) WriteHeader(c int) {
- cw.w.Header().Del("Content-Length")
- cw.w.WriteHeader(c)
-}
-
-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 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 (cw *compressResponseWriter) Flush() {
- // Flush compressed data if compressor supports it.
- if f, ok := cw.compressor.(flusher); ok {
- _ = f.Flush()
- }
- // Flush HTTP response.
- if f, ok := cw.w.(http.Flusher); ok {
- f.Flush()
- }
-}
-
-// CompressHandler gzip compresses HTTP responses for clients that support it
-// via the 'Accept-Encoding' header.
-//
-// Compressing TLS traffic may leak the page contents to an attacker if the
-// page contains user input: http://security.stackexchange.com/a/102015/12208
-func CompressHandler(h http.Handler) http.Handler {
- return CompressHandlerLevel(h, gzip.DefaultCompression)
-}
-
-// CompressHandlerLevel gzip compresses HTTP responses with specified compression level
-// for clients that support it via the 'Accept-Encoding' header.
-//
-// The compression level should be gzip.DefaultCompression, gzip.NoCompression,
-// or any integer value between gzip.BestSpeed and gzip.BestCompression inclusive.
-// gzip.DefaultCompression is used in case of invalid compression level.
-func CompressHandlerLevel(h http.Handler, level int) http.Handler {
- if level < gzip.DefaultCompression || level > gzip.BestCompression {
- level = gzip.DefaultCompression
- }
-
- const (
- gzipEncoding = "gzip"
- flateEncoding = "deflate"
- )
-
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- // 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)
- })
-}
diff --git a/vendor/github.com/gorilla/handlers/cors.go b/vendor/github.com/gorilla/handlers/cors.go
deleted file mode 100644
index 8af9c096e..000000000
--- a/vendor/github.com/gorilla/handlers/cors.go
+++ /dev/null
@@ -1,352 +0,0 @@
-package handlers
-
-import (
- "net/http"
- "strconv"
- "strings"
-)
-
-// CORSOption represents a functional option for configuring the CORS middleware.
-type CORSOption func(*cors) error
-
-type cors struct {
- h http.Handler
- allowedHeaders []string
- allowedMethods []string
- allowedOrigins []string
- allowedOriginValidator OriginValidator
- exposedHeaders []string
- maxAge int
- ignoreOptions bool
- allowCredentials bool
- optionStatusCode int
-}
-
-// OriginValidator takes an origin string and returns whether or not that origin is allowed.
-type OriginValidator func(string) bool
-
-var (
- 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).
-)
-
-const (
- corsOptionMethod string = http.MethodOptions
- corsAllowOriginHeader string = "Access-Control-Allow-Origin"
- corsExposeHeadersHeader string = "Access-Control-Expose-Headers"
- corsMaxAgeHeader string = "Access-Control-Max-Age"
- corsAllowMethodsHeader string = "Access-Control-Allow-Methods"
- corsAllowHeadersHeader string = "Access-Control-Allow-Headers"
- corsAllowCredentialsHeader string = "Access-Control-Allow-Credentials"
- corsRequestMethodHeader string = "Access-Control-Request-Method"
- corsRequestHeadersHeader string = "Access-Control-Request-Headers"
- corsOriginHeader string = "Origin"
- corsVaryHeader string = "Vary"
- corsOriginMatchAll string = "*"
-)
-
-func (ch *cors) ServeHTTP(w http.ResponseWriter, r *http.Request) {
- origin := r.Header.Get(corsOriginHeader)
- if !ch.isOriginAllowed(origin) {
- if r.Method != corsOptionMethod || ch.ignoreOptions {
- ch.h.ServeHTTP(w, r)
- }
-
- return
- }
-
- if r.Method == corsOptionMethod {
- if ch.ignoreOptions {
- ch.h.ServeHTTP(w, r)
- return
- }
-
- if _, ok := r.Header[corsRequestMethodHeader]; !ok {
- w.WriteHeader(http.StatusBadRequest)
- return
- }
-
- method := r.Header.Get(corsRequestMethodHeader)
- if !ch.isMatch(method, ch.allowedMethods) {
- w.WriteHeader(http.StatusMethodNotAllowed)
- return
- }
-
- requestHeaders := strings.Split(r.Header.Get(corsRequestHeadersHeader), ",")
- allowedHeaders := []string{}
- for _, v := range requestHeaders {
- canonicalHeader := http.CanonicalHeaderKey(strings.TrimSpace(v))
- if canonicalHeader == "" || ch.isMatch(canonicalHeader, defaultCorsHeaders) {
- continue
- }
-
- if !ch.isMatch(canonicalHeader, ch.allowedHeaders) {
- w.WriteHeader(http.StatusForbidden)
- return
- }
-
- allowedHeaders = append(allowedHeaders, canonicalHeader)
- }
-
- if len(allowedHeaders) > 0 {
- w.Header().Set(corsAllowHeadersHeader, strings.Join(allowedHeaders, ","))
- }
-
- if ch.maxAge > 0 {
- w.Header().Set(corsMaxAgeHeader, strconv.Itoa(ch.maxAge))
- }
-
- if !ch.isMatch(method, defaultCorsMethods) {
- w.Header().Set(corsAllowMethodsHeader, method)
- }
- } else if len(ch.exposedHeaders) > 0 {
- w.Header().Set(corsExposeHeadersHeader, strings.Join(ch.exposedHeaders, ","))
- }
-
- if ch.allowCredentials {
- w.Header().Set(corsAllowCredentialsHeader, "true")
- }
-
- if len(ch.allowedOrigins) > 1 {
- w.Header().Set(corsVaryHeader, corsOriginHeader)
- }
-
- returnOrigin := origin
- if ch.allowedOriginValidator == nil && len(ch.allowedOrigins) == 0 {
- returnOrigin = "*"
- } else {
- for _, o := range ch.allowedOrigins {
- // A configuration of * is different than explicitly setting an allowed
- // origin. Returning arbitrary origin headers in an access control allow
- // origin header is unsafe and is not required by any use case.
- if o == corsOriginMatchAll {
- returnOrigin = "*"
- break
- }
- }
- }
- w.Header().Set(corsAllowOriginHeader, returnOrigin)
-
- if r.Method == corsOptionMethod {
- w.WriteHeader(ch.optionStatusCode)
- return
- }
- ch.h.ServeHTTP(w, r)
-}
-
-// CORS provides Cross-Origin Resource Sharing middleware.
-// Example:
-//
-// import (
-// "net/http"
-//
-// "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 CORS(opts ...CORSOption) func(http.Handler) http.Handler {
- return func(h http.Handler) http.Handler {
- ch := parseCORSOptions(opts...)
- ch.h = h
- return ch
- }
-}
-
-func parseCORSOptions(opts ...CORSOption) *cors {
- ch := &cors{
- allowedMethods: defaultCorsMethods,
- allowedHeaders: defaultCorsHeaders,
- allowedOrigins: []string{},
- optionStatusCode: defaultCorsOptionStatusCode,
- }
-
- for _, option := range opts {
- _ = option(ch) //TODO: @bharat-rajani, return error to caller if not nil?
- }
-
- return ch
-}
-
-//
-// Functional options for configuring CORS.
-//
-
-// AllowedHeaders adds the provided headers to the list of allowed headers in a
-// CORS request.
-// This is an append operation so the headers Accept, Accept-Language,
-// and Content-Language are always allowed.
-// Content-Type must be explicitly declared if accepting Content-Types other than
-// application/x-www-form-urlencoded, multipart/form-data, or text/plain.
-func AllowedHeaders(headers []string) CORSOption {
- return func(ch *cors) error {
- for _, v := range headers {
- normalizedHeader := http.CanonicalHeaderKey(strings.TrimSpace(v))
- if normalizedHeader == "" {
- continue
- }
-
- if !ch.isMatch(normalizedHeader, ch.allowedHeaders) {
- ch.allowedHeaders = append(ch.allowedHeaders, normalizedHeader)
- }
- }
-
- return nil
- }
-}
-
-// AllowedMethods can be used to explicitly allow methods in the
-// Access-Control-Allow-Methods header.
-// This is a replacement operation so you must also
-// pass GET, HEAD, and POST if you wish to support those methods.
-func AllowedMethods(methods []string) CORSOption {
- return func(ch *cors) error {
- ch.allowedMethods = []string{}
- for _, v := range methods {
- normalizedMethod := strings.ToUpper(strings.TrimSpace(v))
- if normalizedMethod == "" {
- continue
- }
-
- if !ch.isMatch(normalizedMethod, ch.allowedMethods) {
- ch.allowedMethods = append(ch.allowedMethods, normalizedMethod)
- }
- }
-
- return nil
- }
-}
-
-// AllowedOrigins sets the allowed origins for CORS requests, as used in the
-// 'Allow-Access-Control-Origin' HTTP header.
-// Note: Passing in a []string{"*"} will allow any domain.
-func AllowedOrigins(origins []string) CORSOption {
- return func(ch *cors) error {
- for _, v := range origins {
- if v == corsOriginMatchAll {
- ch.allowedOrigins = []string{corsOriginMatchAll}
- return nil
- }
- }
-
- ch.allowedOrigins = origins
- return nil
- }
-}
-
-// AllowedOriginValidator sets a function for evaluating allowed origins in CORS requests, represented by the
-// 'Allow-Access-Control-Origin' HTTP header.
-func AllowedOriginValidator(fn OriginValidator) CORSOption {
- return func(ch *cors) error {
- ch.allowedOriginValidator = fn
- return nil
- }
-}
-
-// OptionStatusCode sets a custom status code on the OPTIONS requests.
-// Default behaviour sets it to 200 to reflect best practices. This is option is not mandatory
-// and can be used if you need a custom status code (i.e 204).
-//
-// More informations on the spec:
-// https://fetch.spec.whatwg.org/#cors-preflight-fetch
-func OptionStatusCode(code int) CORSOption {
- return func(ch *cors) error {
- ch.optionStatusCode = code
- return nil
- }
-}
-
-// ExposedHeaders can be used to specify headers that are available
-// and will not be stripped out by the user-agent.
-func ExposedHeaders(headers []string) CORSOption {
- return func(ch *cors) error {
- ch.exposedHeaders = []string{}
- for _, v := range headers {
- normalizedHeader := http.CanonicalHeaderKey(strings.TrimSpace(v))
- if normalizedHeader == "" {
- continue
- }
-
- if !ch.isMatch(normalizedHeader, ch.exposedHeaders) {
- ch.exposedHeaders = append(ch.exposedHeaders, normalizedHeader)
- }
- }
-
- return nil
- }
-}
-
-// MaxAge determines the maximum age (in seconds) between preflight requests. A
-// maximum of 10 minutes is allowed. An age above this value will default to 10
-// minutes.
-func MaxAge(age int) CORSOption {
- return func(ch *cors) error {
- // Maximum of 10 minutes.
- if age > 600 {
- age = 600
- }
-
- ch.maxAge = age
- return nil
- }
-}
-
-// IgnoreOptions causes the CORS middleware to ignore OPTIONS requests, instead
-// passing them through to the next handler. This is useful when your application
-// or framework has a pre-existing mechanism for responding to OPTIONS requests.
-func IgnoreOptions() CORSOption {
- return func(ch *cors) error {
- ch.ignoreOptions = true
- return nil
- }
-}
-
-// AllowCredentials can be used to specify that the user agent may pass
-// authentication details along with the request.
-func AllowCredentials() CORSOption {
- return func(ch *cors) error {
- ch.allowCredentials = true
- return nil
- }
-}
-
-func (ch *cors) isOriginAllowed(origin string) bool {
- if origin == "" {
- return false
- }
-
- if ch.allowedOriginValidator != nil {
- return ch.allowedOriginValidator(origin)
- }
-
- if len(ch.allowedOrigins) == 0 {
- return true
- }
-
- for _, allowedOrigin := range ch.allowedOrigins {
- if allowedOrigin == origin || allowedOrigin == corsOriginMatchAll {
- return true
- }
- }
-
- return false
-}
-
-func (ch *cors) isMatch(needle string, haystack []string) bool {
- for _, v := range haystack {
- if v == needle {
- return true
- }
- }
-
- return false
-}
diff --git a/vendor/github.com/gorilla/handlers/doc.go b/vendor/github.com/gorilla/handlers/doc.go
deleted file mode 100644
index 944e5a8ae..000000000
--- a/vendor/github.com/gorilla/handlers/doc.go
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
-Package handlers is a collection of handlers (aka "HTTP middleware") for use
-with Go's net/http package (or any framework supporting http.Handler).
-
-The package includes handlers for logging in standardised formats, compressing
-HTTP responses, validating content types and other useful tools for manipulating
-requests and responses.
-*/
-package handlers
diff --git a/vendor/github.com/gorilla/handlers/handlers.go b/vendor/github.com/gorilla/handlers/handlers.go
deleted file mode 100644
index 9b92fce33..000000000
--- a/vendor/github.com/gorilla/handlers/handlers.go
+++ /dev/null
@@ -1,150 +0,0 @@
-// Copyright 2013 The Gorilla Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package handlers
-
-import (
- "bufio"
- "fmt"
- "net"
- "net/http"
- "sort"
- "strings"
-)
-
-// MethodHandler is an http.Handler that dispatches to a handler whose key in the
-// MethodHandler's map matches the name of the HTTP request's method, eg: GET
-//
-// If the request's method is OPTIONS and OPTIONS is not a key in the map then
-// the handler responds with a status of 200 and sets the Allow header to a
-// comma-separated list of available methods.
-//
-// If the request's method doesn't match any of its keys the handler responds
-// with a status of HTTP 405 "Method Not Allowed" and sets the Allow header to a
-// comma-separated list of available methods.
-type MethodHandler map[string]http.Handler
-
-func (h MethodHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
- if handler, ok := h[req.Method]; ok {
- handler.ServeHTTP(w, req)
- } else {
- allow := []string{}
- for k := range h {
- allow = append(allow, k)
- }
- sort.Strings(allow)
- w.Header().Set("Allow", strings.Join(allow, ", "))
- if req.Method == http.MethodOptions {
- w.WriteHeader(http.StatusOK)
- } else {
- http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
- }
- }
-}
-
-// responseLogger is wrapper of http.ResponseWriter that keeps track of its HTTP
-// status code and body size.
-type responseLogger struct {
- w http.ResponseWriter
- status int
- size int
-}
-
-func (l *responseLogger) Write(b []byte) (int, error) {
- size, err := l.w.Write(b)
- l.size += size
- return size, err
-}
-
-func (l *responseLogger) WriteHeader(s int) {
- l.w.WriteHeader(s)
- l.status = s
-}
-
-func (l *responseLogger) Status() int {
- return l.status
-}
-
-func (l *responseLogger) Size() int {
- return l.size
-}
-
-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.status = http.StatusSwitchingProtocols
- }
- return conn, rw, err
-}
-
-// 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 {
- ct := h.Get("Content-Type")
- if i := strings.IndexRune(ct, ';'); i != -1 {
- ct = ct[0:i]
- }
- return ct == contentType
-}
-
-// ContentTypeHandler wraps and returns a http.Handler, validating the request
-// content type is compatible with the contentTypes list. It writes a HTTP 415
-// error if that fails.
-//
-// 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 == http.MethodPut || r.Method == http.MethodPost || r.Method == http.MethodPatch) {
- h.ServeHTTP(w, r)
- return
- }
-
- for _, ct := range contentTypes {
- if isContentType(r.Header, ct) {
- h.ServeHTTP(w, r)
- return
- }
- }
- http.Error(w, fmt.Sprintf("Unsupported content type %q; expected one of %q",
- r.Header.Get("Content-Type"),
- contentTypes),
- http.StatusUnsupportedMediaType)
- })
-}
-
-const (
- // HTTPMethodOverrideHeader is a commonly used
- // http header to override a request method.
- HTTPMethodOverrideHeader = "X-HTTP-Method-Override"
- // HTTPMethodOverrideFormKey is a commonly used
- // HTML form key to override a request method.
- HTTPMethodOverrideFormKey = "_method"
-)
-
-// HTTPMethodOverrideHandler wraps and returns a http.Handler which checks for
-// the X-HTTP-Method-Override header or the _method form key, and overrides (if
-// valid) request.Method with its value.
-//
-// This is especially useful for HTTP clients that don't support many http verbs.
-// It isn't secure to override e.g a GET to a POST, so only POST requests are
-// considered. Likewise, the override method can only be a "write" method: PUT,
-// PATCH or DELETE.
-//
-// 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 == http.MethodPost {
- om := r.FormValue(HTTPMethodOverrideFormKey)
- if om == "" {
- om = r.Header.Get(HTTPMethodOverrideHeader)
- }
- if om == http.MethodPut || om == http.MethodPatch || om == http.MethodDelete {
- r.Method = om
- }
- }
- h.ServeHTTP(w, r)
- })
-}
diff --git a/vendor/github.com/gorilla/handlers/logging.go b/vendor/github.com/gorilla/handlers/logging.go
deleted file mode 100644
index 2badb6fbf..000000000
--- a/vendor/github.com/gorilla/handlers/logging.go
+++ /dev/null
@@ -1,246 +0,0 @@
-// Copyright 2013 The Gorilla Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package handlers
-
-import (
- "io"
- "net"
- "net/http"
- "net/url"
- "strconv"
- "time"
- "unicode/utf8"
-
- "github.com/felixge/httpsnoop"
-)
-
-// Logging
-
-// LogFormatterParams is the structure any formatter will be handed when time to log comes.
-type LogFormatterParams struct {
- Request *http.Request
- URL url.URL
- TimeStamp time.Time
- StatusCode int
- Size int
-}
-
-// 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
-// friends
-
-type loggingHandler struct {
- writer io.Writer
- handler http.Handler
- formatter LogFormatter
-}
-
-func (h loggingHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
- t := time.Now()
- logger, w := makeLogger(w)
- url := *req.URL
-
- h.handler.ServeHTTP(w, req)
- if req.MultipartForm != nil {
- err := req.MultipartForm.RemoveAll()
- if err != nil {
- return
- }
- }
-
- params := LogFormatterParams{
- Request: req,
- URL: url,
- TimeStamp: t,
- StatusCode: logger.Status(),
- Size: logger.Size(),
- }
-
- h.formatter(h.writer, params)
-}
-
-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:] { //nolint: wastedassign //TODO: why width starts from 0and reassigned as 1
- r := rune(s[0])
- width = 1
- if r >= utf8.RuneSelf {
- r, width = utf8.DecodeRuneInString(s)
- }
- if width == 1 && r == utf8.RuneError {
- buf = append(buf, `\x`...)
- buf = append(buf, lowerhex[s[0]>>4])
- buf = append(buf, lowerhex[s[0]&0xF])
- continue
- }
- if r == rune('"') || r == '\\' { // always backslashed
- buf = append(buf, '\\')
- buf = append(buf, byte(r))
- continue
- }
- if strconv.IsPrint(r) {
- n := utf8.EncodeRune(runeTmp[:], r)
- buf = append(buf, runeTmp[:n]...)
- continue
- }
- switch r {
- case '\a':
- buf = append(buf, `\a`...)
- case '\b':
- buf = append(buf, `\b`...)
- case '\f':
- buf = append(buf, `\f`...)
- case '\n':
- buf = append(buf, `\n`...)
- case '\r':
- buf = append(buf, `\r`...)
- case '\t':
- buf = append(buf, `\t`...)
- case '\v':
- buf = append(buf, `\v`...)
- default:
- switch {
- case r < ' ':
- buf = append(buf, `\x`...)
- buf = append(buf, lowerhex[s[0]>>4])
- buf = append(buf, lowerhex[s[0]&0xF])
- case r > utf8.MaxRune:
- r = 0xFFFD
- fallthrough
- case r < 0x10000:
- buf = append(buf, `\u`...)
- for s := 12; s >= 0; s -= 4 {
- buf = append(buf, lowerhex[r>>uint(s)&0xF])
- }
- default:
- buf = append(buf, `\U`...)
- for s := 28; s >= 0; s -= 4 {
- buf = append(buf, lowerhex[r>>uint(s)&0xF])
- }
- }
- }
- }
- return buf
-}
-
-// buildCommonLogLine builds a log entry for req in Apache Common Log Format.
-// ts is the timestamp with which the entry should be logged.
-// status and size are used to provide the response HTTP status and size.
-func buildCommonLogLine(req *http.Request, url url.URL, ts time.Time, status int, size int) []byte {
- username := "-"
- if url.User != nil {
- if name := url.User.Username(); name != "" {
- username = name
- }
- }
-
- host, _, err := net.SplitHostPort(req.RemoteAddr)
- if err != nil {
- host = req.RemoteAddr
- }
-
- uri := req.RequestURI
-
- // Requests using the CONNECT method over HTTP/2.0 must use
- // the authority field (aka r.Host) to identify the target.
- // Refer: https://httpwg.github.io/specs/rfc7540.html#CONNECT
- if req.ProtoMajor == 2 && req.Method == "CONNECT" {
- uri = req.Host
- }
- if uri == "" {
- uri = url.RequestURI()
- }
-
- buf := make([]byte, 0, 3*(len(host)+len(username)+len(req.Method)+len(uri)+len(req.Proto)+50)/2)
- buf = append(buf, host...)
- buf = append(buf, " - "...)
- buf = append(buf, username...)
- buf = append(buf, " ["...)
- buf = append(buf, ts.Format("02/Jan/2006:15:04:05 -0700")...)
- buf = append(buf, `] "`...)
- buf = append(buf, req.Method...)
- buf = append(buf, " "...)
- buf = appendQuoted(buf, uri)
- buf = append(buf, " "...)
- buf = append(buf, req.Proto...)
- buf = append(buf, `" `...)
- buf = append(buf, strconv.Itoa(status)...)
- buf = append(buf, " "...)
- buf = append(buf, strconv.Itoa(size)...)
- return buf
-}
-
-// writeLog writes a log entry for req to w in Apache Common Log Format.
-// ts is the timestamp with which the entry should be logged.
-// status and size are used to provide the response HTTP status and size.
-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)
-}
-
-// writeCombinedLog writes a log entry for req to w in Apache Combined Log Format.
-// ts is the timestamp with which the entry should be logged.
-// status and size are used to provide the response HTTP status and size.
-func writeCombinedLog(writer io.Writer, params LogFormatterParams) {
- buf := buildCommonLogLine(params.Request, params.URL, params.TimeStamp, params.StatusCode, params.Size)
- buf = append(buf, ` "`...)
- buf = appendQuoted(buf, params.Request.Referer())
- buf = append(buf, `" "`...)
- buf = appendQuoted(buf, params.Request.UserAgent())
- buf = append(buf, '"', '\n')
- _, _ = writer.Write(buf)
-}
-
-// CombinedLoggingHandler return a http.Handler that wraps h and logs requests to out in
-// Apache Combined Log Format.
-//
-// 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 -.
-func CombinedLoggingHandler(out io.Writer, h http.Handler) http.Handler {
- return loggingHandler{out, h, writeCombinedLog}
-}
-
-// LoggingHandler return a http.Handler that wraps h and logs requests to out in
-// Apache Common Log Format (CLF).
-//
-// See http://httpd.apache.org/docs/2.2/logs.html#common for a description of this format.
-//
-// LoggingHandler always sets the ident field of the log to -
-//
-// 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)
-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.
-func CustomLoggingHandler(out io.Writer, h http.Handler, f LogFormatter) http.Handler {
- return loggingHandler{out, h, f}
-}
diff --git a/vendor/github.com/gorilla/handlers/proxy_headers.go b/vendor/github.com/gorilla/handlers/proxy_headers.go
deleted file mode 100644
index 281d753e9..000000000
--- a/vendor/github.com/gorilla/handlers/proxy_headers.go
+++ /dev/null
@@ -1,120 +0,0 @@
-package handlers
-
-import (
- "net/http"
- "regexp"
- "strings"
-)
-
-var (
- // De-facto standard header keys.
- xForwardedFor = http.CanonicalHeaderKey("X-Forwarded-For")
- xForwardedHost = http.CanonicalHeaderKey("X-Forwarded-Host")
- xForwardedProto = http.CanonicalHeaderKey("X-Forwarded-Proto")
- xForwardedScheme = http.CanonicalHeaderKey("X-Forwarded-Scheme")
- xRealIP = http.CanonicalHeaderKey("X-Real-IP")
-)
-
-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.
- 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.
- forRegex = regexp.MustCompile(`(?i)(?:for=)([^(;|,| )]+)`)
- // Allows for a sub-match for the first instance of scheme (http|https)
- // prefixed by 'proto='. The match is case-insensitive.
- protoRegex = regexp.MustCompile(`(?i)(?:proto=)(https|http)`)
-)
-
-// ProxyHeaders inspects common reverse proxy headers and sets the corresponding
-// fields in the HTTP request struct. These are X-Forwarded-For and X-Real-IP
-// for the remote (client) IP address, X-Forwarded-Proto or X-Forwarded-Scheme
-// for the scheme (http|https), X-Forwarded-Host for the host and the RFC7239
-// Forwarded header, which may include both client IPs and schemes.
-//
-// NOTE: This middleware should only be used when behind a reverse
-// proxy like nginx, HAProxy or Apache. Reverse proxies that don't (or are
-// configured not to) strip these headers from client requests, or where these
-// headers are accepted "as is" from a remote client (e.g. when Go is not behind
-// a proxy), can manifest as a vulnerability if your application uses these
-// headers for validating the 'trustworthiness' of a request.
-func ProxyHeaders(h http.Handler) http.Handler {
- fn := func(w http.ResponseWriter, r *http.Request) {
- // Set the remote IP with the value passed from the proxy.
- if fwd := getIP(r); fwd != "" {
- r.RemoteAddr = fwd
- }
-
- // Set the scheme (proto) with the value passed from the proxy.
- if scheme := getScheme(r); scheme != "" {
- r.URL.Scheme = scheme
- }
- // Set the host with the value passed by the proxy
- if r.Header.Get(xForwardedHost) != "" {
- r.Host = r.Header.Get(xForwardedHost)
- }
- // Call the next handler in the chain.
- h.ServeHTTP(w, r)
- }
-
- return http.HandlerFunc(fn)
-}
-
-// getIP retrieves the IP from the X-Forwarded-For, X-Real-IP and RFC7239
-// Forwarded headers (in that order).
-func getIP(r *http.Request) string {
- var addr string
-
- 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.
- s := strings.Index(fwd, ", ")
- if s == -1 {
- s = len(fwd)
- }
- addr = fwd[:s]
- 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(r.Header.Get(forwarded)); len(match) > 1 {
- // IPv6 addresses in Forwarded headers are quoted-strings. We strip
- // these quotes.
- addr = strings.Trim(match[1], `"`)
- }
- }
-
- return addr
-}
-
-// getScheme retrieves the scheme from the X-Forwarded-Proto and RFC7239
-// Forwarded headers (in that order).
-func getScheme(r *http.Request) string {
- var scheme string
-
- // Retrieve the scheme from X-Forwarded-Proto.
- if proto := r.Header.Get(xForwardedProto); proto != "" {
- scheme = strings.ToLower(proto)
- } else if proto = r.Header.Get(xForwardedScheme); proto != "" {
- scheme = strings.ToLower(proto)
- } else if proto = r.Header.Get(forwarded); proto != "" {
- // match should contain at least two elements if the protocol was
- // specified in the Forwarded header. The first element will always be
- // the 'proto=' capture, which we ignore. In the case of multiple proto
- // parameters (invalid) we only extract the first.
- if match := protoRegex.FindStringSubmatch(proto); len(match) > 1 {
- scheme = strings.ToLower(match[1])
- }
- }
-
- return scheme
-}
diff --git a/vendor/github.com/gorilla/handlers/recovery.go b/vendor/github.com/gorilla/handlers/recovery.go
deleted file mode 100644
index 0d4f955ec..000000000
--- a/vendor/github.com/gorilla/handlers/recovery.go
+++ /dev/null
@@ -1,98 +0,0 @@
-package handlers
-
-import (
- "log"
- "net/http"
- "runtime/debug"
-)
-
-// RecoveryHandlerLogger is an interface used by the recovering handler to print logs.
-type RecoveryHandlerLogger interface {
- Println(...interface{})
-}
-
-type recoveryHandler struct {
- handler http.Handler
- logger RecoveryHandlerLogger
- printStack bool
-}
-
-// RecoveryOption provides a functional approach to define
-// configuration for a handler; such as setting the logging
-// whether or not to print stack traces on panic.
-type RecoveryOption func(http.Handler)
-
-func parseRecoveryOptions(h http.Handler, opts ...RecoveryOption) http.Handler {
- for _, option := range opts {
- option(h)
- }
-
- return h
-}
-
-// RecoveryHandler is HTTP middleware that recovers from a panic,
-// logs the panic, writes http.StatusInternalServerError, and
-// continues to the next handler.
-//
-// Example:
-//
-// r := mux.NewRouter()
-// r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
-// panic("Unexpected error!")
-// })
-//
-// 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}
- return parseRecoveryOptions(r, opts...)
- }
-}
-
-// RecoveryLogger is a functional option to override
-// the default logger.
-func RecoveryLogger(logger RecoveryHandlerLogger) RecoveryOption {
- return func(h http.Handler) {
- 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(shouldPrint bool) RecoveryOption {
- return func(h http.Handler) {
- r := h.(*recoveryHandler) //nolint:errcheck //TODO:
- // @bharat-rajani should return type-assertion error but would break the API?
- r.printStack = shouldPrint
- }
-}
-
-func (h recoveryHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
- defer func() {
- if err := recover(); err != nil {
- w.WriteHeader(http.StatusInternalServerError)
- h.log(err)
- }
- }()
-
- h.handler.ServeHTTP(w, req)
-}
-
-func (h recoveryHandler) log(v ...interface{}) {
- if h.logger != nil {
- h.logger.Println(v...)
- } else {
- log.Println(v...)
- }
-
- if h.printStack {
- stack := string(debug.Stack())
- if h.logger != nil {
- h.logger.Println(stack)
- } else {
- log.Println(stack)
- }
- }
-}