diff options
| author | Felix Hanley <felix@userspace.com.au> | 2016-05-11 07:43:19 +0000 |
|---|---|---|
| committer | Felix Hanley <felix@userspace.com.au> | 2016-05-11 07:43:19 +0000 |
| commit | 01d4169b551675aa04e9075915113d2e94fdb72d (patch) | |
| tree | 0eaad50b248928795ba6c5c24873b7b84b0bca09 /src/dict2rest/vendor/github.com/justinas/alice | |
| parent | a5be2d0a2f450dd2e2c699e45773016528d43876 (diff) | |
| download | go-dict2rest-01d4169b551675aa04e9075915113d2e94fdb72d.tar.gz go-dict2rest-01d4169b551675aa04e9075915113d2e94fdb72d.tar.bz2 | |
Use Golang 1.6 vendor structure
Diffstat (limited to 'src/dict2rest/vendor/github.com/justinas/alice')
5 files changed, 386 insertions, 0 deletions
diff --git a/src/dict2rest/vendor/github.com/justinas/alice/.travis.yml b/src/dict2rest/vendor/github.com/justinas/alice/.travis.yml new file mode 100644 index 0000000..9398694 --- /dev/null +++ b/src/dict2rest/vendor/github.com/justinas/alice/.travis.yml @@ -0,0 +1,11 @@ +language: go + +install: + - go get github.com/stretchr/testify/assert + +go: + - 1.1 + - 1.2 + - 1.3 + - 1.4 + - tip diff --git a/src/dict2rest/vendor/github.com/justinas/alice/LICENSE b/src/dict2rest/vendor/github.com/justinas/alice/LICENSE new file mode 100644 index 0000000..0d0d352 --- /dev/null +++ b/src/dict2rest/vendor/github.com/justinas/alice/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2014 Justinas Stankevicius + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/dict2rest/vendor/github.com/justinas/alice/README.md b/src/dict2rest/vendor/github.com/justinas/alice/README.md new file mode 100644 index 0000000..88d2134 --- /dev/null +++ b/src/dict2rest/vendor/github.com/justinas/alice/README.md @@ -0,0 +1,92 @@ +# Alice + +[](https://travis-ci.org/justinas/alice) + +Alice provides a convenient way to chain +your HTTP middleware functions and the app handler. + +In short, it transforms + + Middleware1(Middleware2(Middleware3(App))) + +to + + alice.New(Middleware1, Middleware2, Middleware3).Then(App). + +### Why? + +None of the other middleware chaining solutions +behaves exactly like Alice. +Alice is as minimal as it gets: +in essence, it's just a for loop that does the wrapping for you. + +Check out [this blog post](http://justinas.org/alice-painless-middleware-chaining-for-go/) +for explanation how Alice is different from other chaining solutions. + +### Usage + +Your middleware constructors should have the form of + + func (http.Handler) http.Handler + +Some middleware provide this out of the box. +For ones that don't, it's trivial to write one yourself. + +```go +func myStripPrefix(h http.Handler) http.Handler { + return http.StripPrefix("/old", h) +} +``` + +This complete example shows the full power of Alice. + +```go +package main + +import ( + "net/http" + "time" + + "github.com/PuerkitoBio/throttled" + "github.com/justinas/alice" + "github.com/justinas/nosurf" +) + +func timeoutHandler(h http.Handler) http.Handler { + return http.TimeoutHandler(h, 1*time.Second, "timed out") +} + +func myApp(w http.ResponseWriter, r *http.Request) { + w.Write([]byte("Hello world!")) +} + +func main() { + th := throttled.Interval(throttled.PerSec(10), 1, &throttled.VaryBy{Path: true}, 50) + myHandler := http.HandlerFunc(myApp) + + chain := alice.New(th.Throttle, timeoutHandler, nosurf.NewPure).Then(myHandler) + http.ListenAndServe(":8000", chain) +} +``` + +Here, the request will pass [throttled](https://github.com/PuerkitoBio/throttled) first, +then an http.TimeoutHandler we've set up, +then [nosurf](https://github.com/justinas/nosurf) +and will finally reach our handler. + +Note that Alice makes **no guarantees** for +how one or another piece of middleware will behave. +It executes all middleware sequentially so that if a +piece of middleware were to stop the chain, +the request will not reach the inner handlers. +This is intentional behavior. + +Alice works with Go 1.0 and higher, +but running tests requires at least Go 1.1. + +### Contributing + +0. Find an issue that bugs you / open a new one. +1. Discuss. +2. Branch off, commit, test. +3. Make a pull request / attach the commits to the issue. diff --git a/src/dict2rest/vendor/github.com/justinas/alice/chain.go b/src/dict2rest/vendor/github.com/justinas/alice/chain.go new file mode 100644 index 0000000..d281ad3 --- /dev/null +++ b/src/dict2rest/vendor/github.com/justinas/alice/chain.go @@ -0,0 +1,119 @@ +// Package alice provides a convenient way to chain http handlers. +package alice + +import "net/http" + +// A constructor for a piece of middleware. +// Some middleware use this constructor out of the box, +// so in most cases you can just pass somepackage.New +type Constructor func(http.Handler) http.Handler + +// Chain acts as a list of http.Handler constructors. +// Chain is effectively immutable: +// once created, it will always hold +// the same set of constructors in the same order. +type Chain struct { + constructors []Constructor +} + +// New creates a new chain, +// memorizing the given list of middleware constructors. +// New serves no other function, +// constructors are only called upon a call to Then(). +func New(constructors ...Constructor) Chain { + c := Chain{} + c.constructors = append(c.constructors, constructors...) + + return c +} + +// Then chains the middleware and returns the final http.Handler. +// New(m1, m2, m3).Then(h) +// is equivalent to: +// m1(m2(m3(h))) +// When the request comes in, it will be passed to m1, then m2, then m3 +// and finally, the given handler +// (assuming every middleware calls the following one). +// +// A chain can be safely reused by calling Then() several times. +// stdStack := alice.New(ratelimitHandler, csrfHandler) +// indexPipe = stdStack.Then(indexHandler) +// authPipe = stdStack.Then(authHandler) +// Note that constructors are called on every call to Then() +// and thus several instances of the same middleware will be created +// when a chain is reused in this way. +// For proper middleware, this should cause no problems. +// +// Then() treats nil as http.DefaultServeMux. +func (c Chain) Then(h http.Handler) http.Handler { + var final http.Handler + if h != nil { + final = h + } else { + final = http.DefaultServeMux + } + + for i := len(c.constructors) - 1; i >= 0; i-- { + final = c.constructors[i](final) + } + + return final +} + +// ThenFunc works identically to Then, but takes +// a HandlerFunc instead of a Handler. +// +// The following two statements are equivalent: +// c.Then(http.HandlerFunc(fn)) +// c.ThenFunc(fn) +// +// ThenFunc provides all the guarantees of Then. +func (c Chain) ThenFunc(fn http.HandlerFunc) http.Handler { + if fn == nil { + return c.Then(nil) + } + return c.Then(http.HandlerFunc(fn)) +} + +// Append extends a chain, adding the specified constructors +// as the last ones in the request flow. +// +// Append returns a new chain, leaving the original one untouched. +// +// stdChain := alice.New(m1, m2) +// extChain := stdChain.Append(m3, m4) +// // requests in stdChain go m1 -> m2 +// // requests in extChain go m1 -> m2 -> m3 -> m4 +func (c Chain) Append(constructors ...Constructor) Chain { + newCons := make([]Constructor, len(c.constructors)+len(constructors)) + copy(newCons, c.constructors) + copy(newCons[len(c.constructors):], constructors) + + newChain := New(newCons...) + return newChain +} + +// Extend extends a chain by adding the specified chain +// as the last one in the request flow. +// +// Extend returns a new chain, leaving the original one untouched. +// +// stdChain := alice.New(m1, m2) +// ext1Chain := alice.New(m3, m4) +// ext2Chain := stdChain.Extend(ext1Chain) +// // requests in stdChain go m1 -> m2 +// // requests in ext1Chain go m3 -> m4 +// // requests in ext2Chain go m1 -> m2 -> m3 -> m4 +// +// Another example: +// aHtmlAfterNosurf := alice.New(m2) +// aHtml := alice.New(m1, func(h http.Handler) http.Handler { +// csrf := nosurf.New(h) +// csrf.SetFailureHandler(aHtmlAfterNosurf.ThenFunc(csrfFail)) +// return csrf +// }).Extend(aHtmlAfterNosurf) +// // requests to aHtml hitting nosurfs success handler go m1 -> nosurf -> m2 -> target-handler +// // requests to aHtml hitting nosurfs failure handler go m1 -> nosurf -> m2 -> csrfFail +func (c Chain) Extend(chain Chain) Chain { + return c.Append(chain.constructors...) +} diff --git a/src/dict2rest/vendor/github.com/justinas/alice/chain_test.go b/src/dict2rest/vendor/github.com/justinas/alice/chain_test.go new file mode 100644 index 0000000..49c0470 --- /dev/null +++ b/src/dict2rest/vendor/github.com/justinas/alice/chain_test.go @@ -0,0 +1,144 @@ +// Package alice implements a middleware chaining solution. +package alice + +import ( + "net/http" + "net/http/httptest" + "reflect" + "testing" + + "github.com/stretchr/testify/assert" +) + +// A constructor for middleware +// that writes its own "tag" into the RW and does nothing else. +// Useful in checking if a chain is behaving in the right order. +func tagMiddleware(tag string) Constructor { + return func(h http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(tag)) + h.ServeHTTP(w, r) + }) + } +} + +// Not recommended (https://golang.org/pkg/reflect/#Value.Pointer), +// but the best we can do. +func funcsEqual(f1, f2 interface{}) bool { + val1 := reflect.ValueOf(f1) + val2 := reflect.ValueOf(f2) + return val1.Pointer() == val2.Pointer() +} + +var testApp = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte("app\n")) +}) + +// Tests creating a new chain +func TestNew(t *testing.T) { + c1 := func(h http.Handler) http.Handler { + return nil + } + c2 := func(h http.Handler) http.Handler { + return http.StripPrefix("potato", nil) + } + + slice := []Constructor{c1, c2} + + chain := New(slice...) + assert.True(t, funcsEqual(chain.constructors[0], slice[0])) + assert.True(t, funcsEqual(chain.constructors[1], slice[1])) +} + +func TestThenWorksWithNoMiddleware(t *testing.T) { + assert.NotPanics(t, func() { + chain := New() + final := chain.Then(testApp) + + assert.True(t, funcsEqual(final, testApp)) + }) +} + +func TestThenTreatsNilAsDefaultServeMux(t *testing.T) { + chained := New().Then(nil) + assert.Equal(t, chained, http.DefaultServeMux) +} + +func TestThenFuncTreatsNilAsDefaultServeMux(t *testing.T) { + chained := New().ThenFunc(nil) + assert.Equal(t, chained, http.DefaultServeMux) +} + +func TestThenOrdersHandlersRight(t *testing.T) { + t1 := tagMiddleware("t1\n") + t2 := tagMiddleware("t2\n") + t3 := tagMiddleware("t3\n") + + chained := New(t1, t2, t3).Then(testApp) + + w := httptest.NewRecorder() + r, err := http.NewRequest("GET", "/", nil) + if err != nil { + t.Fatal(err) + } + + chained.ServeHTTP(w, r) + + assert.Equal(t, w.Body.String(), "t1\nt2\nt3\napp\n") +} + +func TestAppendAddsHandlersCorrectly(t *testing.T) { + chain := New(tagMiddleware("t1\n"), tagMiddleware("t2\n")) + newChain := chain.Append(tagMiddleware("t3\n"), tagMiddleware("t4\n")) + + assert.Equal(t, len(chain.constructors), 2) + assert.Equal(t, len(newChain.constructors), 4) + + chained := newChain.Then(testApp) + + w := httptest.NewRecorder() + r, err := http.NewRequest("GET", "/", nil) + if err != nil { + t.Fatal(err) + } + + chained.ServeHTTP(w, r) + + assert.Equal(t, w.Body.String(), "t1\nt2\nt3\nt4\napp\n") +} + +func TestAppendRespectsImmutability(t *testing.T) { + chain := New(tagMiddleware("")) + newChain := chain.Append(tagMiddleware("")) + + assert.NotEqual(t, &chain.constructors[0], &newChain.constructors[0]) +} + +func TestExtendAddsHandlersCorrectly(t *testing.T) { + chain1 := New(tagMiddleware("t1\n"), tagMiddleware("t2\n")) + chain2 := New(tagMiddleware("t3\n"), tagMiddleware("t4\n")) + newChain := chain1.Extend(chain2) + + assert.Equal(t, len(chain1.constructors), 2) + assert.Equal(t, len(chain2.constructors), 2) + assert.Equal(t, len(newChain.constructors), 4) + + chained := newChain.Then(testApp) + + w := httptest.NewRecorder() + r, err := http.NewRequest("GET", "/", nil) + if err != nil { + t.Fatal(err) + } + + chained.ServeHTTP(w, r) + + assert.Equal(t, w.Body.String(), "t1\nt2\nt3\nt4\napp\n") +} + +func TestExtendRespectsImmutability(t *testing.T) { + chain := New(tagMiddleware("")) + newChain := chain.Extend(New(tagMiddleware(""))) + + assert.NotEqual(t, &chain.constructors[0], &newChain.constructors[0]) +} |
