summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/go-chi/chi
diff options
context:
space:
mode:
authorLunny Xiao <xiaolunwen@gmail.com>2021-01-05 21:05:40 +0800
committerGitHub <noreply@github.com>2021-01-05 21:05:40 +0800
commit15a475b7dbcf7923d9518dff7764b20e404eb774 (patch)
tree8789f1f82c5e41345b442df4e58120bdd5f8bade /vendor/github.com/go-chi/chi
parent126c9331d6d8789563fae5d5bac2196d63fee0e8 (diff)
downloadgitea-15a475b7dbcf7923d9518dff7764b20e404eb774.tar.gz
gitea-15a475b7dbcf7923d9518dff7764b20e404eb774.zip
Fix recovery middleware to render gitea style page. (#13857)
* Some changes to fix recovery * Move Recovery to middlewares * Remove trace code * Fix lint * add session middleware and remove dependent on macaron for sso * Fix panic 500 page rendering * Fix bugs * Fix fmt * Fix vendor * recover unnecessary change * Fix lint and addd some comments about the copied codes. * Use util.StatDir instead of com.StatDir Co-authored-by: 6543 <6543@obermui.de>
Diffstat (limited to 'vendor/github.com/go-chi/chi')
-rw-r--r--vendor/github.com/go-chi/chi/.travis.yml20
-rw-r--r--vendor/github.com/go-chi/chi/CHANGELOG.md62
-rw-r--r--vendor/github.com/go-chi/chi/README.md63
-rw-r--r--vendor/github.com/go-chi/chi/context.go54
-rw-r--r--vendor/github.com/go-chi/chi/middleware/basic_auth.go3
-rw-r--r--vendor/github.com/go-chi/chi/middleware/clean_path.go28
-rw-r--r--vendor/github.com/go-chi/chi/middleware/content_type.go14
-rw-r--r--vendor/github.com/go-chi/chi/middleware/logger.go21
-rw-r--r--vendor/github.com/go-chi/chi/middleware/strip.go14
-rw-r--r--vendor/github.com/go-chi/chi/middleware/url_format.go2
-rw-r--r--vendor/github.com/go-chi/chi/mux.go46
11 files changed, 230 insertions, 97 deletions
diff --git a/vendor/github.com/go-chi/chi/.travis.yml b/vendor/github.com/go-chi/chi/.travis.yml
deleted file mode 100644
index 7b8e26bcee..0000000000
--- a/vendor/github.com/go-chi/chi/.travis.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-language: go
-
-go:
- - 1.10.x
- - 1.11.x
- - 1.12.x
- - 1.13.x
- - 1.14.x
-
-script:
- - go get -d -t ./...
- - go vet ./...
- - go test ./...
- - >
- go_version=$(go version);
- if [ ${go_version:13:4} = "1.12" ]; then
- go get -u golang.org/x/tools/cmd/goimports;
- goimports -d -e ./ | grep '.*' && { echo; echo "Aborting due to non-empty goimports output."; exit 1; } || :;
- fi
-
diff --git a/vendor/github.com/go-chi/chi/CHANGELOG.md b/vendor/github.com/go-chi/chi/CHANGELOG.md
index 9a64a72eec..2e337506a4 100644
--- a/vendor/github.com/go-chi/chi/CHANGELOG.md
+++ b/vendor/github.com/go-chi/chi/CHANGELOG.md
@@ -1,5 +1,66 @@
# Changelog
+## v1.5.1 (2020-12-06)
+
+- Performance improvement: removing 1 allocation by foregoing context.WithValue, thank you @bouk for
+ your contribution (https://github.com/go-chi/chi/pull/555). Note: new benchmarks posted in README.
+- `middleware.CleanPath`: new middleware that clean's request path of double slashes
+- deprecate & remove `chi.ServerBaseContext` in favour of stdlib `http.Server#BaseContext`
+- plus other tiny improvements, see full commit history below
+- History of changes: see https://github.com/go-chi/chi/compare/v4.1.2...v1.5.1
+
+
+## v1.5.0 (2020-11-12) - now with go.mod support
+
+`chi` dates back to 2016 with it's original implementation as one of the first routers to adopt the newly introduced
+context.Context api to the stdlib -- set out to design a router that is faster, more modular and simpler than anything
+else out there -- while not introducing any custom handler types or dependencies. Today, `chi` still has zero dependencies,
+and in many ways is future proofed from changes, given it's minimal nature. Between versions, chi's iterations have been very
+incremental, with the architecture and api being the same today as it was originally designed in 2016. For this reason it
+makes chi a pretty easy project to maintain, as well thanks to the many amazing community contributions over the years
+to who all help make chi better (total of 86 contributors to date -- thanks all!).
+
+Chi has been an labour of love, art and engineering, with the goals to offer beautiful ergonomics, flexibility, performance
+and simplicity when building HTTP services with Go. I've strived to keep the router very minimal in surface area / code size,
+and always improving the code wherever possible -- and as of today the `chi` package is just 1082 lines of code (not counting
+middlewares, which are all optional). As well, I don't have the exact metrics, but from my analysis and email exchanges from
+companies and developers, chi is used by thousands of projects around the world -- thank you all as there is no better form of
+joy for me than to have art I had started be helpful and enjoyed by others. And of course I use chi in all of my own projects too :)
+
+For me, the asthetics of chi's code and usage are very important. With the introduction of Go's module support
+(which I'm a big fan of), chi's past versioning scheme choice to v2, v3 and v4 would mean I'd require the import path
+of "github.com/go-chi/chi/v4", leading to the lengthy discussion at https://github.com/go-chi/chi/issues/462.
+Haha, to some, you may be scratching your head why I've spent > 1 year stalling to adopt "/vXX" convention in the import
+path -- which isn't horrible in general -- but for chi, I'm unable to accept it as I strive for perfection in it's API design,
+aesthetics and simplicity. It just doesn't feel good to me given chi's simple nature -- I do not foresee a "v5" or "v6",
+and upgrading between versions in the future will also be just incremental.
+
+I do understand versioning is a part of the API design as well, which is why the solution for a while has been to "do nothing",
+as Go supports both old and new import paths with/out go.mod. However, now that Go module support has had time to iron out kinks and
+is adopted everywhere, it's time for chi to get with the times. Luckily, I've discovered a path forward that will make me happy,
+while also not breaking anyone's app who adopted a prior versioning from tags in v2/v3/v4. I've made an experimental release of
+v1.5.0 with go.mod silently, and tested it with new and old projects, to ensure the developer experience is preserved, and it's
+largely unnoticed. Fortunately, Go's toolchain will check the tags of a repo and consider the "latest" tag the one with go.mod.
+However, you can still request a specific older tag such as v4.1.2, and everything will "just work". But new users can just
+`go get github.com/go-chi/chi` or `go get github.com/go-chi/chi@latest` and they will get the latest version which contains
+go.mod support, which is v1.5.0+. `chi` will not change very much over the years, just like it hasn't changed much from 4 years ago.
+Therefore, we will stay on v1.x from here on, starting from v1.5.0. Any breaking changes will bump a "minor" release and
+backwards-compatible improvements/fixes will bump a "tiny" release.
+
+For existing projects who want to upgrade to the latest go.mod version, run: `go get -u github.com/go-chi/chi@v1.5.0`,
+which will get you on the go.mod version line (as Go's mod cache may still remember v4.x). Brand new systems can run
+`go get -u github.com/go-chi/chi` or `go get -u github.com/go-chi/chi@latest` to install chi, which will install v1.5.0+
+built with go.mod support.
+
+My apologies to the developers who will disagree with the decisions above, but, hope you'll try it and see it's a very
+minor request which is backwards compatible and won't break your existing installations.
+
+Cheers all, happy coding!
+
+
+---
+
+
## v4.1.2 (2020-06-02)
- fix that handles MethodNotAllowed with path variables, thank you @caseyhadden for your contribution
@@ -23,7 +84,6 @@
- middleware.Recoverer: a bit prettier
- History of changes: see https://github.com/go-chi/chi/compare/v4.0.4...v4.1.0
-
## v4.0.4 (2020-03-24)
- middleware.Recoverer: new pretty stack trace printing (https://github.com/go-chi/chi/pull/496)
diff --git a/vendor/github.com/go-chi/chi/README.md b/vendor/github.com/go-chi/chi/README.md
index 3d53a61476..1b96d360d7 100644
--- a/vendor/github.com/go-chi/chi/README.md
+++ b/vendor/github.com/go-chi/chi/README.md
@@ -15,7 +15,8 @@ public API service, which in turn powers all of our client-side applications.
The key considerations of chi's design are: project structure, maintainability, standard http
handlers (stdlib-only), developer productivity, and deconstructing a large system into many small
parts. The core router `github.com/go-chi/chi` is quite small (less than 1000 LOC), but we've also
-included some useful/optional subpackages: [middleware](/middleware), [render](https://github.com/go-chi/render) and [docgen](https://github.com/go-chi/docgen). We hope you enjoy it too!
+included some useful/optional subpackages: [middleware](/middleware), [render](https://github.com/go-chi/render)
+and [docgen](https://github.com/go-chi/docgen). We hope you enjoy it too!
## Install
@@ -27,10 +28,11 @@ included some useful/optional subpackages: [middleware](/middleware), [render](h
* **Lightweight** - cloc'd in ~1000 LOC for the chi router
* **Fast** - yes, see [benchmarks](#benchmarks)
* **100% compatible with net/http** - use any http or middleware pkg in the ecosystem that is also compatible with `net/http`
-* **Designed for modular/composable APIs** - middlewares, inline middlewares, route groups and subrouter mounting
+* **Designed for modular/composable APIs** - middlewares, inline middlewares, route groups and sub-router mounting
* **Context control** - built on new `context` package, providing value chaining, cancellations and timeouts
* **Robust** - in production at Pressly, CloudFlare, Heroku, 99Designs, and many others (see [discussion](https://github.com/go-chi/chi/issues/91))
* **Doc generation** - `docgen` auto-generates routing documentation from your source to JSON or Markdown
+* **Go.mod support** - v1.x of chi (starting from v1.5.0), now has go.mod support (see [CHANGELOG](https://github.com/go-chi/chi/blob/master/CHANGELOG.md#v150-2020-11-12---now-with-gomod-support))
* **No external dependencies** - plain ol' Go stdlib + net/http
@@ -334,9 +336,12 @@ with `net/http` can be used with chi's mux.
----------------------------------------------------------------------------------------------------
| chi/middleware Handler | description |
| :--------------------- | :---------------------------------------------------------------------- |
+| [AllowContentEncoding] | Enforces a whitelist of request Content-Encoding headers |
| [AllowContentType] | Explicit whitelist of accepted request Content-Types |
| [BasicAuth] | Basic HTTP authentication |
| [Compress] | Gzip compression for clients that accept compressed responses |
+| [ContentCharset] | Ensure charset for Content-Type request headers |
+| [CleanPath] | Clean double slashes from request path |
| [GetHead] | Automatically route undefined HEAD requests to GET handlers |
| [Heartbeat] | Monitoring endpoint to check the servers pulse |
| [Logger] | Logs the start and end of each request with the elapsed processing time |
@@ -346,6 +351,7 @@ with `net/http` can be used with chi's mux.
| [Recoverer] | Gracefully absorb panics and prints the stack trace |
| [RequestID] | Injects a request ID into the context of each request |
| [RedirectSlashes] | Redirect slashes on routing paths |
+| [RouteHeaders] | Route handling for request headers |
| [SetHeader] | Short-hand middleware to set a response header key/value |
| [StripSlashes] | Strip slashes on routing paths |
| [Throttle] | Puts a ceiling on the number of concurrent requests |
@@ -359,20 +365,19 @@ with `net/http` can be used with chi's mux.
[BasicAuth]: https://pkg.go.dev/github.com/go-chi/chi/middleware#BasicAuth
[Compress]: https://pkg.go.dev/github.com/go-chi/chi/middleware#Compress
[ContentCharset]: https://pkg.go.dev/github.com/go-chi/chi/middleware#ContentCharset
+[CleanPath]: https://pkg.go.dev/github.com/go-chi/chi/middleware#CleanPath
[GetHead]: https://pkg.go.dev/github.com/go-chi/chi/middleware#GetHead
[GetReqID]: https://pkg.go.dev/github.com/go-chi/chi/middleware#GetReqID
[Heartbeat]: https://pkg.go.dev/github.com/go-chi/chi/middleware#Heartbeat
[Logger]: https://pkg.go.dev/github.com/go-chi/chi/middleware#Logger
-[New]: https://pkg.go.dev/github.com/go-chi/chi/middleware#New
-[NextRequestID]: https://pkg.go.dev/github.com/go-chi/chi/middleware#NextRequestID
[NoCache]: https://pkg.go.dev/github.com/go-chi/chi/middleware#NoCache
-[PrintPrettyStack]: https://pkg.go.dev/github.com/go-chi/chi/middleware#PrintPrettyStack
[Profiler]: https://pkg.go.dev/github.com/go-chi/chi/middleware#Profiler
[RealIP]: https://pkg.go.dev/github.com/go-chi/chi/middleware#RealIP
[Recoverer]: https://pkg.go.dev/github.com/go-chi/chi/middleware#Recoverer
[RedirectSlashes]: https://pkg.go.dev/github.com/go-chi/chi/middleware#RedirectSlashes
-[RequestID]: https://pkg.go.dev/github.com/go-chi/chi/middleware#RequestID
[RequestLogger]: https://pkg.go.dev/github.com/go-chi/chi/middleware#RequestLogger
+[RequestID]: https://pkg.go.dev/github.com/go-chi/chi/middleware#RequestID
+[RouteHeaders]: https://pkg.go.dev/github.com/go-chi/chi/middleware#RouteHeaders
[SetHeader]: https://pkg.go.dev/github.com/go-chi/chi/middleware#SetHeader
[StripSlashes]: https://pkg.go.dev/github.com/go-chi/chi/middleware#StripSlashes
[Throttle]: https://pkg.go.dev/github.com/go-chi/chi/middleware#Throttle
@@ -390,7 +395,6 @@ with `net/http` can be used with chi's mux.
[LogEntry]: https://pkg.go.dev/github.com/go-chi/chi/middleware#LogEntry
[LogFormatter]: https://pkg.go.dev/github.com/go-chi/chi/middleware#LogFormatter
[LoggerInterface]: https://pkg.go.dev/github.com/go-chi/chi/middleware#LoggerInterface
-[Pattern]: https://pkg.go.dev/github.com/go-chi/chi/middleware#Pattern
[ThrottleOpts]: https://pkg.go.dev/github.com/go-chi/chi/middleware#ThrottleOpts
[WrapResponseWriter]: https://pkg.go.dev/github.com/go-chi/chi/middleware#WrapResponseWriter
@@ -430,25 +434,25 @@ and..
The benchmark suite: https://github.com/pkieltyka/go-http-routing-benchmark
-Results as of Jan 9, 2019 with Go 1.11.4 on Linux X1 Carbon laptop
+Results as of Nov 29, 2020 with Go 1.15.5 on Linux AMD 3950x
```shell
-BenchmarkChi_Param 3000000 475 ns/op 432 B/op 3 allocs/op
-BenchmarkChi_Param5 2000000 696 ns/op 432 B/op 3 allocs/op
-BenchmarkChi_Param20 1000000 1275 ns/op 432 B/op 3 allocs/op
-BenchmarkChi_ParamWrite 3000000 505 ns/op 432 B/op 3 allocs/op
-BenchmarkChi_GithubStatic 3000000 508 ns/op 432 B/op 3 allocs/op
-BenchmarkChi_GithubParam 2000000 669 ns/op 432 B/op 3 allocs/op
-BenchmarkChi_GithubAll 10000 134627 ns/op 87699 B/op 609 allocs/op
-BenchmarkChi_GPlusStatic 3000000 402 ns/op 432 B/op 3 allocs/op
-BenchmarkChi_GPlusParam 3000000 500 ns/op 432 B/op 3 allocs/op
-BenchmarkChi_GPlus2Params 3000000 586 ns/op 432 B/op 3 allocs/op
-BenchmarkChi_GPlusAll 200000 7237 ns/op 5616 B/op 39 allocs/op
-BenchmarkChi_ParseStatic 3000000 408 ns/op 432 B/op 3 allocs/op
-BenchmarkChi_ParseParam 3000000 488 ns/op 432 B/op 3 allocs/op
-BenchmarkChi_Parse2Params 3000000 551 ns/op 432 B/op 3 allocs/op
-BenchmarkChi_ParseAll 100000 13508 ns/op 11232 B/op 78 allocs/op
-BenchmarkChi_StaticAll 20000 81933 ns/op 67826 B/op 471 allocs/op
+BenchmarkChi_Param 3075895 384 ns/op 400 B/op 2 allocs/op
+BenchmarkChi_Param5 2116603 566 ns/op 400 B/op 2 allocs/op
+BenchmarkChi_Param20 964117 1227 ns/op 400 B/op 2 allocs/op
+BenchmarkChi_ParamWrite 2863413 420 ns/op 400 B/op 2 allocs/op
+BenchmarkChi_GithubStatic 3045488 395 ns/op 400 B/op 2 allocs/op
+BenchmarkChi_GithubParam 2204115 540 ns/op 400 B/op 2 allocs/op
+BenchmarkChi_GithubAll 10000 113811 ns/op 81203 B/op 406 allocs/op
+BenchmarkChi_GPlusStatic 3337485 359 ns/op 400 B/op 2 allocs/op
+BenchmarkChi_GPlusParam 2825853 423 ns/op 400 B/op 2 allocs/op
+BenchmarkChi_GPlus2Params 2471697 483 ns/op 400 B/op 2 allocs/op
+BenchmarkChi_GPlusAll 194220 5950 ns/op 5200 B/op 26 allocs/op
+BenchmarkChi_ParseStatic 3365324 356 ns/op 400 B/op 2 allocs/op
+BenchmarkChi_ParseParam 2976614 404 ns/op 400 B/op 2 allocs/op
+BenchmarkChi_Parse2Params 2638084 439 ns/op 400 B/op 2 allocs/op
+BenchmarkChi_ParseAll 109567 11295 ns/op 10400 B/op 52 allocs/op
+BenchmarkChi_StaticAll 16846 71308 ns/op 62802 B/op 314 allocs/op
```
Comparison with other routers: https://gist.github.com/pkieltyka/123032f12052520aaccab752bd3e78cc
@@ -459,6 +463,17 @@ on the duplicated (alloc'd) request and returns it the new request object. This
how setting context on a request in Go works.
+## Go module support & note on chi's versioning
+
+* Go.mod support means we reset our versioning starting from v1.5 (see [CHANGELOG](https://github.com/go-chi/chi/blob/master/CHANGELOG.md#v150-2020-11-12---now-with-gomod-support))
+* All older tags are preserved, are backwards-compatible and will "just work" as they
+* Brand new systems can run `go get -u github.com/go-chi/chi` as normal, or `go get -u github.com/go-chi/chi@latest`
+to install chi, which will install v1.x+ built with go.mod support, starting from v1.5.0.
+* For existing projects who want to upgrade to the latest go.mod version, run: `go get -u github.com/go-chi/chi@v1.5.0`,
+which will get you on the go.mod version line (as Go's mod cache may still remember v4.x).
+* Any breaking changes will bump a "minor" release and backwards-compatible improvements/fixes will bump a "tiny" release.
+
+
## Credits
* Carl Jackson for https://github.com/zenazn/goji
diff --git a/vendor/github.com/go-chi/chi/context.go b/vendor/github.com/go-chi/chi/context.go
index 26c609ea2c..7dec3f0c01 100644
--- a/vendor/github.com/go-chi/chi/context.go
+++ b/vendor/github.com/go-chi/chi/context.go
@@ -2,9 +2,9 @@ package chi
import (
"context"
- "net"
"net/http"
"strings"
+ "time"
)
// URLParam returns the url parameter from a http.Request object.
@@ -30,26 +30,6 @@ func RouteContext(ctx context.Context) *Context {
return val
}
-// ServerBaseContext wraps an http.Handler to set the request context to the
-// `baseCtx`.
-func ServerBaseContext(baseCtx context.Context, h http.Handler) http.Handler {
- fn := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- ctx := r.Context()
- baseCtx := baseCtx
-
- // Copy over default net/http server context keys
- if v, ok := ctx.Value(http.ServerContextKey).(*http.Server); ok {
- baseCtx = context.WithValue(baseCtx, http.ServerContextKey, v)
- }
- if v, ok := ctx.Value(http.LocalAddrContextKey).(net.Addr); ok {
- baseCtx = context.WithValue(baseCtx, http.LocalAddrContextKey, v)
- }
-
- h.ServeHTTP(w, r.WithContext(baseCtx))
- })
- return fn
-}
-
// NewRouteContext returns a new routing Context object.
func NewRouteContext() *Context {
return &Context{}
@@ -92,6 +72,11 @@ type Context struct {
// methodNotAllowed hint
methodNotAllowed bool
+
+ // parentCtx is the parent of this one, for using Context as a
+ // context.Context directly. This is an optimization that saves
+ // 1 allocation.
+ parentCtx context.Context
}
// Reset a routing context to its initial state.
@@ -107,6 +92,7 @@ func (x *Context) Reset() {
x.routeParams.Keys = x.routeParams.Keys[:0]
x.routeParams.Values = x.routeParams.Values[:0]
x.methodNotAllowed = false
+ x.parentCtx = nil
}
// URLParam returns the corresponding URL parameter value from the request
@@ -160,6 +146,32 @@ func (s *RouteParams) Add(key, value string) {
s.Values = append(s.Values, value)
}
+// directContext provides direct access to the routing *Context object,
+// while implementing the context.Context interface, thereby allowing
+// us to saving 1 allocation during routing.
+type directContext Context
+
+var _ context.Context = (*directContext)(nil)
+
+func (d *directContext) Deadline() (deadline time.Time, ok bool) {
+ return d.parentCtx.Deadline()
+}
+
+func (d *directContext) Done() <-chan struct{} {
+ return d.parentCtx.Done()
+}
+
+func (d *directContext) Err() error {
+ return d.parentCtx.Err()
+}
+
+func (d *directContext) Value(key interface{}) interface{} {
+ if key == RouteCtxKey {
+ return (*Context)(d)
+ }
+ return d.parentCtx.Value(key)
+}
+
// contextKey is a value for use with context.WithValue. It's used as
// a pointer so it fits in an interface{} without allocation. This technique
// for defining context keys was copied from Go 1.7's new use of context in net/http.
diff --git a/vendor/github.com/go-chi/chi/middleware/basic_auth.go b/vendor/github.com/go-chi/chi/middleware/basic_auth.go
index 87b2641a6a..a546c9e9e8 100644
--- a/vendor/github.com/go-chi/chi/middleware/basic_auth.go
+++ b/vendor/github.com/go-chi/chi/middleware/basic_auth.go
@@ -1,6 +1,7 @@
package middleware
import (
+ "crypto/subtle"
"fmt"
"net/http"
)
@@ -16,7 +17,7 @@ func BasicAuth(realm string, creds map[string]string) func(next http.Handler) ht
}
credPass, credUserOk := creds[user]
- if !credUserOk || pass != credPass {
+ if !credUserOk || subtle.ConstantTimeCompare([]byte(pass), []byte(credPass)) != 1 {
basicAuthFailed(w, realm)
return
}
diff --git a/vendor/github.com/go-chi/chi/middleware/clean_path.go b/vendor/github.com/go-chi/chi/middleware/clean_path.go
new file mode 100644
index 0000000000..d42bf28457
--- /dev/null
+++ b/vendor/github.com/go-chi/chi/middleware/clean_path.go
@@ -0,0 +1,28 @@
+package middleware
+
+import (
+ "net/http"
+ "path"
+
+ "github.com/go-chi/chi"
+)
+
+// CleanPath middleware will clean out double slash mistakes from a user's request path.
+// For example, if a user requests /users//1 or //users////1 will both be treated as: /users/1
+func CleanPath(next http.Handler) http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ rctx := chi.RouteContext(r.Context())
+
+ routePath := rctx.RoutePath
+ if routePath == "" {
+ if r.URL.RawPath != "" {
+ routePath = r.URL.RawPath
+ } else {
+ routePath = r.URL.Path
+ }
+ rctx.RoutePath = path.Clean(routePath)
+ }
+
+ next.ServeHTTP(w, r)
+ })
+}
diff --git a/vendor/github.com/go-chi/chi/middleware/content_type.go b/vendor/github.com/go-chi/chi/middleware/content_type.go
index ee4957874f..023978fac0 100644
--- a/vendor/github.com/go-chi/chi/middleware/content_type.go
+++ b/vendor/github.com/go-chi/chi/middleware/content_type.go
@@ -19,9 +19,9 @@ func SetHeader(key, value string) func(next http.Handler) http.Handler {
// AllowContentType enforces a whitelist of request Content-Types otherwise responds
// with a 415 Unsupported Media Type status.
func AllowContentType(contentTypes ...string) func(next http.Handler) http.Handler {
- cT := []string{}
- for _, t := range contentTypes {
- cT = append(cT, strings.ToLower(t))
+ allowedContentTypes := make(map[string]struct{}, len(contentTypes))
+ for _, ctype := range contentTypes {
+ allowedContentTypes[strings.TrimSpace(strings.ToLower(ctype))] = struct{}{}
}
return func(next http.Handler) http.Handler {
@@ -37,11 +37,9 @@ func AllowContentType(contentTypes ...string) func(next http.Handler) http.Handl
s = s[0:i]
}
- for _, t := range cT {
- if t == s {
- next.ServeHTTP(w, r)
- return
- }
+ if _, ok := allowedContentTypes[s]; ok {
+ next.ServeHTTP(w, r)
+ return
}
w.WriteHeader(http.StatusUnsupportedMediaType)
diff --git a/vendor/github.com/go-chi/chi/middleware/logger.go b/vendor/github.com/go-chi/chi/middleware/logger.go
index 158a6a3905..66edc3dda8 100644
--- a/vendor/github.com/go-chi/chi/middleware/logger.go
+++ b/vendor/github.com/go-chi/chi/middleware/logger.go
@@ -6,6 +6,7 @@ import (
"log"
"net/http"
"os"
+ "runtime"
"time"
)
@@ -16,7 +17,7 @@ var (
// DefaultLogger is called by the Logger middleware handler to log each request.
// Its made a package-level variable so that it can be reconfigured for custom
// logging configurations.
- DefaultLogger = RequestLogger(&DefaultLogFormatter{Logger: log.New(os.Stdout, "", log.LstdFlags), NoColor: false})
+ DefaultLogger func(next http.Handler) http.Handler
)
// Logger is a middleware that logs the start and end of each request, along
@@ -27,6 +28,16 @@ var (
//
// Alternatively, look at https://github.com/goware/httplog for a more in-depth
// http logger with structured logging support.
+//
+// IMPORTANT NOTE: Logger should go before any other middleware that may change
+// the response, such as `middleware.Recoverer`. Example:
+//
+// ```go
+// r := chi.NewRouter()
+// r.Use(middleware.Logger) // <--<< Logger should come before Recoverer
+// r.Use(middleware.Recoverer)
+// r.Get("/", handler)
+// ```
func Logger(next http.Handler) http.Handler {
return DefaultLogger(next)
}
@@ -153,3 +164,11 @@ func (l *defaultLogEntry) Write(status, bytes int, header http.Header, elapsed t
func (l *defaultLogEntry) Panic(v interface{}, stack []byte) {
PrintPrettyStack(v)
}
+
+func init() {
+ color := true
+ if runtime.GOOS == "windows" {
+ color = false
+ }
+ DefaultLogger = RequestLogger(&DefaultLogFormatter{Logger: log.New(os.Stdout, "", log.LstdFlags), NoColor: !color})
+}
diff --git a/vendor/github.com/go-chi/chi/middleware/strip.go b/vendor/github.com/go-chi/chi/middleware/strip.go
index 2b8b1842ab..1082d713ef 100644
--- a/vendor/github.com/go-chi/chi/middleware/strip.go
+++ b/vendor/github.com/go-chi/chi/middleware/strip.go
@@ -14,13 +14,18 @@ func StripSlashes(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
var path string
rctx := chi.RouteContext(r.Context())
- if rctx.RoutePath != "" {
+ if rctx != nil && rctx.RoutePath != "" {
path = rctx.RoutePath
} else {
path = r.URL.Path
}
if len(path) > 1 && path[len(path)-1] == '/' {
- rctx.RoutePath = path[:len(path)-1]
+ newPath := path[:len(path)-1]
+ if rctx == nil {
+ r.URL.Path = newPath
+ } else {
+ rctx.RoutePath = newPath
+ }
}
next.ServeHTTP(w, r)
}
@@ -36,7 +41,7 @@ func RedirectSlashes(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
var path string
rctx := chi.RouteContext(r.Context())
- if rctx.RoutePath != "" {
+ if rctx != nil && rctx.RoutePath != "" {
path = rctx.RoutePath
} else {
path = r.URL.Path
@@ -47,7 +52,8 @@ func RedirectSlashes(next http.Handler) http.Handler {
} else {
path = path[:len(path)-1]
}
- http.Redirect(w, r, path, 301)
+ redirectUrl := fmt.Sprintf("//%s%s", r.Host, path)
+ http.Redirect(w, r, redirectUrl, 301)
return
}
next.ServeHTTP(w, r)
diff --git a/vendor/github.com/go-chi/chi/middleware/url_format.go b/vendor/github.com/go-chi/chi/middleware/url_format.go
index 5749e4f32b..d8f04b7cb9 100644
--- a/vendor/github.com/go-chi/chi/middleware/url_format.go
+++ b/vendor/github.com/go-chi/chi/middleware/url_format.go
@@ -53,7 +53,7 @@ func URLFormat(next http.Handler) http.Handler {
if strings.Index(path, ".") > 0 {
base := strings.LastIndex(path, "/")
- idx := strings.Index(path[base:], ".")
+ idx := strings.LastIndex(path[base:], ".")
if idx > 0 {
idx += base
diff --git a/vendor/github.com/go-chi/chi/mux.go b/vendor/github.com/go-chi/chi/mux.go
index 52950e97b5..c6fdb8a0f3 100644
--- a/vendor/github.com/go-chi/chi/mux.go
+++ b/vendor/github.com/go-chi/chi/mux.go
@@ -1,7 +1,6 @@
package chi
import (
- "context"
"fmt"
"net/http"
"strings"
@@ -78,9 +77,10 @@ func (mx *Mux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
rctx = mx.pool.Get().(*Context)
rctx.Reset()
rctx.Routes = mx
+ rctx.parentCtx = r.Context()
- // NOTE: r.WithContext() causes 2 allocations and context.WithValue() causes 1 allocation
- r = r.WithContext(context.WithValue(r.Context(), RouteCtxKey, rctx))
+ // NOTE: r.WithContext() causes 2 allocations
+ r = r.WithContext((*directContext)(rctx))
// Serve the request and once its done, put the request context back in the sync pool
mx.handler.ServeHTTP(w, r)
@@ -227,7 +227,7 @@ func (mx *Mux) With(middlewares ...func(http.Handler) http.Handler) Router {
// Similarly as in handle(), we must build the mux handler once additional
// middleware registration isn't allowed for this stack, like now.
if !mx.inline && mx.handler == nil {
- mx.buildRouteHandler()
+ mx.updateRouteHandler()
}
// Copy middlewares from parent inline muxs
@@ -261,10 +261,11 @@ func (mx *Mux) Group(fn func(r Router)) Router {
// along the `pattern` as a subrouter. Effectively, this is a short-hand
// call to Mount. See _examples/.
func (mx *Mux) Route(pattern string, fn func(r Router)) Router {
- subRouter := NewRouter()
- if fn != nil {
- fn(subRouter)
+ if fn == nil {
+ panic(fmt.Sprintf("chi: attempting to Route() a nil subrouter on '%s'", pattern))
}
+ subRouter := NewRouter()
+ fn(subRouter)
mx.Mount(pattern, subRouter)
return subRouter
}
@@ -277,6 +278,10 @@ func (mx *Mux) Route(pattern string, fn func(r Router)) Router {
// routing at the `handler`, which in most cases is another chi.Router. As a result,
// if you define two Mount() routes on the exact same pattern the mount will panic.
func (mx *Mux) Mount(pattern string, handler http.Handler) {
+ if handler == nil {
+ panic(fmt.Sprintf("chi: attempting to Mount() a nil handler on '%s'", pattern))
+ }
+
// Provide runtime safety for ensuring a pattern isn't mounted on an existing
// routing pattern.
if mx.tree.findPattern(pattern+"*") || mx.tree.findPattern(pattern+"/*") {
@@ -294,7 +299,16 @@ func (mx *Mux) Mount(pattern string, handler http.Handler) {
mountHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
rctx := RouteContext(r.Context())
+
+ // shift the url path past the previous subrouter
rctx.RoutePath = mx.nextRoutePath(rctx)
+
+ // reset the wildcard URLParam which connects the subrouter
+ n := len(rctx.URLParams.Keys) - 1
+ if n >= 0 && rctx.URLParams.Keys[n] == "*" && len(rctx.URLParams.Values) > n {
+ rctx.URLParams.Values[n] = ""
+ }
+
handler.ServeHTTP(w, r)
})
@@ -367,14 +381,6 @@ func (mx *Mux) MethodNotAllowedHandler() http.HandlerFunc {
return methodNotAllowedHandler
}
-// buildRouteHandler builds the single mux handler that is a chain of the middleware
-// stack, as defined by calls to Use(), and the tree router (Mux) itself. After this
-// point, no other middlewares can be registered on this Mux's stack. But you can still
-// compose additional middlewares via Group()'s or using a chained middleware handler.
-func (mx *Mux) buildRouteHandler() {
- mx.handler = chain(mx.middlewares, http.HandlerFunc(mx.routeHTTP))
-}
-
// handle registers a http.Handler in the routing tree for a particular http method
// and routing pattern.
func (mx *Mux) handle(method methodTyp, pattern string, handler http.Handler) *node {
@@ -384,7 +390,7 @@ func (mx *Mux) handle(method methodTyp, pattern string, handler http.Handler) *n
// Build the computed routing handler for this routing pattern.
if !mx.inline && mx.handler == nil {
- mx.buildRouteHandler()
+ mx.updateRouteHandler()
}
// Build endpoint handler with inline middlewares for the route
@@ -458,6 +464,14 @@ func (mx *Mux) updateSubRoutes(fn func(subMux *Mux)) {
}
}
+// updateRouteHandler builds the single mux handler that is a chain of the middleware
+// stack, as defined by calls to Use(), and the tree router (Mux) itself. After this
+// point, no other middlewares can be registered on this Mux's stack. But you can still
+// compose additional middlewares via Group()'s or using a chained middleware handler.
+func (mx *Mux) updateRouteHandler() {
+ mx.handler = chain(mx.middlewares, http.HandlerFunc(mx.routeHTTP))
+}
+
// methodNotAllowedHandler is a helper function to respond with a 405,
// method not allowed.
func methodNotAllowedHandler(w http.ResponseWriter, r *http.Request) {